本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时,也能帮助其他需要参考的朋友。如有谬误,欢迎大家进行指正。
一、UART接口概要
UART接口,即通用异步接收器/发送器,是一种常用的串行通信协议,广泛应用于单片机或各种嵌入式设备之间的通信。在串行通信中,数据通过单条线路或导线逐位传输。在双向通信中,我们使用两根导线来进行连续的串行数据传输。根据应用和系统要求,串行通信需要的电路和导线较少,可降低实现成本。
二、UART电气特性
UART的电气特性主要涉及不同的电气标准,这些标准定义了串口通信中信号的电平、电压范围等关键参数,以下是几种UART常见的电气特性的差异对比表:
对比项 | TTL | RS232 | RS422 | RS485 |
信号类型 | 电平信号 | 负逻辑电平信号 | 差分信号 | 差分信号 |
电平范围 | 0-3.3V/5.0V | ±15V | -0.25V-+6V | -7V-+12V |
抗干扰能力 | 弱 | 较强 | 强 | 强 |
传输距离 | <1m | <15m | <1200m | <1200m |
传输带宽 | <100Kb/s | <100Kb/s | <10Mb/s | <10Mb/s |
负载个数 | 1 | 1 | 10 | 32 |
传输模式 | 全双工,点对点 | 全双工,点对点 | 全双工,点对点 | 半双工,多对多 |
最少走线根数 | 3 | 3 | 4 | 2 |
三、波特率
波特率是衡量数据的传输速度,单位为bps(bits per second),即每秒传输的比特位。UART通信中,发送端和接收端必须在同样的波特率下工作,以确保数据能够准确传输。波特率的不同会导致位的时序不一致,从而引发数据传输错误,波特率误差偏大同样也会导致通讯失败,在工程实践中通常建议双方允许的最大波特率偏差为5%,在高精度要求的应用场合下建议将误差控制在2%以内。
在实际应用中,通常是通过已知的波特率进行计算分频因子并导入UART配置文件,微控制器的datasheet或参考手册通常会提供具体的计算公式和示例。下面以STM32为例:
(1)确认系统时钟频率(PCLK)
对于STM32,USART1的时钟源来自于APB2(PCLK2),其他USART(USART2-5)来源于APB1(PCLK1)。通常PCLK1最大的频率为36MHz,PCLK2的最大频率是72MHz。具体取决于系统时钟的配置。
(2)根据datasheet提取计算公式
STM32的波特率计算公式:波特率=fck/(16×USARTDIV),其中,fck是系统时钟频率(PCLK1或PCLK2),USARTDIV是波特率分频因子,16是因为STM32的串口硬件设计中,每传输1bit数据,会采样16次,以确保数据的准确性。通过这种方式STM32能够减少由于信号干扰或抖动导致的错误,提高串口通讯的可靠性。
(3)计算USARTDIV
根据目标波特率和时钟系统的频率,可以计算出USARTDIV的值:USARTDIV=fck/(16×目标波特率)
(4)分数波特率的产生和设置USART_BRR寄存器
USARTDIV是一个无符号定点数,STM32的USART_BRR寄存器支持分数设置以提高精确度。USART_BRR的前4位用于表示小数部分,后12位用于表示整数部分。计算出的USARTDIV值需要被拆分为整数部分和小数部分,分别填入USART_BRR寄存器。整数部分放在高12位,小数部分放在低4位。
(5)示例计算:
假设系统时钟是fck=72MHz,目标波特率为115200bps,计算USARTDIV的值:
USARTDIV=72000000/(16×115200)=39.0625
其中,将39.0625拆分为整数部分39和小数部分0.0625,进行进制转换,USART_BRR寄存器的值为0x2701。
(6)误差计算
实际波特率可能与目标波特率存在误差,误差率可以通过以下公式计算:
四、数据格式
空闲位:UART协议规定,当总线处于空闲状态时信号线的状态为‘1’即高电平,表示当前线路上没有数据传输。
起始位:每开始一次通信时发送方先发出一个逻辑”0”的信号(低电平),表示传输字符的开始。因为总线空闲时为高电平所以开始一次通信时先发送一个明显区别于空闲状态的信号即低电平。
数据位:数据位指每个数据帧中数据的实际位数。常见的数据位设置有7位、8位,有时也会有9位数据位(用于某些特殊协议)。在ASCII编码中,通常使用7位或8位数据位来表示一个字符。
奇偶检验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。校验位其实是调整个数,串口校验分几种方式:
(1)校验位用于错误检测,可以是奇校验(Odd)、偶校验(Even)或无校验(None)。
(2)奇校验意味着数据位中“1”的数量加上校验位应该是奇数。
(3)偶校验意味着数据位中“1”的数量加上校验位应该是偶数。
(4)无校验意味着不使用校验位,数据帧只包含数据位和停止位。
停止位:停止位定义了每个数据帧结束时的空闲位(空闲状态通常是高电平,即逻辑“1”)。常用的设置是1位停止位,但在某些情况下,如需要增强数据帧之间的区分度时,可能会使用1.5位或2位停止位。