STM32外设学习--USART串口协议--学习笔记。
STM32F103C8T6,也就是我们常说的“蓝色药丸”或“Blue Pill”核心板,拥有3个USART(USART1, USART2, USART3)和2个UART(UART4, UART5)。USART和UART的主要区别在于USART支持同步通信(有时钟线)和异步通信,而UART只支持异步通信。我们日常使用的大部分场景都是异步模式。
一.USART基本概念
1. USART 基础概念
USART是一种全双工、异步串行通信协议。其核心特征如下:
-
全双工:可以同时进行数据的发送和接收。
-
异步:通信双方没有共享的时钟信号,依靠预先约定好的波特率 来同步数据。
-
点对点:通常是一个设备对另一个设备。
-
帧结构:数据被封装成一个个标准的“数据帧”进行传输。
2. 数据帧格式
一个完整的USART数据帧由以下几部分组成:
| 组成部分 | 描述 | 位数 |
|---|---|---|
| 起始位 | 总是逻辑0,表示一帧数据的开始,用于同步。 | 1位 |
| 数据位 | 实际要传输的数据,可以是8位或9位。通常是8位(一个字节)。 | 8或9位 |
| 校验位 | 可选的错误检测位,可以是奇校验、偶校验或无校验。 | 0或1位 |
| 停止位 | 总是逻辑1,表示一帧数据的结束。可以是0.5, 1, 1.5或2位。 | 1, 1.5, 2位 |
一个典型的数据帧(8N1):1个起始位 + 8个数据位 + 无校验位 + 1个停止位,共10位。
波形图示例(发送数据 0x55,二进制 0101 0101):
空闲状态(高电平)||起始位 | D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 |停止位| 空闲...|___|___|___|___|___|___|___|___|___|___|| 0 1 0 1 0 1 0 1 | 1 ...|<------------- 一个完整的数据帧 (10 bits) ------------>|
注意:数据传输是从最低位(LSB)开始的,所以0x55(01010101b)在线上看到的顺序是1-0-1-0-1-0-1-0。
3. STM32F103C8T6 的 USART 关键特性
-
高精度波特率发生器
-
由专用的16位分频器(USART_BRR寄存器)控制。
-
计算公式:
Tx/Rx Baud = f_PCLKx / (16 * USARTDIV)-
USART1挂载在APB2总线(PCLK2,最高72MHz)。
-
USART2/3挂载在APB1总线(PCLK1,最高36MHz)。
-
-
例如,USART1在72MHz下产生115200的波特率:
USARTDIV = 72000000 / (16 * 115200) = 39.0625。
-
-
数据寄存器(USART_DR)
-
这是一个双缓冲寄存器(TDR用于发送,RDR用于接收),意味着你可以写入下一个要发送的数据,而当前数据正在发送;也可以读取上一个接收到的数据,而新的数据正在接收。
-
-
丰富的状态标志和中断
-
TXE(发送数据寄存器空):TDR为空,可以写入下一个数据。(常用)
-
TC(发送完成):一帧数据已完全发送(包括停止位)。(常用)
-
RXNE(接收数据寄存器非空):RDR中有新数据到达,可以读取。(常用)
-
ORE(溢出错误):新数据已经收到,但之前的RXNE标志未被清除,导致数据丢失。
-
这些标志都可以触发中断,使得程序可以高效地处理收发任务。
-
-
多种工作模式
-
轮询模式:主循环中不断检查TXE和RXNE标志。简单,但效率低下,会阻塞CPU。
-
中断模式:当TXE/RXNE等事件发生时,触发中断,在中断服务程序(ISR)中处理数据。效率高,响应及时。
-
DMA模式:无需CPU介入,直接在USART和内存之间传输大量数据。效率最高,适合高速数据流。
-
4. 配置步骤(以异步模式为例)
以下是使用HAL库进行配置的典型步骤:
1. 初始化GPIO
-
将USART的TX引脚配置为复用推挽输出。
-
将USART的RX引脚配置为浮空输入或上拉输入。
2. 配置USART外设
3. 使能中断(如果使用中断或DMA模式)
-
在NVIC中配置并使能USART全局中断。
4. 实现数据收发
5. 编写中断服务程序(ISR)
-
如果使用了中断,需要在对应的中断向量中调用 。
-
你可以重写HAL库的回调函数,来处理发送/接收完成后的逻辑。
5. 硬件连接
STM32F103C8T6与PC或其他MCU的连接非常简单:
-
STM32的TX <--> 对方设备的RX
-
STM32的RX <--> 对方设备的TX
-
GND <--> GND(非常重要! 确保共地)
当与PC通信时,需要一个USB转TTL串口模块(如CH340G, CP2102, FT232RL)。
6. 常见问题与调试技巧
-
通信失败,全是乱码
-
首要原因:波特率不匹配! 检查双方设备的波特率设置是否完全一致。
-
检查时钟配置,特别是
PCLK1和PCLK2的频率是否正确。 -
检查数据帧格式(数据位、停止位、校验位)是否一致。
-
-
只能发送,不能接收(或反之)
-
检查TX和RX线是否接反。
-
检查GPIO模式是否正确(TX必须是AF_PP,RX必须是IN_FLOATING/IN_PULLUP)。
-
检查是否使能了接收中断或DMA。
-
-
使用中断/DMA时数据丢失
-
确保中断优先级设置正确,且没有在中断服务程序中执行耗时操作。
-
对于接收,要确保在数据到来前已经调用了接收函数。
-
-
调试工具
-
逻辑分析仪:可以直观地看到线上的波形,验证数据帧格式和内容。
-
串口调试助手(如Putty, Tera Term, 串口猎人):用于在PC端发送和接收数据,是最常用的调试工具。
-
二.流程图
1.简介
再STM32里集成了很多用于通讯的外设模块。如图

这些通讯接口我们的C8T6是全部支持的,我们先来学习第一个通讯USART(串口)。
通讯的目的,是为了将一个设备的数据传送到另一个设备,廓然硬件系统。比如说我们的STM32集中了很多的功能模块,比如说ADC采集,定时器计数,PWM输出等等,这些都是芯片内部的电路,这些电路的配置寄存器,数据寄存器都在芯片里面,操作这些寄存器非常简单,直接读取就可以了。但是也有一些功能是我们STM32内部没有的,比如蓝牙遥控,陀螺仪加速度计测量姿态的功能,STM32没有,就只能外挂芯片来实现。外挂的芯片数据都在STM32外面,那么STM32如何获取的呢这就需要我们再两个设备之间,连接上一根或多跟通讯线,通过通讯线路发送或接收数据,完成数据交换。
通讯协议:制定通讯的规则,通讯双方按照协议规则进行数据收发。
比如说I2C通讯,SCL是时钟,SDA是数据。
全双工代表可以双向通讯,全双工通讯一般有两根通讯线,比如说串口,一根TX发送,一根RX接收。同步异步是时钟特性。
单端信号的通讯他们引脚的高低电平都是对地的电压差,所以单端通讯的双方必须共地,就是把GND接在一起。虽然USB是差分信号,但是有一些单端的,是需要共地的,使用差分信号,可以极大的提高抗干扰特性。所以一般差分信号的传输距离和速度,都会非常高。
多设备就是可以再总线上刮起多个设备。
2.串口通信

在单片机中,串口是最简单的一种通讯,对比SPI和I2C来说相当简单,而且一般单片机都会有串口的硬件外设,使用也是非常方便的。

这个是USB转串口模块,芯片是CH340这个芯片可以把串口协议,转化为USB协议。

这个是陀螺仪传感器模块,可以测量角速度,加速度这些参数。左右各有四个引脚,一边是串口引脚,一边是I2C引脚。

蓝牙串口模块,下面的引脚是串口通讯引脚,上面的芯片可以连接手机。
3.串口接线图

一般串口通讯都有四个引脚,VCC,TX,RX,GND。TX和RX是单端信号,他们的高低电平是相对于GND的,所以GND应该也算一个通讯线,串口通讯的TX,RX,GND是必须要接的,上面的VCC如果两个设备都有独立的供电,那么就可以不接。
如果其中一个设备没有供电模块,就要把两个设备的VCC接在一起。
这是简单的串口通讯,难的串口通信有时钟引脚,硬件流控制引脚。TX与RX要交叉连接,TX是发送RX是接收。那么就是一个设备的发送接另一个设备的接收,一个设备的接收,接另一个设备的发送。
一般像我们这种从控制器里出来的信号,是TTL信号,相同的电平才能互相通讯,不同的电平讯号需要加一个电平转换芯片。
4.串口常用的电平标准

RS232一般在大型设备上使用,因为由于环境比较恶略,静电干扰比较大。所以这里电平的电压比较大而且允许波动的范围也很大。
RS485电平是一对差分信号。差分信号抗干扰非常强,使用RS485电平标准,通讯距离可达上千米。而上面的两种电平,像单片机这种低压小型设备使用的都是TTL电平。需要别的电平的话。直接加一个电源转换芯片,就可以了。协议规定是一个设备TX发送高低电平另一个设备RX接收高低电平。
在线路中使用TTL电平,因为STM32是3.3V器件,所以说线路对地是3.3V就代表发送了逻辑1。如果线路对地是0V就代表发送了逻辑0。
5.软件部分-串口参数及时序

如何用1和0来组成我们想要发送的一字节数据。下面的图就是串口发送的时序图,这就是串口发送一个数据的格式。这个格式是串口协议规定的。

串口中每一个字节都装载在一个数据帧里面。每个数据帧都由起始位,数据位,停止位构成。这里数据位有8个代表一个字节的8位。在后面的图里面

话可以在最后加一个奇偶校验位,这样数据位其实就是9位,有效载荷位是前8位。代表一个字节。校验位在最后占一位。
(1)波特率
串口通讯的速率,我们之前说了串口一般是异步通讯,所以需要双方约定一个通讯速率,比如说一个设备每隔一秒发送一位,那么另一个设备就要每隔一秒接收一位。如果接收快了,那么就会重复接收某些位,如果接收慢了,就会漏掉某些位。所以说发送和接收必须要约定好速率。这个速率就是波特率,波特率的意思是每秒传送码元的速度,单位是码元/s,或者直接叫波特。
还有一个速率叫比特率,比特率的意思是每秒传输的比特数。单位是bit/s,或者叫bps。在二进制调制的情况西=下,每一个码元就是一个bit。此时波特率就等于比特率,像我们单片机串口通讯,基本都是二进制调制。也就是高电平表示1低电平表示0.1位就是1bit。
所以说串口的波特率经常会和比特率混用。如果是多进制调制,那么波特率和比特率就不一样了,需要注意一下。
比如说我们双方规定波特率为1000bps,那就表示1S要发1000位。每一位的事件就是1ms。

也就是这里,这一段事间是1ms。发送方每隔1ms发送1位,就收方,每隔1ms就收一位。这就是波特率,它决定了每隔多久发送一位。
(2)起始位和停止位
他是标志一个数据帧的开始固定为低电平。

首先串口的空闲状态时高电平,也就就是没有数据传输的时候引脚必须要设置高电平,作为空闲状态。
然后需要传输的时候必须要发送一个起始位这个起始位必须时低电平,来打破空闲时候的高电平,产生一个下降沿,这个下降沿就告诉设备,这一帧数据要开始了。如果没有起始位,当我们发送8个1时候数据线就会一直是高电平,没有任何波动。
同理在一个数据发送完成后,必须要有一个停止位,用于数据帧间隔,固定为高电平,同时这个停止位,也是为了下一个起始位做准备的。如果没有停止位,当我最后一个数据是0的时候,下次在发送新的一帧就没办法产生下降沿了。
起始位固定为0产生下降沿,表示传输开始。停止位固定为1把引脚恢复为高电平方便下一次下降沿,如果没有数据了正好引脚为高电平,也表示空闲状态,
(3)数据位
比如要发送一个字节0X0F,那就首先把0F转换为二进制,0000 1111然后低位先行,所以数据要从低位开始发送也就是1111 0000像这样依次放在发射引脚上。

所以最终引脚的波形就是这样子的。所以说要发送0x0f这个数据,就按照波特率要求定时翻转引脚电平,产生一个这样的引脚波形就可以了。
(4)校验位
单片机中用到的是奇偶校验位,它可以看到数据传输是否出错了。如果出错了可以选择丢弃,或者重传。
如果使用了奇校验,那么包括校验位在内的九位数,就会出现奇数个1,比如传输0000 1111目前一个四个1是偶数个,那么校验位就需要在补一个1,连同校验位一共5个1,保证1为奇数。如果数据是0000 0111,此时有三个1那么校验位就补一个0
发送方,在发送数据后会补充一个校验位保证1的个数为奇数,接收方在接收数据后,会验证数据位和校验位,如果一的个数还是奇数,就代表数据没问题,如果在传输过程中,有一位因为干扰,变味了1或0,那么奇偶特性就会发生变化。
接收方一接收发现不对,那么就会认为传输出错,可以选择丢弃,或者要求重传。偶校验同理
但是如果有两个数据同时出错,那么奇偶性不会变化,就不会差错,所以奇偶校验只能保证一定程度上的数据不会出错。
如果需要更高的检出率可以考虑一下CRC校验。
(5)总结
我们数据位有两种表示方法一种是像图一样,分为八位数据,九位数据。
另外就是把校验位和数据位分开,八位数据位,一位校验位。
6.串口通讯实际波形

(1)波形1

这个波形是发送一个字节数据0x55在TX引脚输出的波形,波特率9600,所以每一位时间就是1/9600大概是104us。
没发送数据空闲位置是高电平。数据开始发送先发送起始位,产生下降沿代表数据帧开始,数据0x55转为二进制0101 0101,数据低行就是依次发送1010 1010之后就是停止位把引脚置回去高电平。在STM32中这个高低电平的数据是通过USART自动完成的,不用我们操心。
当然也可以软件模拟这个波形就是定时器定时104uS的时间时间到了之后按照数据帧要求调用给端口写入电平的函数,产生一个一样的电平,这样也可以完成串口通信。
如果想要读取的话,那么就定时一个时间,每隔一段时间,就读取这个端口值,最终拼接成一个字节。当然接收时候还需要一个外部中断在起始位的下降沿触发,进入接收模式,并且对齐采样时钟,依次采样8次。

波特率变小的话那么波形时长就会变为原来的二倍也就是208uS。

还可以设置两位停止位那么就会在数据中心停下一下,但是没有空闲端。
