USART介绍:
USART是通用同步/异步收发器英文全称:(Universal Synchronous / Asynchronous Receiver Transmitter)与UART不同的是USART的S代表的是同步,但是一般不用这个功能,它只支持时钟输出,不支持时钟输入。所以同步模式只是兼容别的协议或者特殊模式使用,两个USART设备不能同步通信。
USART是STM32内部集成的外设,它能根据数据寄存器的数据的一个字节自动生成一个数据帧时序,并从TX引脚发送出去,也可以自动接收RX发送的数据帧,并解码为一个字节数据并存放在数据寄存器里。
自带波特率发生器,最高达4.5Mbits/s。
可配置数据位长度:8或9,停止位长度(0.5/1/1.5/2)
可选校验位:无校验/奇校验/偶校验
一般选择常用参数:波特率:9600,115200,数据位:8位,停止位:1位,无校验
支持同步模式,硬件流控制,DMA,智能卡,IrDA,LIN。
硬件流控制,如果A向B发送数据,在AB中间有根线,如果B没准备好接收,B就置高电平,如果准备好了,B就置低电平。当A接收到了B反馈的准备信号时候,才会发送数据。主要是防止B处理慢而导致的数据丢失问题,一般不用。
DMA表示支持DMA转运,如果有大量的数据进行收发,可以使用DMA转运数据,减轻CPU负担。
STM32F103C8T6资源:USART1(APB2总线)、USART2、USART3(APB1总线)
USART工作原理
左上角引脚部分 ,TX和RX就是数据的发送和接收引脚,TX就是从发送移位寄存器接过来的,RX接收脚通向接收移位寄存器。发送数据寄存器(TDR)和接收数据寄存器(RDR)这两个寄存器共用一个地址,在程序上只表现为一个寄存器(DR),但是实际情况是两个寄存器,TDR是只写的,RDR是只读的。当进行写操作时,数据就写到了TDR,当进行读操作时,数据从RDR进行读取。发送移位寄存器的作用是把数据一位一位地移出去,对应串口协议的波形数据位。
发送是如何工作的呢?在某个时刻,给TDR写入了0x55这个数据,此时硬件监测到写入数据,就会检查当前移位寄存器是否有数据正在移位,如果没有,这个数据就会立刻写入发送移位寄存器,并且将TXE(TX Empty发送寄存器空)标志位置1,,我们检查这个标志位,如果置1我们就可以继续在TDR写入下一个数据了。(注意:当TXE标志位置1时,数据还没有发送。)这时候发送移位寄存器就会在下面的发送器控制驱动下向右移位,这也就是低位先行,一位一位地把数据输出到TX引脚。移位完成后,新的数据会自动从TDR转移到发送移位寄存器中,如果当前移位没有完成,TDR数据寄存器就会进行等待,一旦移位完成,就会立刻转移过来。有了TDR和移位寄存器的双重缓存可以保证连续发送数据的时候,数据帧之间不会有空闲,提高工作效率。
接收的工作原理与发送类似,数据从RX引脚通向接收移位寄存器,在接收器控制的驱动下,一位一位地读取RX的电平,先放在最高位,然后向右移,移位8次后就能接收一个字节了,当一个字节移位完成后,这一个字节的数据就会整体地转移到接收数据寄存器(RDR)中,同时也会置一个标志位,叫(RXNE)RX Not Empty接收数据寄存器非空。当我们检查到RXNE置1之后就可以把数据读走了,同样,当数据从接收移位寄存器转移到RDR时,就可以直接接收下一帧数据了。
左下角还有硬件输出流控制引脚,nRTS是请求发送,是输出脚,也就是告诉别人我当前能不能接收数据。nCTS是清除发送,是输入脚,也就是用于接收另一个设备的nRTS的信号。n代表低电平有效。工作流程就是设备A给设备B发送数据,那么设备A的TX就接到B的RX上,B的RTS接到A的CTS上,当B能接受数据时给RTS置低电平,请求对方发送,对方的CTS接收到之后,就会一直发送数据,如果B的接收数据寄存器的数据一直没有处理,那么RTS就会置高电平。对方CTS接收到之后,就会停止发送。
SCLK控制是用于产生同步的时钟信号,发送寄存器每移位一次,同步时钟电平就跳变一个周期,时钟告诉对方我移出去一位了,这个时钟信号只支持输出,不支持输入,所以两个USART设备之间不能实现同步的串口通信。有了时钟输出就可以兼容SPI,也可以使用时钟做自适应波特率,例如接收设备不确定发送设备给的什么波特率,那么就可以测量时钟周期,再计算就得到了波特率,需要自己写程序实现。时钟功能一般不使用。
唤醒单元是实现串口可以挂载多设备,多设备就是在一条总线上接了很多从设备,每个设备分配一个地址,需要跟某个设备通信,就先进行寻址,确定通信对象,再进行数据收发。再这里可以给设备分配一个地址,当发送指定地址时,此设备唤醒开始工作,当发送别的设备地址时,别的设备就开始唤醒工作。没收到地址就会保持沉默。这样就实现了多设备的串口通信了。
中断申请位,就是状态寄存器里的标志位,两个寄存器TXE和RXNE比较重要,一个是发送寄存器空,一个是接收寄存器非空。中断输出控制就是配置中断是否通向NVIC。
最下面是波特率发生器部分,其实就是分频器,如图中fPCLKx(x= 1, 2),表示x等于1或者2,USART1挂载在APB2,所以是PCLK2的时钟,一般为72M,其他的USART挂载在APB1中,所以是PCLK1的时钟,一般为36M,/USARTDIV表示除以一个分频系数,有些波特率用72M除以整数的话除不尽,会有误差,因此这个分频系数分为整数部分和小数部分,小数部分支持小数点后四位,之后分频完后还要再除以16,之后通向发送器时钟和接收器时钟,通向控制部分。如果TE为1发送器波特率控制有效,RE为1,接收器波特率控制有效。
STM32的USART引脚
根据引脚图:
可以看出USART2的引脚为PA2和PA3,USART3的引脚为PB10和PB11。USART1的引脚为PA9和PA10,复用引脚为PB6和PB7。
USART基本结构
在软件层面,只有1个DR寄存器供我们读写,读取DR寄存器的时候,数据从RX到接收移位寄存器,发送数据的时候,数据从发送移位寄存器到TX发送出去。
数据帧:
如图所示,时钟就是同步时钟输出功能,它会在每一位的中间都会产生一个时钟上升沿,时钟的频率和数据的速率相等,接收端可以在时钟上升沿进行采样。下面是空闲帧(从头到尾都是1)和断开帧(从头到尾都是0),这两个数据帧是局域网协议使用的。
数据帧设置时,一般就两种,一种是9位字长有校验,一种是8位字长无校验。
停止位:
停止位有四种参数,0.5,1,1.5,2这四种参数,对应就是数据位时长的倍数,一般配置为1倍。
起始位侦测与噪声处理:
如图这是USART的起始位侦测,当输入电路侦测到一个数据帧的起始位之后,就会以波特率的频率,连续采样一帧的数据,并且在起始位,采样位置就要对齐到位的正中间,只要第一位对齐,那么后面就都是对齐的。为了实现这些功能,输入的电路对采样时钟进行细分,它会以波特率的16倍进行采样,也就是在一位的时间里可以进行16次采样。
当进行采样时,在某个位置突然出现0,就说明在这两次之间出现下降沿,如果没有噪声,那么这之后就是起始位了,在起始位,会进行连续16次采样,如果没有噪声,这16次采样都是0,但是实际电路会产生噪声,所以即使出现下降沿,后续还需要再采样几次,避免是噪声产生的下降沿。根据手册,实际采样会在出现下降沿的第3,5,7进行一批采样,在8,9,10进行一批采样,要求这两批采样保证每3位里面至少有2个0,如果有轻微噪声,有两个0,一个1时候,状态寄存器会置一个NE(Noise Error)标志位,噪声标志位,表示有噪声,当3位里面只有1个0那么就不算侦测到了起始位,可能前面的下降沿是噪声导致的。
当通过起始位检测时候,那么接收状态就由空闲转变为接收起始位,同时第8,9,10次采样位置正好是起始位的中间位置,之后接收数据位时,都在8,9,10次进行采样。并且进行数据接收时,也是在8,9,10中间位置进行采样,按照2:1的比例来,如果收到两个1,1个0,就认为是1,同理认为是0,这种情况下,NE标志位也会置1。
波特率计算
发送器和接收器的波特率由波特率寄存器BRR里的DIV确定
计算公式:波特率 =
例如要配置9600的波特率,DIV = 72M / 9600 / 16 = 468.75,转化成二进制就是111010100.11,整数部分高位不够补0,小数部分低位不够补0,就是000111010100.1100,使用库函数直接填波特率参数,库函数会自动计算。