STM32 的USART 简介
通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个串行通信设备,可以灵活地与外部设备进行全双工数据交换。有别于USART 还有一个UART(Universal Asynchronous Receiver and Transmitter),它是在USART 基础上裁剪掉了同步通信功能,只有异步通信。简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART。
串行通信一般是以帧格式传输数据,即是一帧一帧的传输,每帧包含有起始信号、数据信息、停止信息,可能还有校验信息。USART 就是对这些传输参数有具体规定,当然也不是只有唯一一个参数值,很多参数值都可以自定义设置,只是增强它的兼容性。USART 满足外部设备对工业标准NRZ 异步串行数据格式的要求,并且使用了小数波特率发生器,可以提供多种波特率,使得它的应用更加广泛。
USART 支持同步单向通信和半双工单线通信;还支持局域互连网络LIN、智能卡(SmartCard)协议与lrDA(红外线数据协会) SIR ENDEC 规范。
USART 支持使用DMA,可实现高速数据通信,有关DMA 具体应用将在DMA 章节作具体讲解。
USART 在STM32 应用最多莫过于“打印”程序信息,一般在硬件设计时都会预留一个USART 通信接口连接电脑,用于在调试程序是可以把一些调试信息“打印”在电脑端的串口调试助手工具上,从而了解程序运行是否正确、如果出错哪具体哪里出错等等。
USART 功能框图
USART 的功能框图包含了USART 最核心内容,掌握了功能框图,对USART 就有一个整体的把握,在编程时就思路就非常清晰。USART 功能框图见图1。
图1 USART 功能框图
功能引脚
TX:发送数据输出引脚。
RX:接收数据输入引脚。
SW_RX:数据接收引脚,只用于单线和智能卡模式,属于内部引脚,没有具体外部引脚。
nRTS:请求以发送(Request To Send),n 表示低电平有效。如果使能RTS 流控制,当USART 接收器准备好接收新数据时就会将nRTS 变成低电平;当接收寄存器已满时,nRTS 将被设置为高电平。该引脚只适用于硬件流控制。
nCTS:清除以发送(Clear To Send),n 表示低电平有效。如果使能CTS 流控制,发送器在发送下一帧数据之前会检测nCTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送。该引脚只适用于硬件流控制。
SCLK:发送器时钟输出引脚。这个引脚仅适用于同步模式。USART 引脚在STM32F103ZET6 芯片具体分布见表1。
表1 STM32F103VET6 芯片的USART 引脚
系统控制器有三个USART 和两个UART,其中USART1 和时钟来源于APB2 总线时钟,其最大频率为72MHz,其他四个的时钟来源于APB1 总线时钟,其最大频率为36MHz。UART 只是异步传输功能,所以没有SCLK、nCTS 和nRTS 功能引脚。
数据寄存器
USART 数据寄存器(USART_DR)只有低9 位有效,并且第9 位数据是否有效要取决于USART 控制寄存器1(USART_CR1)的M位设置,当M位为0 时表示8 位数据字长,当M位为1 表示9 位数据字长,我们一般使用8 位数据字长。
USART_DR 包含了已发送的数据或者接收到的数据。USART_DR 实际是包含了两个寄存器,一个专门用于发送的可写TDR,一个专门用于接收的可读RDR。当进行发送操作时,往USART_DR 写入数据会自动存储在TDR 内;当进行读取操作时,向USART_DR读取数据会自动提取RDR 数据。
TDR 和RDR 都是介于系统总线和移位寄存器之间。串行通信是一个位一个位传输的,发送时把TDR 内容转移到发送移位寄存器,然后把移位寄存器数据每一位发送出去,接收时把接收到的每一位顺序保存在接收移位寄存器内然后才转移到RDR。USART 支持DMA 传输,可以实现高速数据传输,具体DMA 使用将在DMA 章节讲解。
控制器
USART 有专门控制发送的发送器、控制接收的接收器,还有唤醒单元、中断控制等等。使用USART 之前需要向USART_CR1 寄存器的UE 位置1 使能USART,UE 位用来开启供给给串口的时钟。发送或者接收数据字长可选8 位或9 位,由USART_CR1 的M位控制。
发送器
当USART_CR1 寄存器的发送使能位TE 置1 时,启动数据发送,发送移位寄存器的数据会在TX 引脚输出,低位在前,高位在后。如果是同步模式SCLK也输出时钟信号。
一个字符帧发送需要三个部分:起始位+数据帧+停止位。起始位是一个位周期的低电平,位周期就是每一位占用的时间;数据帧就是我们要发送的8 位或9 位数据,数据是从最低位开始传输的;停止位是一定时间周期的高电平。
停止位时间长短是可以通过USART 控制寄存器2(USART_CR2)的STOP[1:0]位控制,可选0.5 个、1 个、1.5 个和2 个停止位。默认使用1 个停止位。2 个停止位适用于正常USART 模式、单线模式和调制解调器模式。0.5 个和1.5 个停止位用于智能卡模式。
当选择8 位字长,使用1 个停止位时,具体发送字符时序图见图2。
图2 字符发送时序图
当发送使能位TE 置1 之后,发送器开始会先发送一个空闲帧(一个数据帧长度的高电平),接下来就可以往USART_DR 寄存器写入要发送的数据。在写入最后一个数据后,需要等待USART 状态寄存器(USART_SR) 的TC 位为1, 表示数据传输完成, 如果USART_CR1 寄存器的TCIE 位置1,将产生中断。
在发送数据时,编程的时候有几个比较重要的标志位我们来总结下。
接收器
如果将USART_CR1 寄存器的RE 位置1,使能USART 接收,使得接收器在RX 线开始搜索起始位。在确定到起始位后就根据RX 线电平状态把数据存放在接收移位寄存器内。接收完成后就把接收移位寄存器数据移到RDR 内,并把USART_SR 寄存器的RXNE 位置1,同时如果USART_CR2 寄存器的RXNEIE 置1 的话可以产生中断。
在接收数据时,编程的时候有几个比较重要的标志位我们来总结下。
小数波特率生成
波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,单位为波特。比特率指单位时间内传输的比特数,单位bit/s(bps)。对于USART 波特率与比特率相等,以后不区分这两个概念。波特率越大,传输速率越快。
USART 的发送器和接收器使用相同的波特率。计算公式如下:
公式 21-1 波特率计算
其中,fPLCK 为USART 时钟, USARTDIV 是一个存放在波特率寄存器(USART_BRR)的一个无符号定点数。其中DIV_Mantissa[11:0] 位定义USARTDIV 的整数部分,DIV_Fraction[3:0]位定义USARTDIV 的小数部分。
例如: DIV_Mantissa=24(0x18) , DIV_Fraction=10(0x0A) , 此时USART_BRR 值为0x18A;那么USARTDIV 的小数位10/16=0.625;整数位24,最终USARTDIV 的值为24.625。
如果知道USARTDIV 值为27.68,那么DIV_Fraction=16*0.68=10.88,最接近的正整数为11,所以DIV_Fraction[3:0]为0xB;DIV_Mantissa=整数(27.68)=27,即为0x1B。波特率的常用值有2400、9600、19200、115200。下面以实例讲解如何设定寄存器值得到波特率的值。
我们知道USART1 使用APB2 总线时钟,最高可达72MHz,其他USART 的最高频率为36MHz。我们选取USART1 作为实例讲解,即fPLCK=72MHz。为得到115200bps 的波特率,此时:
解得USARTDIV=39.0625 , 可算得DIV_Fraction=0.0625*16=1=0x01 ,DIV_Mantissa=39=0x17,即应该设置USART_BRR 的值为0x171。
校验控制
STM32F103 系列控制器USART 支持奇偶校验。当使用校验位时,串口传输的长度将是8 位的数据帧加上1 位的校验位总共9 位,此时USART_CR1 寄存器的M位需要设置为1,即9 数据位。将USART_CR1 寄存器的PCE 位置1 就可以启动奇偶校验控制,奇偶校验由硬件自动完成。启动了奇偶校验控制之后,在发送数据帧时会自动添加校验位,接收数据时自动验证校验位。接收数据时如果出现奇偶校验位验证失败,会见USART_SR 寄存器的PE 位置1,并可以产生奇偶校验中断。使能了奇偶校验控制后,每个字符帧的格式将变成:起始位+数据帧+校验位+停止位。
中断控制
USART 有多个中断请求事件,具体见表2。
表2 USART 中断请求