文章目录
USART串口协议
通信接口
为什么需要通信
将一个设备的数据传到另一个设备,扩展硬件系统,比如在stm32芯片里集成了很多功能模块,定时器计数、PWM输出、AD采集等等,都是芯片内部的电路,这些电路的配置寄存器、数据寄存器都在芯片里面,操作这些寄存器直接读写就行,但有些STM32内部没有的功能,比如蓝牙无线遥控、陀螺仪加速度计测量姿态等等,只能外挂芯片,STM要想获取这些数据,需要在两个设备间连接上一根或多跟通信线,通过通信线路发送或者接受数据,完成数据交换,从而实现控制外挂模块和读取外挂模块数据的目的。
引脚
TX(Transmit Exchange)是数据发送脚,RX(Receive Exchange)是数据接收脚。
SCL(Serial Clock)是时钟,SDA(Serial Data)是数据。
SCLK(Serial Clock)是时钟,MOSI(Master Output Slave Input)是主机输出数据脚,MISO(Master Input Slave Output)是主机输入数据脚,CS(Chip Select)是片选,用于指定通信的对象。
CAN_H、CAN_L是差分数据脚,用两个引脚表示一个差分数据。
DP(Data Positive)和DM(Data Minus)或者脚D+和D-,也是一对差分数据脚。
双工
全双工的通信都有两根通信线,半双工有一根通信线,CAN和USB两根差分线也是组合成一根数据线的。
时钟特性
比如发一个波形,高电平然后低电平,接收方如何知道是1、0还是1、1、0、0呢,这时需要一个时钟信号来告诉接收方,什么时候需要采集数据,时钟特性分为同步和异步,I2C和SPI有单独的时钟线,所以是同步的,接收方可以在时钟信号的指引下进行采样,剩下的串口、CAN和USB没有时钟线,所以需要双方约定一个采样频率,这就是异步通信,并且还要加一些帧头帧尾等,进行采样位置的对齐。
电平特性
上面三个单端信号,引脚的高低电平都是对GND的电压差,所以单端信号通信的双方必须共地,就是把GND接在一起,所以说前三个的通信引脚还应该加一个GND引脚。CAN和USB是差分信号,是靠两个差分引脚的电压差来传输信号的,由于USB协议里也有些地方需要单端信号,所以USB需要共地,使用差分信号可以极大地提高抗干扰特性,所以差分信号一般传输速度和距离都会非常高。
设备特性
串口和USB是点对点的通信,中间三个是可以在总线上挂载多个设备的,点对点通信相当于一对一,多设备需要有一个寻址的过程确定通信的对象。
串口通信
USB转串口模块
上面有CH340芯片,可以把串口协议转换为USB协议
陀螺仪传感器模块
可以测量角速度、加速度这些姿态参数
蓝牙串口模块
硬件电路
一般串口通信的模块都有四个引脚,VCC、TX、RX、GND,VCC和GND是供电,TX和RX是通信的引脚,TX和RX是单端信号,他们的高低电平都是相对于GND的,所以严格来说GND也算是通信线,所以这三个引脚必须接,对于VCC,如果两个设备都有独立供电,那VCC可以不接,如果其中一个设备没有供电,比如设备1是STM32,有独立供电,设备2是蓝牙串口没有独立供电,需要把蓝牙串口的VCC和STM32的VCC接在一起,STM32通过这根线,向右边的子模块供电,供电的电压注意要按子模块的要求来。
TX是发送,RX是接收,一个设备的发送接另一个设备的接收,一个设备的接收接另一个设备的发送。
如果仅需要设备1向设备2通信,可以只接设备1的TX到设备2的RX。
串口有很多电平标准,直接从控制器里出来的信号,一般都是TTL电平,想通的电平才能互相通信,不同的电平信号,需要加一个电平转换芯片,转接一下。
电平标准
单片机这种低压小型设备,使用TTL电平。
RS232电平一般在大型的机器上使用,由于环境可能比较恶劣,经典干扰比较大,所以电平的电压都比较大,而且允许波动的范围也很大。
RS485电平是差分信号,差分信号抗干扰能力非常强,使用RS485电平标准,通信距离可达上千米,上面两个最远只能几十米。
串口参数及时序
如何用1和0,来组成我们想要发送的一个字节数据,两个时序图是串口发送一个字节的格式,格式是串口协议规定的,串口中每一个字节都装载在一个数据帧里面,每个数据帧都由起始位、数据位和停止位组成。
左边数据位有8个,代表一个字节的8位。右边数据帧里还可以在数据位的最后加一位奇偶校验位,数据位共9位,其中有效载荷是前8位,代表一个字节,校验位跟在有效载荷后面,占1位。
波特率
规定串口通信的速率,因为串口一般是使用异步通信,所以需要双方约定一个通信速率,比如每隔1s发送一位,就要每隔1s接收一位,如果接收快了就会重复接收某些位,如果接收慢了就会漏掉某些位,所以发送和接收必须约定好速率,这个速率参数就是波特率。波特率本来的意思是每秒传输码元的个数,单位是码元/s,或者直接叫波特(Baud),另外还有个速率表示,叫比特率,比特率的意思是每秒传输的比特数,单位是bit/s,或者叫bps。在二进制调制的情况下,一个码元就是一个bit,此时波特率就等于比特率,像单片机的串口通信,基本都是二进制调制,高电平表示1,低电平表示0,一位就是1bit,所以这个串口的波特率,经常会和比特率混用,但没关系,这两个说法的数值相等。如果是多进制调制,那波特率和比特率就不一样了。反映到波形上,如果双方规定波特率为1000bps,表示1s要发1000位,每一位的时间就是1ms。发送方每隔1ms发送一位,接收方每隔1ms接收一位,这就是波特率,决定了每隔多久发送一位。
起始位
串口的空闲状态是高电平,也就是没有数据传输的时候,引脚必须置高电平作为空闲状态,需要传输的时候必须要先发送一个起始位,起始位必须是低电平来打破空闲状态的高电平,产生一个下降沿,下降沿就告诉接收设备这一帧数据要开始了,如果没有起始位,那发送8个1的时候,数据线就一直是高电平没有任何波动,这样接收方不知道什么时候发送数据,所以必须要有一个固定为低电平的起始位,产生下降沿,来告诉接收设备要发送数据了。
停止位
同理在一个字节数据发送完成后,必须要有一个停止位,停止位的作用时用于数据帧间隔,固定为高电平,同时这个停止位也是为下一个起始位做准备的,如果没有停止位,那当数据最后一位是0的时候,下次再发送新的一帧就没法产生下降沿了。即起始位固定为0,产生下降沿,表示传输开始,停止位固定位1,把引脚恢复成高电平,方便下一次的下降沿,如果没有数据了,正好引脚也为高电平,代表空闲状态。
数据位
如果发送一个字节是0x0F,首先把0F转换为二进制,就是0000 1111,然后低位先行,所以数据要从低位开始发送,也就是1111 0000,依次放在发送引脚上,最终引脚的波形就是下图所示。
校验位
串口使用奇偶检验的数据验证方法,奇偶校验可以判断数据传输是不是出错了,如果数据出错了,可以选择丢弃或者要求重传,校验可以选择3种方式,无校验、奇校验和偶校验,无校验就是不需要校验位,波形是左边这个,起始位、数据位、停止位,总共三个部分,奇校验和偶校验的波形是右边这个,起始位、数据位、校验位、停止位,总共四个部分。
奇校验
如果使用了奇校验,那么包括校验位在内的9位数据会出现奇数个1,比如传输0000 1111,四个1是偶数个,校验位需要再补一个1,0000 11111,总共五个一,保证1位奇数,如果数据是0000 1110,此时3个1奇数个,校验位补0,0000 11100,总共3个1,1的个数为奇数,发送方在发送数据后,会补一个校验位,保证1的个数为奇数,接收方在接收数据后,会验证数据位和校验位,如果1的个数还是奇数,就认为数据没出错,如果因为干扰接收方发现1个个数不是奇数就认为传输出错,可以选择丢弃或要求重传,这就是奇校验的差错控制方法。
偶校验
保证1的个数是偶数,注意奇偶校验的检出率不是很高,如果两位数据同时出错,奇偶特性不变就校验不出来,所以奇偶校验只能保证一定程度上的数据校验。
最后补充,数据位有两种表示方法,一种是把校验位作为数据位的一部分,像下面的时序一样,分为8位数据和9位数据,其中9位数据就是8位有效载荷和1位校验位,另一种就是把数据位和校验位独立开,数据位就是有效载荷,校验位就是独立的1位,上面描述的就是把数据位和校验位分开描述,在串口助手里也是分开描述。
串口时序
用示波器实测波形,操作方法是把探头的GND接在负极,探头接在发送设备的TX引脚,然后发送数据就能捕捉到这些波形了。
第一个波形是发送一个字节数据0x55时,在TX引脚输出的波形,波特率是9600,所以每一位的时间就是1/9600,大概是104us,每一位就是100us多一点,就是104us,数据帧开始,先发送起始位,产生下降沿,代表数据帧开始,数据0x55转为二进制,低位先行,就是依次发送1010 1010,然后这个参数是8位数据,1位停止,无校验,没有校验位,所以之后就是停止位,把引脚置回高电平,这样一个数据帧就完成了,在STM 32中根据字节数据翻转高低电平,是由USART外设自动完成的,不用我们操心。
如果发送0xAA,起始位,然后0101 0101,停止位,结束。
如果发送0xFF,就是8个1,起始位,8个1,停止位,结束。在起始位下降沿之后的一个数据帧的时间内,高电平就是作为数据1来看的,当数据帧结束后,虽然还是1,没有任何变化,但此时的1已经属于空闲状态了,需要等待下一个下降沿来开启新的一帧数据。
如果发送0x00,就是8个0,波形就是,起始位,8个0,停止位置回高电平。
如果把波特率改为4800,也就是波特率变为一半,相应的波形时长就会变为原来的二倍,十位数据总共大概2ms多一点,具体应该2.08ms,一位就是208us,是之前的二倍,数据波形的时间拉宽,波形的变化趋势是不变的。
数据是0x55,加了偶检验位,1个的个数是4个,已经是偶数了,所以输出的校验位是0,低电平,此时包括校验位在内的数据总共是偶数个1。
最后看停止位的变化,串口的停止位是可以进行配置的,可以选择1位、1.5位、2位等,上面的波形是1位停止位,连续发送两个0x55,两个数据帧回接在一起,中间没有空闲状态,下面波形是2位停止位,连续发送两个0x55,停止位就是两位的宽度,中间没有空闲,不过数据分割的就更宽一些了,这就是不同长度停止位的现象。
总结一下,TX引脚输出定时翻转的高低电平,RX引脚定时读取引脚的高低电平,每个字节的数据加上起始位、停止位、可选的校验位,打包为数据帧,依次输出在TX引脚,另一端RX引脚依次接收,这样就完成了字节数据的传递,这就是串口通信。