fa一.串口外设的简介
上个博客我们了解了串口协议,接下来我们来了解一下STM32的串口外设。
STM32F103C8T6的USART(通用同步/异步收发器)是一个强大的串行通信硬件外设,支持全双工异步串行通信,也具备同步模式等功能。下面这个表格汇总了它的核心特性和在STM32F103C8T6上的资源分布,方便你快速了解:
| 特性分类 | 具体说明 |
|---|---|
| 基本特性 | 通用同步/异步收发器,波特率发生器最高达4.5Mbits/s ,支持全双工异步通信,也支持同步单向通信和半双工单线通信。 |
| 数据帧 | 数据位长度可配置为8位或9位 ;停止位长度可配置为0.5, 1, 1.5, 2位 ;校验位可配置为无校验、奇校验、偶校验。 |
| STM32F103C8T6资源 | 3个USART(USART1、USART2、USART3)。 |
| 引脚分布 | USART1 : TX(PA9), RX(PA10);USART2 : TX(PA2), RX(PA3);USART3: TX(PB10), RX(PB11)。 |
| 时钟源 | USART1 挂载在 APB2总线 (PCLK2,最高72MHz);USART2/3 挂载在 APB1总线(PCLK1,最高36MHz)。 |
1.工作模式与数据帧
STM32的USART主要工作在异步模式(UART) ,这也是最常见的串口通信方式。它通过波特率 、数据位 、停止位 和可选的校验位来约定数据传输的格式。
一个完整的USART数据帧由以下部分组成:
-
起始位 :总是逻辑
0,标志一帧数据的开始。 -
数据位:实际要传输的数据,可以是8位或9位。如果使能了奇偶校验,通常设置为9位数据格式(8位数据+1位校验位)。
-
校验位:可选的错误检测位,可以是奇校验或偶校验
-
停止位 :总是逻辑
1,标志一帧数据的结束,长度可选。
数据传输时是从最低位(LSB)开始的
2. 配置使用要点
配置和使用USART时,有几个关键点需要特别注意:
-
GPIO模式配置
-
TX引脚(发送) 应配置为复用推挽输出(GPIO_Mode_AF_PP)。
-
RX引脚(接收) 应配置为浮空输入(GPIO_Mode_IN_FLOATING)或上拉输入。
-
-
波特率计算与时钟
-
波特率由专用的波特率寄存器(USART_BRR) 控制,该寄存器包含整数部分和小数部分
-
计算公式为:
Tx/Rx Baud = f_PCLKx / (16 * USARTDIV)。其中
USARTDIV是写入BRR寄存器的值。 -
务必注意:USART1挂载在APB2总线(PCLK2,最高72MHz),USART2/3挂载在APB1总线(PCLK1,最高36MHz)计算波特率时需要使用对应总线时钟。
-
-
关键状态标志位
-
TXE(发送数据寄存器空):当TDR(发送数据寄存器)为空,可以写入下一个数据时,该位置1。
-
TC(发送完成):当一帧数据(包括停止位)已完全发送出去时,该位置1。
-
RXNE(读取数据寄存器非空):当RDR(接收数据寄存器)中有收到新数据时,该位置1
-
3 编程模式与示例
根据需求,你可以选择不同的编程模式操作USART:
| 模式 | 特点 | 适用场景 |
|---|---|---|
| 轮询模式 | 主循环中不断检查TXE和RXNE等状态标志,简单但效率低,会阻塞CPU。 | 简单应用,非实时性任务。 |
| 中断模式 | 当TXE/RXNE等事件发生时触发中断,在中断服务程序(ISR)中处理数据,效率高,响应及时。 | 数据接收、提高程序运行效率。 |
| DMA模式 | 无需CPU介入,直接在USART和内存之间传输数据,效率最高。 | 高速数据流,如GPS模块、大量数据传输。 |
一个典型的使用库函数进行USART初始化的代码流程如下:
-
使能时钟:开启USART所在总线的时钟以及对应GPIO端口的时钟。
-
初始化GPIO:将TX和RX引脚配置为正确的复用模式。
-
配置USART参数 :使用
USART_InitTypeDef结构体,设置波特率、字长、停止位、校验位、硬件流控制和模式等。 -
(可选)配置中断:如果使用中断模式,需配置NVIC并使能相应的USART中断。
-
使能USART :调用
USART_Cmd()函数使能USART。
4. 硬件连接与调试
-
硬件连接 :STM32与外部设备(如USB转TTL模块、另一个MCU)连接时,基本原则是TX接RX,RX接TX,并且GND共地。
-
常见问题:
-
通信乱码 :最常见的原因是波特率不匹配,请检查双方设备波特率设置以及STM32的时钟配置是否正确。
-
数据丢失:在中断或DMA模式下,可能因处理不及时导致。确保中断优先级合理,并及时读取数据。
-
-
调试工具 :串口调试助手(如Putty、Tera Term)是必不可少的调试工具。
5. 重要总结
STM32F103C8T6的USART是一个功能全面且灵活的通信外设。掌握其数据帧格式 、波特率计算 (注意时钟源)以及三种编程模式 (轮询、中断、DMA)的适用场景,是可靠进行串口通信的关键。对于需要高效处理大量数据的场景,强烈建议使用DMA模式
二.硬件图
1.简介
一般我们还会遇到UART就是异步收发器,一般我们窜口很少使用同步功能。USART更多的是都来一个时钟输出,但是不支持时钟输入,所以不能用于两个USART之间的同步通信。
USART大致可分为两部分发送和接收,发送就是将数据寄存器的一个字节数据自动转换为协议规定的波形从TX引脚发送出去,接收数据就是从RX引脚接收波形。
当我门配置好了USART电路直接读写数据寄存器,就能自动接收和发送数据了。
波特率发生器起始就是一个预分频器,比如我们APB2总线给了一个72MHz的频率。然后波特率发生器进行一个分频,得到我们想要的一个时钟。最后在这个时钟下进行收发,就是我们指定的通信波特率了。
数据位长度就是这里,需要校验位就选9位,不需要校验位就选8位。
停止位长度就是在进行连续发送时停止位决定了帧的间隔长用的就是1位停止位。
2.串口参数
我们一般最常用的就是波特率9600或者115200
数据位8位停止位1位,无校验。
同步模式就是多了一个CLK时钟输出
硬件流设置是比如A设备有个TX向B设备的RX发送数据A设备一直再发,发的太快了B处理不过来,如果没有硬件流控制那么B就只能抛弃新数据,或者覆盖原数据了,如果有硬件流控制,那么在硬件电路上,会多出一根线如果B没准备好接收就置高电平,如果准备好接收就置低电平。A接收到了B反馈的指定信号,就会只在B准备好时候,才发数据。如果B没有准备好,那么数据就不会发送出去。
DMA是这个串口支持数据转运,如果有大量的数据进行收发,可以用DMA来转运数据,减轻CPU的负担。
irda是红外通信,一个是红外发光管,一个是红外接收管。这个irda并不是遥控器的红外通信,所以不能用来模拟遥控器。
LIN是局域网通信协议,可以研究一下。
我们STM32中USART1是APB2总线上设备,USART2,USART3是APB1总线上设备。
3.USART框图
3.输入和输出
左上角就是我们的发送和接收引脚。下面的IRDA_OUT和IRDA_IN是智能卡和IRDA通信的引脚。
发送和接收是通过这样子连接的。
右边的就是串口的数据寄存器了,发送和接收的字节就存在这里。上面有两个寄存器,一个是发送数据寄存器TDR,一个是接收数据寄存器RDR。这两个寄存器占用同一个地址。在程序上只表现为一个寄存器,就是数据寄存器DR但时机硬件中,分为了两个寄存器一个用于发送TDR,一个用于接收RDR。TDR是只写的,RDR是只读的,当进行写操作时,数据就写入到TDR,当进行读操作时数据就是从RDR读出来的。
下面时两个移位寄存器,一个用来发送,一个用来接收,发送是把一个字节数据一位一位移去正好对应串口协议波形的数据位。
这两个寄存器是如和工作的呢,比如你在TDR里写入了055这个数据,那么在寄存器里就是二进制存储,就是0101 0101,那么此时硬件检测到你写入数据了,那么此时他就会检查当前移位数据寄存器是不是有数据正在进行移位如果没有这个0101 0101就会立刻全部移动到发射移位寄存器,准备发送,当数据从TDR移动到移位寄存器时会置一个标志位叫TXE,发送寄存器空,我们检查这个标志位如果置1了就可以在TDR写入下一个数据了。
当TXE标志位置1时数据还没有发送出去,只要数据从TDR转移到发送移位寄存器了TXE就会置1.
然后发射移位寄存器就会在下面发射器控制的驱动下向右移位,一位一位的把数据输出到TX引脚,这里是向右移位的,所以正好和串口协议规定的,低位先行是一致的。当数据移位完成后,新的数据就会再次自动地从TDR寄存器转移到移位寄存器里面来。如果当前移位寄存器数据没有完成,按摩移位寄存器就会进行等待,一旦数据移位完成,立刻转移进来。
有了TDR和移位寄存器的双重缓存,可以保证连续发送数据的时候数据帧之间不会有空闲。提高了工作效率
接收端同理,在接收控制器驱动下一位一位读取RX电平,先放在最高位然后右移。移位八次之后就能接收一个字节了。同样,因为串口协议规定低位先行,所以接收移位寄存器是从高位往低位这个方向移动的之后当一个字节移位完成,这一个字节的数据就会整体的一下子转移到数据接收寄存器RDR里面来。在转移过程中也会置一个标志位,叫RXNE,接收数据寄存器非空当我们检测到RXNE置1之后就可以把数据读取走了。
同样这里也是两个寄存器缓存,当数据从移位寄存器转移到RDR时候,就可以移位接收下一个数据了。
这就是USART整个外设的工作流程。
4.硬件流
硬件数据流控制,前面我们介绍过,如果发送设备发送的过快,接收设备来不及接收就会出现覆盖和丢失的现象,有了流控,就可以避免这个问题了。
这里流控有两个引脚一个是nRTS是请求发送,是输出脚也就是告诉别人我当前能不能接收,nCTS是清除发送时输入脚也就是用于接收别人的nRTS信号,这里加个n意思是低电平有效。
这两个引脚如何使用的呢,首先需要找另一个支持流控的串口他的TX接到我的RX然后我的RTS要输出一个能不能接收的反馈信号。接到对方的CTS上面。
当我能接收的时候RTS就置低电平请求对方发送。对方的CTS接收到之后就可以一直发。当我处理不过来时比如输出寄存器数据没有读取,又有新的数据过来现在就代表我没有及时处理,那么RTS就会置高电平对方CTS收到后就会进行等待,暂停发送。直到接收数据寄存器被读取走RTS置低电平新的数据才会继续发送。反过来当我们TX给别人发送数据时候,我们CTS就要接到对方的CTS用于判断双方能不能接收。
TX和CTS是一对,RX和RTS是一对的。CTX和RTX也要交叉连接这就是流控的模式。
5.同步时钟
用于产生,同步的时钟信号,他是配合发送移位寄存器进行输出的,发送寄存器每移位一次,同步时钟电平就跳转一个周期。时钟告诉对方我们移位出去了,当然时钟支支持输出,不支持输入,所以两个USATR之间不能实现同步串口通信。那这个时钟信号有什么用呢,第一个就是兼容别的协议。比如串口+时钟就和SPI协议很向,所以有了串口和时钟,就能兼容SPI协议,另外这个时钟也就可以做自适应波特率。比如接收设备不确定发射设备给的什么波特率那就可以测量一下这个时钟的周期。然后再计算波特率。
6.唤醒单元
这部分的作用是实现串口挂载多设备。之前了解,串口是进行点对点的通讯,点对点支支持两个设备互相通讯。想发数据直接发就行,而多设备可以载一条总线上接多个从设备,每个设备分配一个地址,我想跟某个设备通信就先进行寻址,确定通信对象,在进行数据收发。
这里的唤醒单元就可以实现多设备的功能,在这里可以给串口分配一个地址,当你发送指定地址时,此设备唤醒,然后开始工作。如果这个设备没有收到地址,就会保持沉默,这样就可以实现多设备的串口通信了。
7.中断输出控制
中断申请位,就是状态寄存器这里各种标志位,有两个标志位比较重要一个是TXE发送寄存器空,一个是RXNE接收寄存器非空,这两个是判断发送状态和接收状态的非必要标志位。
这里就是配置中断控制是否能通向NVIC
8.波特率发生器
其实就是分频器,APB时钟进行分频,得到发送和接收移位的时钟,这里时钟输入是fPCLKx,x可以是1或2。
USRAT挂载在APB2所以就是PCLK2一般是72MHz。其他的USRTA挂在APB1所以是PCLK1,一般是36MHz。之后这个时钟进行一个分频,除一个USARTDIV的分频系数。USARTDIV里面就是右边这样,
是一个数值。并且分为了整数部分和小数部分。因为有些波特率,用72MHZ除一个整数的话肯除不尽,会有误差。所以这里分频器是支持小数点后四位的,分频器会更加精准。之后分频完成后还要再除以一个16,得到发送器时钟和接收器时钟,通向控制部分。
然后右边部分这里如果TE为1就是发射器使能了,发送部分的波特率就有效。
如果RE为1,就是接收器使能了,接收部分的波特率就会有效。
9.引脚定义
这里的USART2的TX是PA2口,RX是PA3口。
USART3的TX是PB10口,RX是PB11口。
USART1的TX是PA9口,RX是P10口。
这里必须按照引脚定义里面来,比如你要使用USART1,那么TX引脚必须是PA9,RX引脚必须是PA10。
这里有USART1的重映射,所以有机会换口一次。
三.简化结构图
1.结构图
波特率发生器,用于产生约定的通信速率,时钟来源是PCLK2/1。经过波特率发生器分频后,产生的时钟通向,发送控制器和接收控制器,发送控制器和接收控制器用来控制发射移位和接收移位。之后由发射移位寄存器和接收移位寄存器这两个寄存器相互配合,将数据一位一位移出去通过GPIO口的复用输出,输出到TX引脚产生串口协议规定的波形,这里画的右移的符号代表这个移位寄存器是向右移位的是低位先行。当发送数据寄存器的数据转移到移位寄存器时,会产生一个TXE标志位,我们判断标志位就可以知道是不是写入下一个数据了,然后接收部分RX波形通过接收引脚输入,在接收控制器作用下一位一位移位到接收移位寄存器,这里画了右移的符号表示也是右移的,因为是低位先行,所以要从左边开始移进来。移完一帧数据后,数据就会统一转运到接收数据寄存器。在转移的同时置一个RXNE标志位我们检查标志位,就可以知道是不是收到数据了。同时这个标志位也可以申请中断,这样就可以在收到数据时,进入中断函数,快速的读取和保存数据。
右边实际由四个寄存器,软件方面只有一个DR可供我们读写,写入DR时数据走上面的路进行发送,反之亦然,这就是USART进行串口数据收发过程,右下角有个开关控制,就是配置完成后用CMD开启一下USART外设。
2.数据帧

空闲高电平起始位0,根据写入的数据进行置1或置0.停止位1数据结束。
首先串口的空闲状态时高电平,也就就是没有数据传输的时候引脚必须要设置高电平,作为空闲状态。
然后需要传输的时候必须要发送一个起始位这个起始位必须时低电平,来打破空闲时候的高电平,产生一个下降沿,这个下降沿就告诉设备,这一帧数据要开始了。如果没有起始位,当我们发送8个1时候数据线就会一直是高电平,没有任何波动。
同理在一个数据发送完成后,必须要有一个停止位,用于数据帧间隔,固定为高电平,同时这个停止位,也是为了下一个起始位做准备的。如果没有停止位,当我最后一个数据是0的时候,下次在发送新的一帧就没办法产生下降沿了。
起始位固定为0产生下降沿,表示传输开始。停止位固定为1把引脚恢复为高电平方便下一次下降沿,如果没有数据了正好引脚为高电平,也表示空闲状态,
时钟就是我们说的同步输出的功能,每一位数据上升沿都有一个时钟,输出端可以进行采样,时钟最后一位可以根据LBCL控制位决定要不要输出。
单片机中用到的是奇偶校验位,它可以看到数据传输是否出错了。如果出错了可以选择丢弃,或者重传。
如果使用了奇校验,那么包括校验位在内的九位数,就会出现奇数个1,比如传输0000 1111目前一个四个1是偶数个,那么校验位就需要在补一个1,连同校验位一共5个1,保证1为奇数。如果数据是0000 0111,此时有三个1那么校验位就补一个0
发送方,在发送数据后会补充一个校验位保证1的个数为奇数,接收方在接收数据后,会验证数据位和校验位,如果一的个数还是奇数,就代表数据没问题,如果在传输过程中,有一位因为干扰,变味了1或0,那么奇偶特性就会发生变化。
接收方一接收发现不对,那么就会认为传输出错,可以选择丢弃,或者要求重传。偶校验同理
但是如果有两个数据同时出错,那么奇偶性不会变化,就不会差错,所以奇偶校验只能保证一定程度上的数据不会出错。
如果需要更高的检出率可以考虑一下CRC校验。
一般选择8位数据位,1位校验位,或者八位数据位无校验位。
3.不同停止位数据帧

可配置的停止长度为0.5,1,1.5,2四种。
0.5停止位,停止位时长是0.5个数据位,
1停止位,停止位时长是1倍数据位,
1.5停止位,停止位时长是1.5倍数据位,
2停止位,停止位时长是2倍数据位,
一般选择1位就行。
4.起始位侦测

当输入电路检测到一个数据帧的起始位后就会以波特率的频率连续采样一帧数据同时从起始位开始采样位置要对齐到位的正中间只要第一位对齐了,后面肯定都是对齐的。这里会以波特率的16倍频进行采样,也就是在一位的时间可以进行16次采样。
然后再起始位进行连续16次采样,没有噪声的话这16次采样肯定都是0,但是实际电路还是会存在一些噪声的,所以这里即使出现了下降沿,也会连续再采样几次,防止噪声,这个电路还会再下降沿出现的第3,5,7次进行一批采样,在第8,9,10次进行一批采样且这两次采样都要要求每三位至少有2位都是0。如果没有噪声那肯定都是0,满足情况,如果有轻微噪声,3位里面有1个1那么也是检测到了起始位。但是在状态寄存器里会置位1个NE噪声标志位,就是提醒你一下,数据收到了但是有噪声,看着办,如果3位里面有一个0,那么就不算检测到了起始位,可能前面的下降沿是噪声导致的,这时电路就忽略前面的数据,重新开始捕捉下降沿。这就是STM32的串口在接收过程中,对噪声的处理。
如果通过了起始位侦测,那么接收状态就由空闲变为接收起始位,同时第8,9,10次采样的位置,正好是起始位正中间。之后接收数据位时,都在第8,9,10次采样,这样就能保证采样位置在位的正中间了。
这就是起始位侦测,和采样数据对齐的策略了。
4.数据采样的流程

这里的1-16是一个数据位的时间长度,在一个数据位有16个采样时钟,由于起始位侦测已经对齐了采样时钟所以这里就在第8,9,10次采样数据位,为了保证数据的可靠性,这里是连续采样3次没有噪声的情况下这三次肯定全为0或者全为1。全为1就认为收到了1,全为0就认为收到了0。如果有噪声那么就按照2;1规则来,2次为1,就认为收到了1。
5.波特率发生器

波特率发生器就是分频器。DIV分为整数部分和小数部分,那么波特率和分频系数的关系,可以由上面的公式进行计算。
波特率=fPCLK1(2)/(16*DIV)。为什么这里多了一个16

因为内部多了一个16倍波特率的采样时钟。
比如说我们要配置USART1为9600的波特率如何配置BRR寄存器呢,我们带入公式因为USART1时钟为72MHz。是在APB2总线上的。
9600=72MHz/16*DIV解的DIV=72MHz/9600/16 = 468.75。这是一个带小数的分频系数,最后写道寄存器,还要转换为二进制。最终得到1 1101 0100.11,所以最终写道这个寄存器为整数部分是:1 1101 0100,前面多出来的补0,小数部分11,后面多出来的部分补0,
6.USB转串口原理图


最左边是USB端口,一共有四根线,分别为VCC,GND,D+,D-。

经过我们CH340芯片转换之后,输出的TXD和RXD是串口通信协议。

第五脚实际上是VCC3.3V是芯片的输入脚。一般这个模块会有一个跳线帽,这个跳线帽一般接在4,5引脚或者5,6引脚上。

这里也可以看到说明,跳线帽是用来选择通信信号电平,也是用来给芯片供电。
如果把跳线帽接在4,5脚上,那么供电就只有一个5V脚了所以这个供电有点折磨人。要么选择5V电平,供电就只有3.3V,要么选择3.3V电平,供电就只有5V,不过考虑到电平的5V和3.3V可以互相兼容,所以既需要供电,又需要通信,那就保证供电时正确的就可以了。
到这里我们串口外设就结束了,下个博客我们来进行代码部分。