在嵌入式系统开发中,串行通信(Serial Communication)是一种非常常见且基础的通信方式,尤其是在与PC、传感器、显示屏或其他微控制器进行数据交换时。STM32微控制器系列提供了强大的USART(通用同步/异步收发器)和UART(通用异步收发器)外设来实现这种通信。要实现高效、可靠的串口通信,仅仅配置好波特率、数据位、停止位和校验位是远远不够的。开发者必须深入理解并熟练运用USART的状态寄存器(SR - Status Register)中的各个标志位(Flag)。这些标志位就像是串口的“状态指示灯”,实时地向我们报告其内部的工作状态和发生的事件。本文将详细介绍STM32中USART的各个关键标志位,帮助你更好地掌控串口通信。
1. USART_FLAG_TXE: 发送数据寄存器空标志
含义: 这是串口发送过程中最核心的标志位之一。它指示USART的发送数据寄存器(TDR - Transmit Data Register)是否为空。TDR是一个缓冲区,CPU将要发送的数据写入这里,然后由硬件自动将数据从TDR转移到发送移位寄存器(Shift Register),再逐位发送出去。
SET: TDR为空,意味着上一个字节已经从TDR转移到移位寄存器,CPU可以安全地向USART_DR(数据寄存器,访问它实际上就是访问TDR或RDR)写入下一个待发送的数据。RESET: TDR不为空,表示TDR中仍存放着待发送或正在发送的数据,此时不应写入新数据,否则可能会覆盖旧数据。
应用场景: 在轮询方式发送数据时,通常需要在一个循环中不断检查TXE标志,确认其为SET后,再将下一个字节写入数据寄存器。这确保了数据的连续发送。
2. USART_FLAG_TC: 传输完成标志
含义: 这个标志位指示一个完整的数据帧(包括数据位、校验位和停止位)已经从发送移位寄存器完全发送出去。它不仅意味着TDR为空,还意味着发送移位寄存器也已空,并且停止位已经发送完毕。
SET: 整个数据帧(从起始位到停止位)已成功发送到物理引脚。RESET: 数据发送尚未完成或正在进行中。
应用场景: TC标志对于需要在完整发送一帧数据后执行特定操作的场景至关重要。例如,在协议通信中,可能需要在发送完一个命令包后切换到接收模式等待响应;或者在多包连续发送时,需要等待前一包完全发送完毕再发送下一包;亦或是在发送完成后进入低功耗模式。
3. USART_FLAG_RXNE: 接收数据寄存器非空标志
含义: 这是串口接收过程中最常用的标志位。它指示USART的接收数据寄存器(RDR - Receive Data Register)中是否包含了一个已接收并准备就绪的数据字节。
SET: RDR中有数据,可以安全地从USART_DR读取这个字节。RESET: RDR为空,没有新的数据可供读取。
注意: 读取USART_DR寄存器会自动清除RXNE标志位。因此,在中断服务程序(ISR)中,通常会先检查RXNE标志,如果为SET,则立即从USART_DR读取数据,这一步操作同时也就清除了标志。
应用场景: 在轮询或中断方式接收数据时,都需要检查RXNE标志。在中断方式下,当检测到接收数据时,硬件会触发RXNE中断,开发者在中断服务程序中读取数据即可。
4. USART_FLAG_IDLE: 空闲线路检测标志
含义: 当USART在接收完一个字符后,如果接收线路(RX线)持续保持“空闲”(逻辑高电平)状态的时间达到或超过一个完整的字符传输时间(包括数据位、校验位和停止位),该标志位就会被置位。这通常表示数据传输的间隙或一帧数据的结束。
SET: 检测到线路空闲,意味着上一包数据可能已接收完毕。RESET: 线路不处于空闲状态,正在接收数据或处于非空闲状态。
应用场景: IDLE标志非常适合用于接收不定长数据包。当一包数据发送完毕,线路会进入空闲状态,触发IDLE中断。开发者可以在IDLE中断服务程序中,将之前通过RXNE中断收集到的数据作为一个完整的包进行处理,而无需预先知道包的长度。
5. 错误标志位
STM32的USART还提供了一系列错误标志位,用于指示接收过程中可能发生的异常情况。及时检查和处理这些错误对于保证通信的可靠性非常重要。
USART_FLAG_ORE(OverRun Error - 溢出错误): 当RDR中已有数据(RXNE为SET)时,如果接收移位寄存器又完成了下一个字节的接收,就会发生溢出。这通常是因为CPU未能及时读取RDR中的数据。读取USART_SR寄存器再读取USART_DR寄存器会清除ORE标志。USART_FLAG_NE(Noise Error - 噪声错误): 在接收过程中检测到线路噪声(例如在停止位期间检测到非预期的低电平)。读取USART_SR寄存器会清除NE标志。USART_FLAG_FE(Framing Error - 帧错误): 接收一个字符时,没有检测到预期的停止位(即停止位期间为低电平)。读取USART_SR寄存器会清除FE标志。USART_FLAG_PE(Parity Error - 奇偶校验错误): 在使能奇偶校验的情况下,接收到的数据奇偶校验失败。读取USART_SR寄存器会清除PE标志。
处理: 在中断服务程序中,除了处理RXNE,也应检查这些错误标志。如果发现错误,可以根据需要记录错误信息、丢弃当前接收的数据或采取其他恢复措施。
其他标志位
USART_FLAG_CTS(Clear To Send): 用于硬件流控制,指示CTS输入引脚状态是否改变。注意UART4和UART5不支持此功能。USART_FLAG_LBD(LIN Break Detection): 用于LIN通信模式,指示检测到LIN间断字符。
关于时钟配置的注意事项
在进行STM32开发时,正确的时钟配置是系统正常工作的前提。如果你的硬件板上的外部高速晶振(HSE)由标准库默认的25MHz改为了8MHz,那么必须相应地修改标准库中的时钟配置参数,否则系统时钟、外设时钟以及波特率等都会计算错误。
- 修改
system_stm32f4xx.c文件: 在该文件中找到#define PLLM 25,将其修改为#define PLLM 8。PLLM是主PLL的预分频系数,它根据HSE频率来计算。 - 修改
stm32f4xx.h文件: 在该文件中找到#define HSE_VALUE 25000000,将其修改为#define HSE_VALUE 8000000。HSE_VALUE定义了外部高速晶振的频率值,库函数会使用这个值来计算各种时钟。
完成这两个修改后,重新编译项目,系统时钟树才会按照8MHz的外部晶振进行正确的配置。
总结
STM32 USART的这些状态标志位是实现精确、可靠串口通信的基石。通过轮询或中断的方式检查这些标志位,开发者可以精确地控制数据的发送时机、及时获取接收的数据、检测并处理通信错误,以及高效地管理不定长数据包的接收。深入理解每个标志位的含义和触发条件,并将其恰当地应用到你的代码中,是掌握STM32串口通信的关键一步。同时,不要忘记根据实际硬件配置(如外部晶振频率)正确设置时钟系统。
本文由 jxxxy 创作,采用 知识共享署名4.0 国际许可协议进行许可。
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。