STM32F051——USART

Source

        我在大二学32的时候曾经写过一篇博客,现在看了一个韩老师的专题课后再来完善一下32串口方面的知识。所有的知识都可在官方手册中找到,目前我认为学习一个新的芯片,最全最细的就是官方手册了,英文看不懂可以看中文的,不过最好是英文的,翻译有的地方有偏差。

---------------------------------------------------------------------------------------------------------------------------------

目录

1 协议基础知识介绍

1.1 同步通信和异步通信

同步通信:

异步通信:

1.2 串行通信和并行通信的区别

串行通信:

并行通信:

串行传输:

并行传输:

1.3 单工、半双工、全双工

1.4 常见通信总结

1.5 USART基本概念

1.6 串口电路连接

1.7 STM32f051串口 

1.8 串口通信协议介绍

1.9 波特率

2. USART寄存器介绍

2.1 控制寄存器 USART_CR

USART_CR1

USART_CR2

2.2 波特率寄存器 USART_BRR

2.3 中断和状态寄存器 USART_ISR

2.4 数据发送寄存器 USART_TDR

2.5 数据接收寄存器 USART_RDR 

3 USART开发传输控制流程

3.1 USART硬件原理图分析

4 实践:USART控制——字符传输读 写

4.1 CubeMX中配置管脚 

 4.2 串口数据的发送和接收

4.3 串口传输函数——读取寄存器方式

 4.4 实践:USART控制——字符传输利用库

(1) 串口的发送函数

(2) 串口的接收函数

4.5 实践6:USART控制——实现printf()串 口重定向输出


1 协议基础知识介绍

1.1 同步通信和异步通信

通信,最少要有两个对象,一个收,一个发

同步通信:

        一般情况下同步通信指的是通信双方根据同 步信号进行通信的方式。比如通信双方有一个共同的时 钟信号,大家根据时钟信号的变化进行通信。

 

异步通信:

        是指数据传输速度匹配依赖于通信双方有自 己独立的系统时钟,大家约定好通信的速度。异步通信 不需要同步信号,但是并不是说通信的过程不同步。数 据量大会有误差。(两边都有自己独立的时钟信号)

注意:同步通信有时钟线,异步通信没有时钟线。

1.2 串行通信和并行通信的区别

串行通信:

指的是同一时刻只能收或发一个bit位信息。 因此只用1根信号线即可。

并行通信:

指的是同一时刻可以收或发多个bit位的信 息,因此需要多根信号线才行。

串行传输:

数据按位顺序传输。

-优点:占用引脚资源少

-缺点:速度相对较慢

例如:UART 串口

 

并行传输:

数据各个位同时传输。

-优点:速度快

-缺点:占用引脚资源多 IO口资源有限和使用紧张;

1.3 单工、半双工、全双工

单工:要么收,要么发,只能做接收设备或者发送设 备。比如收音机

半双工:可以收,可以发,但是不能同时收发, 比如对 讲机

全双工:可以在同一时刻既接收,又发送。 比如手机

 

1.4 常见通信总结

1.5 USART基本概念

        通用同步异步收发器(USART)灵活地与外部设备进行 全双工数据通信,满足外部设备对工业标准NRZ异步串 行数据格式的要求。USART通过小数波特率发生器提供 了多种波特率。它支持同步单向通信和半双工单线通 信;还支持LIN(局域互联网络),智能卡协议与IrDA (红外数据协会)SIR ENDEC规范,以及调制解调操作 (CTS/RTS)。而且,它还支持多处理器通信。

         USART**支持同步模式因此USART 需要同步始终信 号USART_CK(如STM32 单片机),通常情况同步信号 很少使用,因此USART和一般单片机UART使用方式是 一样的,都使用异步模式。**

1.6 串口电路连接

接口与外部设备通过三个引脚相连, RX,TX,GND

任何 USART 双向通讯要求最少有两个引脚: 接收数据 输入(RX)和发送数据输出(TX)

RX: 接收数据输入是串行数据的输入口。 使用过采样技 术来完成数据恢复,以区别输入数据和噪声。

TX: 数据发送输出。 当发送器被禁止,输出脚回到其 I/O 口配置状态。 当发送器被使能,但不发送数据时,TX 脚 为高电平输出。 在单线和智能卡模式中,这个口线既用 于发送数据也 用于接收数据。

注意:

(1)电脑用的TTL电平和EIA电平不能直接连;

(2)TTL电平, 0V表示0 ,大于3.3或者5伏就表示为1了;

        DB9插槽已经很少了,或者迷你USB口插槽,因此有的 是USB线,这时需要当做串口用的话需要用驱动转换, CH340。

1.7 STM32f051串口 

 

STM32F051内置多达两个通用同步 / 异步收发器( USART1 和 USART2 ),通信速度可达 6 Mbit / s

如果使用 USART1进行串口传输通讯。 查找原理图和手册,对应寄存器是PA9,PA10。

1.8 串口通信协议介绍

协议很重要!!! 

 从左到右,看图上发生的事件,实际发送从起始位开 始,停止位结束。

1. 约定数据什么时候发送,不传输数据的时候默认都是高 电平;

2. 起始位:开始发送的时候,发送一个低电平,作为起始 位;

3. 数据位:约定数据位8~9位(正常的通讯协议是5~8位, 但是STM32F0要求是8~9);数据的低位先发送;

4. 校验位:数据发送完成,发送一个可选的校验位,检验 数据的正确性; (奇校验,奇校验位设置1bit值为1,发送的数据里为1的 bit位的个数加上奇校验位的发送的奇校验标志1,一共是奇 数个1,就是正确发送。偶校验同理),一般传输量不大, 不会产生误差,所以一般不校验;

5. 停止位:1到2个bit数据,一般是设置为0;

6. 约定数据传输的速率,一般是用到是9600,115200(不 是纯数据位,包含了起始位等);

例如: 0 1 0 1 0 0 0 0 0 0 **TXD 串口输出0x05波形图、 注意是低位先发送**

1.9 波特率

        在串行通信中,用“波特率”来描述数据的传输速率。所谓 波特率,既每秒传送的二进制位数,其单位为bps(bits per second)。它是衡量串行数据速度快慢的重要指 标。

        国际上规定一个标准的波特率系列: 110、300、600、 1200、1800、2400、4800、9600、115200、 14.4Kbps、19.2Kbps、……

例如:115200bps、指每秒传送115200位。通信双方必 须设置同样的同学速率才能正常通信

注意:实际的数据没这么多,还包括起始位,结束位, 校验位

2. USART寄存器介绍

2.1 控制寄存器 USART_CR

USART_CR1

 32位,其中[31:26]无效,

        以上描述,表明控制寄存器可以配置中断使能、通讯协 议控制位,我们的开发只需要其中的一部分,也够用 了,其他具体的配置需求可以参看手册的24章。

注意:串口通讯协议的 配置,通常是8N1 配置:

8个通讯数据位, N没有奇偶校验,1个停止位;

USART_CR2配置停止位。

USART_CR2

 

 串口通讯协议的 8N1 配置 8个通讯数据位, N没有奇偶校验,1个停止位;

2.2 波特率寄存器 USART_BRR

        记录了 USART 的波特率。手动配置需要有公式去赋值, STM32CubeMX生成的工程会自动帮助配置,具体实现 代码可以用来了解。 

2.3 中断和状态寄存器 USART_ISR

         用于判断输入、释放数据的状态: 控制寄存器中数据发送位(TXE)为1,表示TDR已经有数 据放到移位寄存器TX Shift Reg,等待移位寄存器输出 (写外设)完毕;(发送寄存器(TXE)为空时,注意 USART_TDR 寄存器此时是空的,即可以往 USART_TDR 写入数据。此时写入 USART_TDR 寄存器不会覆盖先前 在 USART_TDR 中的数据,已经到移位寄存器啦。) 控制寄存器中数据接收位(RXNE)为1,表示RDR已经有 数据从移位寄存器RX Shift Reg中一位一位移动过来, 等待被输入(芯片读)完毕;所以置位ISR的数据接收位 (RXNE),就会设置将 RX Shift Reg 接收的数据移动到 USART_RDR 寄存器里,传输出错,ORE被设置,具体 可以参考手册了解。

2.4 数据发送寄存器 USART_TDR

 

2.5 数据接收寄存器 USART_RDR 

只读,不可写,保证读到的是接收到的。

串口的发送和接收过程举例:

上、中、下三部分:下是接收数据过程、中串口速度控 制(波特率)、上发送数据过程 

 

peripheral BUS:外设总线

Transmitter: 发送器

Receiver:  接收器

Buffer:缓冲

Register:寄存器

FIFO:先入先出  一段空间大小的字符串传输,不是一个字节;

什么是FIFO?_大fu啊的博客-CSDN博客_fifo

Clock Source:时钟源

shifter:位移寄存器

Holding Register:存储寄存器

Control Unit:控制器

Non-FIFO 一个字节一个字节传输模式

Control unit 控制单元(检查是否有数据、控制移位寄 存器)

TDR 发送数据寄存器:存储数据,控制单元检测有数据 要传输,放到传输控制寄存器,发送移位会一位一位的 发送出去。

RDR 接收数据寄存器:接收数据,控制单元检测有数据 要读取,接收位移会一位一位的读取,放到接收控制寄 存器。

Buad-rate generator 波特率产生器(控制接收和发送 的速度)

ISR 状态寄存器(发送数据状态TEX,第7位;接收数据状 态RXNE,第5位)

TDR 数据发送寄存器(发送的数据)

RDR 数据接收寄存器(读到的数据)

3 USART开发传输控制流程

3.1 USART硬件原理图分析

注意:如果无法识别串口,安装好ch340串口驱动。我分享了一个链接

链接:https://pan.baidu.com/s/1os__C48tMrrgEjYI-e7fUw?pwd=82gt 
提取码:82gt 

4 实践:USART控制——字符传输读 写

4.1 CubeMX中配置管脚 

设置PA10和PA9分别收发管脚使用** ,且需要注意咱们 是用USART(同步异步串行接口)的异步功能,那么这里 要明确去设置为异步通讯!*

之后要注意配置通讯协议,默认是115200,8N1。

 

 4.2 串口数据的发送和接收

4.3 串口传输函数——读取寄存器方式

在usart.c中编写一下代码 

(1) **串口发送一个字符:**
void Uart_Putchar(uint8_t ch)
{ //等待TDR为空,表示可写,ISR这时TXE是1
while(!(USART1->ISR &(1<<7)));
USART1->TDR = ch;//发送字符
}
(2) **串口接收一个字符:**
uint8_t Uart_Getchar(void)
{ //等待RDR不为空,表示收到数据,ISR这时RXNE是1
while(!(USART1->ISR & (1<<5)));
return USART1->RDR;//返回收到的字符
}

在usart.h中声明函数 

/* USER CODE BEGIN Includes */
void Uart_Putchar(uint8_t ch);
uint8_t Uart_Getchar(void);
/* USER CODE END Includes */

 

Main.c中编写测试代码
char ch = 0;
while (1)
{
ch = Uart_Getchar();
Uart_Putchar(ch);
}

 

编译后再下载到板子上。 板子接上串口线,和电脑连接,设备识别为如下端口:

 

如果你的串口线接线到电脑正确,但是没有识别到端 口,可以尝试安装CH340驱动。 

识别成功后,打开串口助手,配置如下:

配置好后,点击“打开”,在输入框里输入要发送的字符 串,点击“发送”,可以看到接收框内收到对应得字符串。

 

拓展:实现字符串输出函数
void Uart_Putstring(uint8_t *str)
{
    while(*str != '\0')
    {
        Uart_Putchar(*str);
        str++;
    }
}

 4.4 实践:USART控制——字符传输利用库

函数 HAL库中串口的收发函数 在工程stm32f0xx_hal_uart.c文件中,定义了串口传输 库函数。

(1) 串口的发送函数

HAL_UART_Transmit(UART_HandleTypeDef *huart,

uint8_t *pData, uint16_t Size, uint32_t Timeout);

 

(2) 串口的接收函数

HAL_UART_Receive(UART_HandleTypeDef *huart,

uint8_t *pData, uint16_t Size, uint32_t Timeout);

打印一行测试:

 

4.5 实践6:USART控制——实现printf()串 口重定向输出

        printf函数的使用一般是在有屏幕的界面上实现代码的输 出调试功能,而我们的开发环境中一般是没有屏幕的, 此时我们可以将输出转移到其他设备上。在串口开发 中,就经常利用此调试方法。需要注意的是printf函数的 传输调用的是c库中的fputc函数。因此我们如果重新写 了fputc函数,就可以改变printf函数的功能,可以向串 口打印输出。 

int fputc(int ch,FILE *f)
{
    while((USART1->ISR&(1<<7)) == 0);
    USART1->TDR=(uint8_t)ch;
    return ch;
}

这里我之前专门写过一篇介绍输入输出重定向的博文:

STM32——我对输入输出重定向的理解_宇努力学习的博客-CSDN博客_清除txe