一文看懂USART工作流程

其他总线的总结大佬面经里有可以看看

https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM

USART简介

USART(UniversAl Synchronous/Asynchronous Receiver/TrAnsmitter)通用同步/异步收发器。

注:这个S就是Synchronous同步,如果少了这个S就是异步,一般来说我们串口很少使用同步功能。所以USART和UART使用起来也没什么区别。其实这个STM32的USART同步模式,只是多了个时钟输出而已,它只支持时钟输出,不支持时钟输入。所以这个同步模式更多的是为了兼容别的协议或者特殊用途而设计的,并不支持两个USART之间进行同步通信。所以我们学习串口主要还是异步通信。

USART是STM32内部集成的硬件外设,可根据数据寄存器的一个字节数据自动生成数据帧时序,从TX引脚发送出去,也可自动接收RX引脚的数据帧时序,拼接为一个字节数据,存放在数据寄存器里

这个USART外设就是串口通信的硬件支持电路。USART大体可以分为发送和接收两部分。发送部分就是将数据寄存器的一个字节数据自动转化为协议规定的波形,从TX引脚发送出去。接收部分就是自动接收RX引脚的波形,按照协议规定,解码为一个字节,数据存放在数据寄存器里。当我们配置好了USART电路,直接读写数据寄存器,就能自动发送和接收数据了,使用还是非常方便的。

自带波特率发生器,最高达4.5MBits/s

波特率发生器它其实就是一个分频器。比如我们APB2总线给个72MHz的频率,然后波特率发生器进行一个分频,得到我们想要的波特率时钟,最后在这个时钟下进行收发,就是我们指定的通信波特率。波特率我们最常用的是9600或者115200。

可配置数据位长度(8/9)、停止位长度(0.5/1/1.5/2)

可选校验位(无校验/奇校验/偶校验)

我们最常用的是无校验

以上这些所有的参数都是可以通过配置寄存器来完成的,使用库函数配置的话就更简单了,直接给结构体赋值就行。

支持同步模式、硬件流控制、DMA、智能卡、IrDA、LIN

这个同步模式就是多了个时钟CLK的输出。

硬件流控制,比如A设备有个TX向B设备的RX发送数据。A设备一直在发,发的太快了,B处理不过来,如果没有硬件流控制,B就只能抛弃新数据或者覆盖原数据了。如果有硬件流控制,在硬件电路上会多出一根线,如果B没准备好接收就置高电平,如果准备好了,就置低电平。A接收到了B反馈的准备信号,就只会在B设备好的时候才发数据。如果B没准备好,数据就不会发送数据。这就是硬件流控制。它可以防止因为B处理慢而导致数据丢失的问题。STM32也有硬件流控制,不过我们一般不用。

这个串口支持DMA进行数据转运,如果有大量的数据进行收发,可以使用DMA转运数据,减轻CPU的负担。

最后智能卡(比如饭卡、公交卡)、IrDA(用于红外通信)、LIN这些是其它的一些协议,因为这些协议和串口是非常像,所以STM32就对USART加了一些小改动,就能兼容这么多协议了,不过我们一般不用。IrDA用于红外通信,这个红外通信就是一个红外发光管,另一边是红外接收管,然后靠闪烁红外光通信。LIN是局域网的通信协议,这个感兴趣的话,自己研究一下。

最后看一下我们这个芯片的USART资源,

STM32F103C8T6 USART资源: USART1、 USART2、 USART3

其中这里USART1是APB2总线上的设备,剩下的都是APB1总线的设备,这个在开启时钟的时候注意一下,在使用的时候,挂载哪个总线影响并不是很大。

USART的框图

接下来我们来看一下USART的框图,

先看左上脚这里的引脚部分,

这里有TX和RX这两个就是发送和接收引脚,下面的那三个引脚是智能卡和IrDA通信的引脚,我们不用这些协议,所以这些引脚就不用管了。右边这个框框IrDASIR编码模块也不用管它。

TX发送脚就是从这里接出去的,

RX接收脚就是通向这里,

然后看一下右边这一块,这部分就是串口的数据寄存器,发送或接收的字节数据就存在这里

上面只有两个数据寄存器,一个是发送数据寄存器TDR(Transmit DR),另一个是接收数据寄存器RDR(Receive DR),这两个寄存器占用同一个地址,就跟51单片机串口的SBUF寄存器一样。在程序上只表现为一个寄存器,就是数据寄存器DR。但实际硬件中是分成了两个寄存器,一个用于发送,TDR,一个用于接收RDR。TDR是只写的,RDR是只读的,当进行写操作时,数据就写到了TDR,当进行读操作时,数据就是从RDR读出来的。

然后往下看下面是两个移位寄存器,一个用于发送,一个用于接收。发送移位寄存器的作用就是把一个字节的数据一位一位地移出去,正好对应串口协议的波形的数据位。

这两个寄存器是怎么工作的?

举个例子,

比如在某时刻给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电平,先放在最高位,然后往右移,移位八次之后就能接受一个字节。

同样,因为串口协议规定是低位先行,所以接收移位寄存器是从高位往低位这个方向移动的,之后,当一个字节移位完成之后,这一个字节的数据就会整体的,一下子转移到接收数据寄存器RDR。在转移的过程中也会置一个标志位,叫RXNE(RX Not Empty),接收数据寄存器非空。当我们检测到RXNE置1之后,就可以把数据读走了。

同样这里也是两个寄存器进行缓存,当数据从移位寄存器转移到RDR时,就可以直接一位接收下一帧数据了。

这就是USART外设整个的工作流程。

#面经##数据人的面试交流地##牛客创作赏金赛##嵌入式##硬件人的春招flag#
全部评论

相关推荐

点赞 评论 收藏
分享
05-29 22:11
门头沟学院 Java
Elastic90:抛开学历造假不谈,这公司的招聘需求也挺怪的,Java开发还要求你有图文识别、移动端开发和c++的经验,有点逆天了。
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
1
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务