STM32学习笔记14:USART基本介绍

芯片型号:STM32F103RC

软件开发包:标准外设库

一、串口通讯协议简介

1.1 硬件电路
  • 简单双向串口通信有两根通信线(发送端 TX 和接收端 RX)
  • TX 与 RX 要交叉连接
  • 当只需单向的数据传输时,可以只接一根通信线
  • 当电平标准不一致时,需要加电平转换芯片

硬件电路

1.2 电平标准

电平标准是数据 1 和数据 0 的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

  1. TTL 电平:+3.3V 或 +5V 表示 1,0V 表示 0
  2. RS232 电平:-3~-15V 表示 1,+3~+15V 表示 0
  3. RS485 电平:两线压差 +2~+6V 表示 1,-2~-6V 表示 0(差分信号)
1.3 串口参数及时序
  • 波特率:串口通信的速率
  • 起始位:标志一个数据帧的开始,固定为低电平
  • 数据位:数据帧的有效载荷,1 为高电平,0 为低电平,低位先行
  • 校验位:用于数据验证,根据数据位计算得来
  • 停止位:用于数据帧间隔,固定为高电平

串口中,每一个字节都能装载在一个数据帧里,每个数据帧都由起始位、数据位和停止位组成,如左图,数据位有 8 个,代表一个字节的 8 位。如右图,还可以在数据位的最后加一个校验位,这样数据位总共就是 9 位,其中有效载荷是前 8 位。

  ​0x55,9600,8位数据,1位停止,无校验          0x55,9600,8位数据,1位停止,偶校验

串口时序2位停止无校验

  0x55,9600,8位数据,2位停止,无校验

二、STM32 的 USART 简介

  • USART(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步收发器
  • USART 是 STM32 内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里
  • 自带波特率发生器,最高达 4.5Mbits/s
  • 可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)
  • 可选校验位(无校验/奇校验/偶校验)
  • 支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN

三、USART 框图

USART框图

(1)引脚

在左上角引脚部分,有 TX 发送引脚和 RX 接收引脚,而 SW_RX、IRDA_OUT/IN 是智能卡和 IrDA 通信的引脚。

(2)数据寄存器

编码器模块的右边是串口的数据寄存器,上面有两个数据寄存器,分别是发送数据寄存器 TDR 和接收数据寄存器 RDR, 这两个寄存器共用同一个地址。在程序上,只表现为一个寄存器,即使数据寄存器 DR;但实际硬件中,分成了两个寄存器,一个用于发送 TDR,一个用于接收 RDR,TDR 是只写的,RDR 是只读的。当进行写操作时,数据就写入 TDR,当进行读操作时,数据就是从 RDR 读出来的。

(3)移位寄存器

往下看,是两个移位寄存器,分别用于发送和接收。

发送移位寄存器的作用是,把一个字节的数据一位一位地移出去,正好对应串口协议的波形的数据位。发送数据寄存器和发送移位寄存器是搭配工作的,比如说在某个时刻给 TDR 写入 0x55 这个数据,在寄存器里就是二进制存储 0101 0101,此时硬件检测到写入数据了,就会检查当前移位寄存器是不是有数据正在移位,如果没有,0101 0101 就会立刻全部移动到发送移位寄存器,准备发送。

当数据从 TDR 移动到移位寄存器时,会置一个标志位,叫 TXE(TX Empty)发送寄存器空。检查这个标志位,如果置 1 了,就可以在 TDR 写一个数据了。注意:当 TXE 标志位置 1 时,数据其实还没有发送出去,只要数据从 TDR 转移到发送移位寄存器了,TXE 就会置 1,就可以写入新的数据了,然后发送移位寄存器就会在下面的发送器控制的驱动下,向右移位,一位一位地把数据输出到 TX 引脚。 这里向右移位正好和串口协议规定的低位先行是一致的。

当数据移位完成后,新的数据就会再次自动地从 TDR 转移到发送移位寄存器里,如果当前移位寄存器还没有完成,TDR 数据就会进行等待,一旦移位完成,就会立刻转移过来。有了 TDR 和移位寄存器的双重缓存,可以保证连续发送数据的时候,数据帧之间不会有空闲,提高了工作效率。简单来说,就是数据一旦从 TDR 转移到移位寄存器,无论移位是否完成,下一个数据都会被放入 TDR 中进行等待,一旦移位完成,新的数据就会立刻跟上。

对于接收端,数据从 RX 引脚通向接收移位寄存器,在接收器控制的驱动下,一位一位地读取 RX 电平,先放在最高位,然后向右移,移位 8 次之后,就接收了一个字节。同样,因为串口协议规定是低位先行,所以接收移位寄存器是从高位往低位这个方向移动的,之后,当一个字节移位完成后,这一个字节的数据就会整个转移到接收数据寄存器 RDR 中 。在转移的过程中,也会置一个标志位,叫 RXNE(RX Not Empty)接收数据寄存器非空。当检测到 RXNE 置 1 后,就可以读取数据了。同样,这里也是两个寄存器进行缓存,当数据从移位寄存器转移到 RDR 时,就可以直接移位接收下一帧数据了。

(4)控制和增强部分

除此之外,还有控制和增强部分。其中,发送器控制用来控制发送移位寄存器工作,接收器控制用来控制接收移位寄存器工作,然后左边有一个硬件数据流控,也就是硬件流控制,简称流控。流控的作用是防止如果发送设备发送数据太快,接收设备来不及处理,出现数据丢失或覆盖的情况。这里流控有两个引脚,一个是 nRTS(Request To Send),发送请求,若是低电平,表明USART准备好接收数据;一个是 nCTS(Clear To Send),清除发送,若是高电平,在当前数据传输结束时阻断下一次的数据发送。

对于这两个引脚的使用,首先,要找另一个支持流控的串口,它的 TX 要接到我的 RX,然后我的 RTS 要输出一个能不能接收的反馈信号,接到对方的 CTS。当我能接收的时候,RTS 就置低电平,请求发送,对方的 CTS 接收到之后,就可以一直发;当我处理不过来时,比如接收数据寄存器一直没读,又有新的数据过来,不能及时处理,那 RTS 就会置高电平,对方的 CTS 接收到之后,就会暂停发送,直到接收数据寄存器被读取,RTS 置低电平,新的数据才会继续发送。反过来,当我的 TX 给对方发送数据时,我的 CTS 就要接到对方的 RTS,用于判断对方能不能接收。TX 和 CTS 是一对的,RX 和 RTS 是一对的,CTS 和 RTS 也要交叉连接。

(5)时钟

再右边是 SCLK 控制和 SCLK 引脚,产生和输出用于同步传输的时钟,它是配合发送移位寄存器输出的,发送移位寄存器每移位一次,同步时钟电平就跳变一个周期。这个时钟只支持输出,不支持输入,所以两个 USART 之间不能实现同步的串口通信。该时钟信号的用途有两个:兼容别的协议和做自适应波特率。

(6)唤醒单元、中断输出控制和波特率发生器

下面还有唤醒单元,用于实现串口挂载多设备。在 USART 地址可以给串口分配一个地址,当发送指定地址时,此设备唤醒开始工作;当发送别的设备地址时,别的设备就唤醒工作。

再下面是中断输出控制,中断申请位就是状态寄存器的各种标志位,其中有两个比较重要,一个是 TXE 发送寄存器空,另一个是 RXNE 接收寄存器非空,这两个是判断发送状态和接收状态的必要标志位。USART 中断控制就是配置中断是不是能通向 NVIC。

最下面是波特率发生器部分,波特率发生器其实就是分频器,APB 时钟进行分频,得到发送和接收移位的时钟。

四、数据帧

字长

这个图是在程序中配置 8 位字长和 9 位字长的波形对比。

第一条时序是 TX 发送或者 RX 接收的数据帧格式,空闲高电平,起始位 0,然后根据写入的数据置 1 或 0,比如 9 位字长,依次发送位 0 到位 8,加起来就是 9 位,最后停止位 1,数据帧结束。在这里,位 8 是一个可能的奇偶校验位,通过配置寄存器就可以配置成奇校验、偶校验或无校验。可以选择配置成 8 位有效载荷 + 1 位校验位,也可以选择 9 位全都是有效载荷。

第二条时序是时钟,也就是同步时钟输出的功能。可以看到在每一位数据位的中间都有一个时钟上升沿,时钟的频率和数据速率也是一样的,接收端可以在时钟上升沿进行采样,这样就可以精准定位每一位数据。时钟的最后一位可以通过 LBCL 位控制是否输出,时钟的极性、相位也可以通过配置寄存配置。

后面两个时序,一个是空闲帧,一直为 1;另一个是断开帧,一直为 0。这两个数据帧是局域网协议用的。

停止位

这个图是不同停止位的波形变化。STM32 的串口可以配置停止位长度为 0.5、1、1.5、2,这四种参数的区别就是停止位的时长不一样。

五、起始位侦测

起始位侦测

这个图展示的是 USART 的起始位侦测。当输入电路侦测到一个数据帧的起始位后,就会以波特率的频率,连续采样一帧数据。同时从起始位开始,采样位置就要对齐到位的正中间,只要第一位对齐了,后面就肯定都是对齐的。

为了实现这个功能,首先输入的这部分电路对采样时钟进行了细分,它会以波特率的 16 倍频率进行采样,也就是在一位的时间里,可以进行 16 次采样。最开始空闲状态高电平,采样就一直是 1,在某个位置突然采到一个 0,那么就说明在这两次采样之间出现了下降沿,如果没有噪声,那之后就应该是起始位了。在起始位会连续采样 16 次,没有噪声的话,这 16 次采样就都是 0,但实际电路中会存在一些噪声,所以这里即使出现下降沿了,后续也要再采样几次,以防万一。

根据手册描述,这个接收电路还会在下降沿之后的第 3 次、5 次、7 次进行一批采样,在第 8 次、9 次、10 次再进行一批采样,且这两批采样都要求每 3 位里面至少应有 2 个 0。如果没有噪声,就全是 0,满足情况;如果有一些轻微的噪声,导致这里 3 位里面,只有两个 0,另一个是 1,那也算是检测到起始位了,但是在状态寄存器里会置一个 NE(Noise Error)噪声标志位,就是提醒数据收到了,但是有噪声;如果这里 3 位里面只有 1 个 0,那就不算检测到起始位,电路会忽略前面的数据,重新开始捕获下降沿。

如果通过了起始位侦测,接收状态就由空闲变为接收起始位,同时第 8、9、10次采样的位置就正好是起始位的正中间,之后接收数据位时就都在第8、9、10次进行采样,这样就能保证采样位置在位的正中间了。

六、数据采样

数据采样

图示为数据采样的流程,从 1 到 16 是一个数据位的时间长度,一个数据位由 16 个采样时钟,由于起始位侦测已经对齐了采样时钟,所以这里就直接在第 8、9、10 次采样数据位。为了保证数据的可靠性,这里是连续采样 3 次,没有噪声的理想情况下,这 3 次肯定全为 1 或全为 0。全为 1,就认为收到了 1;全为 0,就认为收到了 0。如果有噪声,导致 3 次采样不全为 1 或 全为 0,那它就按照 2:1 的规则,2 次为 1,就认为收到了 1;2 次为 0,就认为收到了 0。在这种情况下,噪声标志位 NE 也会置 1。

七、波特率发生器

  • 发送器和接收器的波特率由波特率寄存器 BRR 里的 DIV 位确定
  • 计算公式:波特率 = fPCLK2/1 / (16 * DIV)

波特比率寄存器

波特率发生器就是分频器,发送器和接收器的波特率由波特率寄存器 BRR 里的 DIV 位确定,DIV 分为整数部分和小数部分,可以实现更细腻的分频。

波特率 = fPCLK2/1 / (16 * DIV),为什么这里多了个 16?因为它内部还有一个 16 倍波特率的采样时钟,所以这里输入时钟 / DIV 要等于 16 倍的波特率,最终计算波特率,自然要多除以一个 16 了。

参考视频源于B站up主: 野火科技、江协科技
参考文档:《STM32库开发实战指南——基于野火MINI开发板》

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值