1.STM32F103 的 USART 介绍

1.1了解

STM32F103的USART(通用同步异步收发器)是一种灵活的全双工通信接口,支持同步和异步模式。

USART与UART的区别:

  • USART:支持同步(需外部时钟)和异步通信,功能更全面,适用于复杂协议。

  • UART:仅支持异步通信,适用于简单的串口通信场景。

  • STM32F103ZET6:提供3个USART(USART1-3)和2个UART(UART4-5)。


USART核心功能:

通信模式

  • 同步模式:需外部时钟信号(CK引脚),适用于高速或时序严格的设备。

  • 异步模式:无需时钟线,依靠预定义的波特率(如常见的串口通信)。

  • 单线半双工:通过一根线实现双向通信(如RS-485)。

USART还支持 LIN(域互连网络)、 智能卡协议与 IrDA(红外线数据协会) SIR ENDEC 规范,以及调制解调器操作 (CTS/RTS)。而且,它还支持多处理器通信和 DMA 功能,使用 DMA 可实现高速数据通信。USART 还通过小数波特率发生器提供了多种波特率。


数据帧:

作用:

数据帧在通信中的作用非常重要,尤其是在像 UART 这样的串行通信协议中。直接传输数据并没有提供必要的控制信息和同步机制,而数据帧则通过结构化的数据封装确保了通信的顺利进行。

一帧数据在 UART 通信中通常包含以下几个部分:

  1. 起始位 (Start bit)
  2. 数据位 (Data bits)
  3. 奇偶校验位 (Parity bit) (可选)
  4. 停止位 (Stop bits)

典型的 UART 数据帧格式如下:

起始位 数据位(8位) 奇偶校验位(可选) 停止位(1位/1.5位/2位)
1 8 1 1 / 1.5 / 2

因为 UART 是 异步通信 协议,因此不需要外部时钟信号来同步数据的发送与接收。每一帧的数据在发送时会通过数据线传输,而接收端需要依赖 波特率 (Baud Rate) 来确保发送和接收的数据时序匹配。双方在通信开始前需要约定好波特率,以确保传输的顺利进行。

通信配置方式:

1. IO口模拟时序(通用功能)

  • 控制方式:通过软件手动拉IO口高低电平来模拟时序。
  • 特点
    • 关注时序,程序控制I/O口电平。
    • 无需关注硬件配置。
  • 优点:灵活、程序移植性强。
  • 缺点:效率低、容易出错。

2. 配置通信控制器(复用功能)

  • 控制方式:通过串口控制器自动拉IO口高低电平来模拟时序。
  • 特点
    • 依赖硬件控制器配置,关注寄存器设置。
    • 无需手动控制时序,硬件自动完成。
  • 优点:高效、准确、稳定。
  • 缺点:对硬件依赖较强,移植性差。

1.2串口的基本结构分析

串口内部结构框图:

串口内部结构分为传输数据过程部分控制部分波特率部分3个部分。

传输数据过程部分:

STM32F103的串口数据传输主要依赖于 数据寄存器 (DR)移位寄存器 (Shift Register) 的配合。

DR 实际是包含了两个寄存器,一个专门用于发送的可写 TDR,一个专门用于接收的可读 RDR。当进行发送操作时,往 DR 写入数据会自动存储在 TDR 内;当进行读取操作时,向 DR 读取数据会自动提取 RDR 数据。为了方便写程序,TDR和RDR统一为DR,所以开发人员在写程序的时候,无论发送还是接收只需要写DR。。

图中小实心箭头表示是逐位串行传输,大空心箭头表示是多位并行传输。


  • TX:发送数据输出引脚。
  • RX:接收数据输入引脚。
  • SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚。
  • IRDA_OUT 和 IRDA_IN:这些可能是红外数据协会(IrDA)接口的输入和输出引脚,用于通过红外光进行数据传输。

发送数据过程:

内核(CM3)层写入数据到 发送数据寄存器(TDR),发送数据寄存器将数据放入发送移位寄存器,发送移位寄存器逐位将数据发送到串口线路。

        注意:内核CM3写数据到发送数据寄存器之前要检测之前的发送是否完成发送,如果发送完成可以写到发送数据寄存器,发送未完成则要等待发送完成。

接收数据过程:

接收移位寄存器从串口线路接收到数据时,数据会逐位地接收到 接收数据寄存器(RDR)中,接收数据寄存器将接收到的完整数据存入寄存器后,内核(CM3)会从接收数据寄存器中读取数据到变量。

        注意:内核CM3在读数据前要检测是否接收完成,接收完成就可以读到变量中,如果没有接收完成,要等待接收完成再读到变量中。

如何检测数据是否发送完成或接收完成:       

1. 发送完成标志位(TX Complete)和接收完成标志位(RX Ready)

  • 这是最常用且直接的方式,大多数通信协议(如UART等)的硬件模块会提供状态寄存器(Status Register),通过标志位(Flag)指示当前操作状态。

2. 硬件流控制信号(nRTS和nCTS):(不常用)

  • 发送方在准备好发送数据时,拉低 nRTS 信号,表明它准备好了发送。
  • 接收方在准备好接收数据时,拉低 nCTS 信号,告诉发送方它已经准备好接收数据。
  • 发送方监控 nCTS 信号,只有在 nCTS 为低电平时,才开始发送数据。如果 nCTS 为高电平,发送方会暂停数据发送,直到接收方准备好。

控制部分:

  • nRTS:请求以发送(Request To Send),n 表示低电平有效。如果使能 RTS 流 控制,当 USART 接收器准备好接收新数据时就会将 nRTS 变成低电平;当接收 寄存器已满时,nRTS 将被设置为高电平。该引脚只适用于硬件流控制。
  • nCTS:清除以发送(Clear To Send),n 表示低电平有效。如果使能 CTS 流 控制,发送器在发送下一帧数据之前会检测 nCTS 引脚,如果为低电平,表示可 以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用 于硬件流控制。
  • SCLK发送器时钟输出引脚。这个引脚仅适用于同步模式。

 具体要怎么配置到了配置寄存器的时候再详细讲,这部分在这里先不深入。

波特率部分:

USART波特率的计算公式为:

其中,USARTDIV 是一个无符号定点数,由整数部分(DIV_Mantissa)和小数部分(DIV_Fraction)组成,分别存储在波特率寄存器 USART_BRR 的位域中。

计算步骤:

1.确定目标波特率(如9600、115200等)和 USART时钟频率 fck​(如16MHz、72MHz)。

2.计算 USARTDIV

3.分解整数和小数部分

  • 整数部分:直接取整数位(DIV_Mantissa)。
  • 小数部分:将小数乘以16,四舍五入到最近的整数(0-15),作为 DIV_Fraction。

4.组合寄存器值

  • USART_BRR 的格式为:DIV_Mantissa[11:0] << 4 | DIV_Fraction[3:0]

示例:

1.目标波特率 = 9600,fck=8MHz

  • 整数部分:52(0x34)

  • 小数部分:0.0833 × 16 ≈ 1.33 → 取1(0x1)

  • USART_BRR = 0x341,实际波特率 ≈ 9603.84(误差 0.04%)。

2.目标波特率 = 115200,fck=72MHz

  • 整数部分:39(0x27)

  • 小数部分:0.0625 × 16 = 1(0x1)

  • USART_BRR = 0x271,实际波特率精确为115200。

***简便算法***

USART->BRR = 主频/波特率

USARTDIV 是一个有符号的浮点数,但它需要经过处理才能写入 USART_BRR 寄存器。

具体来说,USARTDIV 需要乘以 16(二进制左移4位),去掉小数点部分,得到一个整数值,再写入 USART_BRR 寄存器。

即:

***简便算法***

2.使用参考手册查看USART寄存器

状态寄存器(USART_SR)

功能:用于存储与串行通信相关的状态信息,包括错误检测、数据接收与发送的标志位。

  • CTS (Clear to Send):
    该标志位用于流控制。如果硬件流控制启用并且 CTS 信号有效时,该标志位为 1。

  • LBD (LIN Break Detection):

    当LIN总线检测到断开信号(如在LIN协议中接收到持续的低电平)时,此标志位被设置为 1,表示出现了总线中断的情况。  (用于局域网的,跟串口没有关系)

  • TXE (Transmit Data Register Empty):
    当传输数据寄存器为空时,该标志位会被设置为 1,表示可以向传输寄存器中写入新的数据。

  • TC (Transmission Complete):
    该标志位表示传输操作完成,数据寄存器的内容已完全发送。

  • RXNE (Receive Data Register Not Empty):
    当接收寄存器中有新的数据可供读取时,该标志位会被设置为 1。此时,可以从接收数据寄存器读取数据。

  • IDLE (Idle Line Detected):
    当接收到的数据帧中没有数据,并且线路处于空闲状态时,该标志位会被设置为 1。(到了中断的时候用)

  • ORE (Overrun Error):
    该标志位表示接收缓冲区发生了溢出(即接收缓冲区已满,新的数据无法存储)。能检查,无法解决问题,如果按照标准形式配置是不会上溢的,所以这个没用)

  • NE (Noise Error):
    当接收到的数据中包含噪声时,该标志位会被设置为 1。(同ORE一样只能查,而且跟串口没关系)

  • FE (Framing Error):
    如果接收到的数据帧的起始位或停止位异常(例如位长错误),此标志位被设置为 1。(也是只能查,没用)

  • PE (Parity Error):
    当接收到的数据具有奇偶校验错误时,此标志位会被设置为 1。奇偶校验错误的校验一定表示数据出错,但正确的校验不代表数据一定正确,很鸡肋,我们不用)

重点关注:TXE    TC    RXNE(TXE和TC的功能是一样的,用一个就行,推荐TC)

具体配置:

数据寄存器(USART_DR) 

功能:存储接收和待发送的数据。(我们可以把它当成一个变量来用就行)

具体配置:

 波特率寄存器(USART_BRR)

功能:通过设置波特率来控制串行通信的速度。 

控制寄存器 1(USART_CR1) 

功能:用于控制USART的各项功能和操作。通过配置 USART_CR1 寄存器,用户可以启用或禁用多种USART功能,包括启用发送和接收、设置数据位、启用中断等。

  • UE (USART Enable):                                                                                                              当设置此位为 1 时,启用 USART 外设。此位用于开启或关闭 USART 模块。(一般写在串口初始化函数的最后)

  • M (Word Length)):

    设置为 0 时,表示每个数据帧有 8 位;设置为 1 时,表示每个数据帧有 9 位。这位控制数据帧的长度。(一般用8位,好处理)

  • WAKE (Wakeup Method):
    此位设置为 1 时,启用接收模式下的唤醒功能。唤醒模式允许在接收到数据后从低功耗模式中唤醒处理器。若设置为 0,则为常规模式。(不用)

  • PCE (Parity Control Enable):
    当设置为 1 时,启用奇偶校验功能。此位决定 USART 是否使用奇偶校验。(不用奇偶校验)

  • PS (Parity Selection):
    此位用于设置奇偶校验的类型。如果设置为 1,表示使用奇校验;设置为 0,表示使用偶校验。(不用奇偶校验)

  • PEIE (Parity Error Interrupt Enable):
    当设置为 1 时,启用奇偶校验错误中断。当接收到的数据中出现奇偶校验错误时,会触发此中断。(不用奇偶校验)

  • TXEIE (TXE Interrupt Enable):
    当设置为 1 时,启用发送数据寄存器空中断。当数据发送寄存器为空时,触发此中断,表示可以向发送寄存器中写入数据。(到了中断的时候用)

  • TCIE (Transmission Complete Interrupt Enable):
    当设置为 1 时,启用传输完成中断。当数据传输完全完成并且发送寄存器为空时,会触发此中断。(到了中断的时候用)

  • RXNEIE (RXNE Interrupt Enable):
    当设置为 1 时,启用接收数据寄存器非空中断。当接收寄存器中有新数据可供读取时,会触发此中断。(到了中断的时候用)

  • IDLEIE (Idle Interrupt Enable):
    当设置为 1 时,启用空闲线检测中断。当接收线路为空闲状态并且没有接收到数据时,会触发此中断。(到了中断的时候用)

  • TE (Transmitter Enable):
    当设置为 1 时,启用 USART 发送功能。此位控制 USART 是否能够发送数据。(全双工模式该寄存器和RE都要打开)

  • RE (Receiver Enable):
    当设置为 1 时,启用 USART 接收功能。此位控制 USART 是否能够接收数据。(全双工模式该寄存器和TE都要打开)

  • RWU (Receiver Wakeup):
    当设置为 1 时,启用接收器的唤醒功能,用于低功耗模式下的唤醒操作。(不用)

  • SBK (Send Break):
    当设置为 1 时,发送一个 Break 信号,常用于同步或错误指示。(不用)

重点关注:UE        M        TE        RE

具体配置:

控制寄存器 2(USART_CR2)

 

功能:用于配置 USART 的一些关键功能,控制数据传输和接收的不同模式。

  • LINEN (LIN Mode Enable):                                                                                                        当设置此位时,USART 工作在 LIN (Local Interconnect Network) 模式下。启用 LIN 模式后,USART 通过特定的帧格式进行通信。(不用)

  • STOP[1:0] (Stop Bits):

    00: 1 停止位(标准),01: 0.5 停止位(不常用),10: 2 停止位,11: 1.5 停止位(仅在 9 位数据模式下有效)。 

  • CLKEN (Clock Enable):
    此位控制 USART 时钟的启用与禁用。启用此位后,USART 可以输出时钟信号,用于同步模式下的通信。(串口通信是异步的,不用时钟线 ,不用)

  • CPOL (Clock Polarity):
    该位控制时钟的极性。当 CPOL 设置为 0 时,时钟信号的空闲状态为低电平;当 CPOL 设置为 1 时,时钟信号的空闲状态为高电平。(同上,不用)

  • CPHA (Clock Phase):
    该位控制数据采样的时机。CPHA 设置为 0 时,数据在时钟的第一个边缘被采样;当 CPHA 设置为 1 时,数据在时钟的第二个边缘被采样。(同上,不用) 

  • LBCL (Last Bit Clock Pulse):
    此位用于控制最后一个数据位之后是否发送时钟脉冲。如果设置为 1,则最后一个数据位之后会产生一个时钟脉冲。(同上,不用)  

  • LBDIE (LIN Break Detection Interrupt Enable):
    该位使能 LIN 中断。当接收到 BREAK 字符时,如果启用了此位,USART 将会触发中断。(不用) 

  • LBDL (LIN Break Detection Length):
    此位控制 BREAK 字符的检测长度。设置为 0 时,BREAK 字符的持续时间为 10 个位周期,设置为 1 时,持续时间为 11 个位周期。(不用)

  • ADD[3:0] (Address of the USART):
    这些位用于设置 USART 地址。它们用于在多机通信时区分不同的设备,地址值用于确定数据帧是否为目标设备的通信数据。(不用)

重点关注: STOP[1:0]

具体配置:

 

  

控制寄存器 3(USART_CR3) 

功能:主要用于配置流控制、DMA 等功能。

  • CTSIE (CTS Interrupt Enable):                                                                                              此位用于启用 CTS 中断。当 CTS 信号发生变化时,如果启用了此位,USART 将触发中断。(不用)

  • CTSE (CTS Enable):
    该位用于启用接收方流控制中的CTS(Clear to Send)功能。设置为1时,USART会启用CTS流控制。(不用)

  • RTSE (RTS Enable):
    该位用于启用发送方流控制中的RTS(Request to Send)功能。设置为1时,USART会启用RTS流控制。(不用)

  • DMAR (DMA Enable Receiver):
    该位启用接收 DMA(直接内存存取)。设置为 1 时,USART 将允许 DMA 在接收数据时直接写入内存。通过 DMA,可以提高数据处理效率,避免 CPU 的干预。(不用)

  • SCEN (Smartcard Mode Enable):
    该位启用智能卡模式。设置为 1 时,USART 将工作在智能卡模式下,这种模式用于与智能卡通信。(不用)

  • NACK (Smartcard No Acknowledge):
    在智能卡模式下,当 NACK 设置为 1 时,USART 不会发送确认(ACK)信号。(不用) 

  • HDSEL (Half-Duplex Selection):
    该位选择是否启用半双工模式。在半双工模式下,数据只能在同一时间在一个方向上传输,而不能同时进行发送和接收。设置为 1 时启用半双工模式。(串口通常是全双工的,默认为0就好,不用配置)

  •  IRLP (IrDA Low-Power Mode):
    此位控制 IrDA 模式的低功耗模式。当设置为 1 时,IrDA 模式进入低功耗工作模式,以减少能耗。(不用)

  •  IREN (IrDA Mode Enable):
    此位用于启用 IrDA(红外数据)模式。设置为 1 时,USART 工作在 IrDA 模式下,这意味着数据传输是基于红外信号的。(不用)

  •  EIE (Error Interrupt Enable):
    当设置此位时,USART 会在出现帧错误、奇偶校验错误、溢出错误等错误时触发中断。启用此功能有助于在通信中及时检测错误并处理。(不用)

具体配置:

保护时间和预分频寄存器(USART_GTPR)

功能:配置保护时间和预分频功能,影响USART数据的发送和接收速率。

  • Guard Time (GT) 提供了接收方的保护时间,可以防止数据之间出现错误。
  • Prescaler (PSC) 调整了USART时钟的分频,从而控制了波特率,确保数据的准确传输。

具体配置:

 串口模块需要配置的寄存器

1.状态寄存器 (USART_SR)

  • 位 6 (TC):
    TC(Transmission Complete)表示传输完成标志。当数据寄存器的数据成功从发送移位寄存器转移到数据线时,设置为1。
  • 位 5 (RXNE):
    RXNE(Receive Data Register Not Empty)接收数据寄存器非空标志,表示接收缓冲区有数据。当数据寄存器收到数据并且尚未读取时,RXNE设置为1。

2. 数据寄存器 (USART_DR)

  • 该寄存器用于传输数据。
  • 发送数据时,写入此寄存器。
  • 接收数据时,读取此寄存器。
  • 数据的大小为 8 位或 9 位,取决于配置。

3. 波特率寄存器 (USART_BRR)

  • 该寄存器用于设置串口的波特率。它由两个部分组成:
    • DIV_Mantissa (高 12 位)
    • DIV_Fraction (低 4 位)

4. 控制寄存器 1 (USART_CR1)

  • 位 13 (UE):
    UE(USART Enable)使能串口。当该位被设置为1时,USART 被启用,可以进行发送和接收操作。
  • 位 12 (M):
    M(Word Length)设置数据帧长度。当该位为0时,数据位宽为 8 位;为 1 时,数据位宽为 9 位。
  • 位 3 (TE):
    TE(Transmitter Enable)使能数据发送。设置为1时,串口可以进行数据发送。
  • 位 2 (RE):
    RE(Receiver Enable)使能数据接收。设置为1时,串口可以进行数据接收。

5. 控制寄存器 2 (USART_CR2)

  • 位 13、12 (STOP[1:0]):
    STOP[1:0](Stop Bits)用于设置停止位的长度。
    • 00: 1个停止位
    • 01: 0.5个停止位
    • 10: 2个停止位
    • 11: 1.5个停止位

3.掌握串口的编程步骤

3.1串口初始化函数

void usartX_init(u32 bps)

/***************************************************************************
*函数名			:usartX_init
*函数功能		:串口USARTX初始化
*函数参数		:u32 bps
*函数返回值		:无
*函数描述		:输入波特率bps,初始化USARTX
***************************************************************************/

IO口初始化配置

  • 使能GPIO端口时钟
    通过设置RCC->APB2ENR寄存器对应位,使能串口TX/RX引脚所属GPIO端口的时钟。
    示例:若使用PA9(TX)和PA10(RX),需使能GPIOA时钟:
    RCC->APB2ENR |= (1 << 2);
  • 配置TX引脚模式
    TX引脚(如PA9)需配置为复用推挽输出模式,以支持串口发送功能。                                    操作GPIO的CRH或CRL寄存器,设置对应引脚模式。
    示例:PA9的CRH[11:8]设置为0x9(复用推挽输出,最大速度10MHz)。
  • 配置RX引脚模式
    RX引脚(如PA10)需配置为浮空输入模式,以正确接收数据。                                                操作GPIO的CRH或CRL寄存器,设置对应引脚模式。
    示例:PA10的CRH[15:12]设置为0x4(浮空输入)。
  • 复用重映射配置(可选)
    若使用默认引脚(如USART1的PA9/PA10),无需重映射,保持AFIO->MAPR寄存器默认值即可。若需重映射到其他引脚(如PB6/PB7),需设置AFIO->MAPR对应位。
    示例:禁用USART1重映射:
    AFIO->MAPR &= ~(1 << 2);

串口控制器配置

  • 使能串口时钟
    通过设置RCC->APB2ENR寄存器对应位,使能USART外设时钟。
    示例:使能USART1时钟:
    RCC->APB2ENR |= (1 << 14);
  • 配置数据位长度(8位)
    设置CR1寄存器的M位为0,选择8位数据格式:
    USARTx->CR1 &= ~(1 << 12);
  • 使能发送功能
    设置CR1寄存器的TE位为1,开启发送功能:
    USARTx->CR1 |= (1 << 3);
  • 使能接收功能
    设置CR1寄存器的RE位为1,开启接收功能:
    USARTx->CR1 |= (1 << 2);
  • 配置停止位(1个停止位)
    设置CR2寄存器的STOP[1:0]位为00,选择1个停止位:
    USARTx->CR2 &= ~(3 << 12);
  • 配置波特率
    根据主频和波特率计算BRR寄存器的值:
    公式:BRR = 主频 / 波特率
    示例:主频72MHz,波特率9600时:                                                                                          BRR = 72000000 / 9600 = 7500                                                                                            赋值给BRR寄存器:                                                                                                                    USARTx->BRR = 7500;
  • 使能串口
    设置CR1寄存器的UE位为1,使能串口功能:
    USARTx->CR1 |= (1 << 13);

RX/TX引脚配置及复用模式说明

1. TX引脚(发送端)配置

  • 模式选择复用推挽输出(AF_PP)

  • 原因
    TX引脚需要由外设(如USART)硬件直接控制输出电平。配置为复用模式后,外设模块(如USART_TX)将接管引脚驱动,自动生成信号波形(如串口数据帧)。

2. RX引脚(接收端)配置

  • 模式选择浮空输入(IN_FLOATING)

  • 原因
    RX引脚需处于输入状态以正确接收外部信号。外设(如USART_RX)通过专用硬件路径直接读取引脚电平,与GPIO的输出电路无关。

  • 将RX引脚配置为复用推挽输出(AF_PP)时仍能接收数据:                                        当RX引脚配置为复用推挽输出(AF_PP)时,若外设未主动驱动输出,其输出电路处于高阻态,此时输入路径独立工作,仍可通过引脚电平捕获外部信号,从而实现数据接收。配置为输出不影响输入

注意:

复用输入无需配置为复用模式

  • 并没有复用输入这个配置的,只不过我们这样叫而已。

  • STM32的复用输入确不需要特定的模式,而是通过配置为普通输入模式(浮空、上拉、下拉)并启用外设功能来实现的。

  • 复用输入的本质是外设直接读取引脚电平,因此只需将GPIO设为输入模式(浮空/上拉/下拉)。

  • 复用功能通过外设使能自动绑定,无需额外配置GPIO复用寄存器。

  • 官方推荐配置:将RX引脚设为浮空输入上拉输入

  • STM32的复用输入通过以下步骤实现:
    1. 配置GPIO为输入模式(浮空、上拉或下拉)。

    2. 启用外设的复用功能(如USART的RX功能)。

    3. 外设自动将GPIO引脚与内部外设模块连接。

复用输出必须配置复用模式

  • 复用输出需要将GPIO设为复用推挽或开漏模式,确保外设控制输出驱动器。

3.2发送一个字节函数

void usartX_send_byte(u8 data)

/***************************************************************************
*函数名			:usartX_send_byte
*函数功能		:串口USARTX发送一个字节
*函数参数		:u8 data
*函数返回值		:无
*函数描述		:等待发送寄存器空后写入数据给数据寄存器
***************************************************************************/
  • 等待发送完成:检查 USART1->SR 寄存器中的第6位(TC 位)来判断是否发送完成。如果 TC 位为1,表示完成,可以继续发送数据。如果 TC 位为0,则等待直到 TC 位变为1。

  • 发送数据:一旦发送完成,函数将传入的 data 写入 USART1->DR 寄存器,从而通过 USARTX 发送一个字节的数据。

3.3接收一个字节函数

u8 usartX_rec_byte(void)

/***************************************************************************
*函数名			:usartX_rec_byte
*函数功能		:串口USARTX接收一个字节
*函数参数		:无
*函数返回值		:u8
*函数描述		:等待接收数据就绪后读取,直接返回寄存器值
***************************************************************************/
  • 等待接收数据就绪:检查 USART1->SR 寄存器中的第5位(RXNE 位)来判断是否有数据接收到。如果 RXNE 位为1,表示接收数据寄存器中有数据,可以读取。如果 RXNE 位为0,则等待直到 RXNE 位变为1。

  • 读取数据:一旦接收数据寄存器中有数据,函数直接返回 USART1->DR 寄存器中的值,即接收到的字节数据。

3.4发送一个字符串函数

void usartX_send_str(u8 *str)

/***************************************************************************
*函数名			:usartX_send_str
*函数功能		:串口USARTX发送一个字符串
*函数参数		:u8 *str
*函数返回值		:无
*函数描述		:逐字节发送字符串,直到遇到空终止符'\0'
***************************************************************************/
  • 遍历字符串:通过一个 while 循环遍历传入的字符串 str,直到遇到字符串的终止符 \0

  • 逐字节发送:在循环中,每次调用 usartX_send_byte 函数发送当前字符(*str),然后将指针 str 向后移动一位,指向下一个字符。

  • 终止条件:当遇到字符串的终止符 \0 时,循环结束,函数执行完毕。

3.5接收一个字符串函数

void usartX_send_str(u8 *str)

/***************************************************************************
*函数名			:usartX_send_str
*函数功能		:串口USARTX发送一个字符串
*函数参数		:u8 *str
*函数返回值		:无
*函数描述		:接收字符串,直到遇到终止符'#'
***************************************************************************/
  • 循环接收字符:通过一个无限循环(while(1))持续接收字符。

  • 接收字节数据:每次调用 usart1_rec_byte 函数接收一个字节的数据,并将其存储到 str 指向的内存位置。

  • 检查终止符:如果接收到的字符是终止符 #,则跳出循环。

  • 指针后移:如果接收到的字符不是终止符,则将指针 str 后移,指向下一个存储位置。

  • 添加字符串终止符:在循环结束后,将 \0 添加到字符串末尾,表示字符串结束。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐