USART串口协议
本文最后更新于34天前,其中的信息可能已经有所发展或是发生改变。

USART,全称Universal Synchronous/Asynchronous Receiver/Transmitter,意为通用同步/异步串行接收/发送器

通信接口

通信的目的:将一个设备的数据传送到另一个设备,扩展硬件系统

通信协议:制定通信的规则,通信双方按照协议规则进行数据收发

通信的目的

比如STM32芯片,它里面集成了很多功能模块,定时器计数,pwm输出,ad采集等等,这些都是芯片内部的电路,这些电路的配置寄存器,数据寄存器都在芯片里面,操作这些寄存器非常简单,直接读写就行了,但是也有些功能是STM32内部没有的,比如我们想要蓝牙无线遥控的功能,测量姿态的功能,STM32没有,所以就只能外挂芯片来完成,那外挂的芯片它的数据都在STM32外面,就需要我们在这两个设备之间连接上一根或多根通讯线,通过通讯线路发送或者接收数据,完成数据交换,从而实现控制外挂模块和读取外挂模块数据的目的,所以在这里通信的目的是将一个设备的数据传送到另一个设备,单片机有了通信的功能,就能与众多别的模块互联,极大地扩展了硬件系统。

通信协议

通信协议的作用是制定通信的规则,通信双方按照协议规则进行数据收发,通信的目的是进行信息传递,双方约定的规则就是通信协议,还那最后在STM32里面就有下边这么多的通信协议。

名称引脚双工时钟电平设备
USARTTXRX全双工异步单端点对点
I2CSCLSDA半双工同步单端多设备
SPISCLKMOSIMISOCS全双工同步单端多设备
CANCAN_HCAN_L半双工异步差分多设备
USBDPDM半双工异步差分点对点

这个表只是列了一个最典型的参数,因为各种通信协议应用都非常宽泛,参数也很多,所以这里列出的仅是他最常用最简单的配置。

协议

USART串口,它的引脚是TXRX,有的地方也叫TXDRXD,这两种名称是一个意思,TX是数据发送引脚,RX是数据接收引脚。

IIC通信,引脚是SCLSDASCL(Serial clock)是时钟,SDA(Serial Data)是数据。

SPI通信,引脚是 SCLKMOSIMISOCSSCLK(Serial clock)是时钟,MOSI(Master Output Slave Input)是主机输出数据引脚,MISO(Master Input Slave Output)是主机输入数据引脚,CS(Chip Select)是片选用于指定通信的对象。

CAN通信,引脚是CAN_HCAN_L,这两个是差分数据脚,用两个引脚表示一个差分数据

USB通信,引脚是DP (Data Positive)和DM (Data Minus)或者叫d+和d-,也是一对差分数据引脚 这就是这些通信协议规定的引脚数据,按照协议的规定在这些引脚上进行输入和输出,从而实现通信

通信模式

接着看一下后面它们的特性(全双工:打电话。半双工:对讲机。单工:广播)

全双工模式,这里全双工就是指通信双方能够同时进行双向通信,一般来说全双工的通信都有两根通讯线,比如串口一根TX发送一根RX接收,SPI,一根MOSI发送,一根MISO接收,接收发送线路和接收线路互不影响

半双工模式,IIC、CAN和USB都只有一根数据线,CAN和USB两根差分线也是组合成一根数据线的,所以都是半双工,

单工,单工是指数据只能从一个设备到另一个设备,而不能反着来,比如把串口的RX引脚去掉,那串口就退化成单工了

时钟特性

比如你发送一个波形,高电平然后低电平,接收方怎么知道你是1、0还是1、1、0、0呢,这就需要有一个时钟信号来告诉接收方,你什么时候需要采集数据,时钟特性分为同步和异步,这里I2C和SPI有单独的时钟线,所以他们是同步的,接收方可以在时钟信号的指引下进行采样,剩下的串口、CAN和USB没有时钟线,所以需要双方约定一个采样频率,这就是异步通信,并且还需要加一些帧头帧尾等,进行采样位置的对齐。

电平特性

USART、IIC、SPI都是单端信号,也就是他们引脚的高低电平都是对GND的电压差,所以单单信号通信的双方必须要共地,就是把GND接在一起,所以说这里通信的件前三个还应该加一个GND,不接GND是没法通信的,

CAN和USB是差分信号,它是靠两个差分引脚的电压差来传输信号的,是差分信号。在通信的时候可以,不需要GND,不过USB协议里面也有一些地方需要单端信号,所以USB还是需要共地的,使用差分信号可以极大地提高抗干扰特性,所以差分信号一般传输速度和距离都会非常高,性能也是很不错的,

设备特性

串口和USB属于点对点的通信,IIC、SPI、CAN是可以在总线上挂载多个设备的。,点对点通信,就相当于老师找你去办公室谈话,只有两个人直接传输数据就可以了,多设备就相当于老师在教室里面对所有同学谈话,需要有一个寻址的过程,以确定通信的对象。

串口通信

串口是一种应用十分广泛的通信接口,串口成本低,容易使用通信线路简单,可实现两个设备的互相通信,在我们这个单片机的领域,串口其实是一种最简单的通讯接口,它的协议相比较IIC、SPI等已经是非常简单的了,而且一般单片机它里面都会有串口的硬件外设,使用也是非常方便的,一般串口都是点对点的通信,所以是两个设备之间的互相通信。

单片机的串口可以使单片机与单片机,单片机与电脑,单片机与各式各样的模块互相通信,其中单片机和电脑通信,是串口的一大优势,可以接电脑屏幕,非常适合调试程序,打印信息 ,像IIC和SPI这些一般都是芯片之间的通信,不会接在电脑上,有了通信就是极大地扩展了单片机的应用范围,增强了单片机系统的硬件实力

USB转串口模块,上面有个芯片,型号是ch340,这个芯片可以把串口协议转换为USB协议 ,它一边是USB口,可以插在电脑上,另一边是串口的硬件,可以和支持串口的芯片接在一起,这样就能实现串口和电脑的通信了。

陀螺仪传感器的模块,这姿态参数它左右各有四个引脚,一边是串口的硬件,另一边是IIC的硬件

蓝牙串口模块,上面的芯片可以和手机互联,实现手机遥控单片机的功能,那这些就是串口通信和一些使用串口通信的模块

硬件电路

下面这个图就是串口的接线图

一般串口通信的模块都有四个引脚,VCC、TXRX、GND,VCC和GND是供电,TXRX是通信的引脚,TXRX是单端信号,他们的高低电平都是相对于GND的,所以严格上来说,GND应该也算是同一线,所以串口通信的TX RX GND是必须要接的,如果两个设备都有独立供电,那VCC可以不接,如果其中一个设备没有供电,比如这里设备一是STM32设备,那就需要把蓝牙串口的VCC和STM32的VCC接在一起,STM32通过这根线,向右边的子模块供电,当然供电的电压也需要注意一下,要按照子模块的要求来,这就是供电要求。

简单双向串口通信有两根通讯线。发送端TX和接收端RX这里是简单的串口通信,复杂一点的串口通信,还有其他引脚,比如时钟引脚,硬件流控制的硬件,这些引脚STM32的串口也有,不过我们最常用的还是简单的串口通信,也就是VCC、TXRX、GND这四个引脚。

TX与RX要交叉连接TX是发送,RX是接收,那肯定得是一个设备的发送 接 另一个设备的接收,一个设备的接收 接 另一个设备的发送,这样来接线。

当只需单向的数据传输时,可以直接一根通信线。比如你只需要设备一向设备二的单向通信,那就可以直接这一根TXRX的线,另一根就可以不接,这就变成了单工的通行方式

当电平标准不一致时,需要加电平转换芯片。串口也是有很多电平标准的,像这种直接从控制器里出来的信号,一般都是TTL电平,相同的电平才能互相通信,不同的电平信号需要加一个电平转换芯片转接一。

串口常用的几种电平标准

电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

TTL电平:+3.3V或+5V表示1,0V表示0

RS232电平:-3~-15V表示1,+3~+15V表示0

RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)

RS232电平一般在大型的机器上使用,由于环境可能比较恶劣,静电干扰比较大,所以这里电平的电压都比较大,而且允许波动的范围也很大

RS485电平参考是两线压差,所以RS485的电平是差分信号,差分信号抗干扰能力非常强悍,使用RS485电平标准,通信距离可以达到上千米,而TTL电平RS232电平这两种电平最远只能达到几十米,再远就传不了了,这就是串口常用的这几种电平标准。

像单片机这种低压小型设备使用的都是TTL电平,之后的内容也都是基于TTL电平来讲,如果你做设备需要其他的电平,那就再加电平转换芯片就行,在软件层面,它们都属于串口,所以程序并不会有什么变化。

在硬件电路上,协议规定是一个设备使用TX发送高低电平,另一个设备使用RX接收高低电平,在线路中使用TTL电平,因为STM32是3.3伏的器件,所以如果线路对地3.3伏就代表发送了逻辑一,如果线路对地是零,就代表发生了逻辑零

串口协议的软件部分

如何用一和零来组成我们想要发送的一个字节数据,两个数据帧图。

波特率:串口通信的速率

起始位:标志一个数据帧的开始,固定为低电平

数据位:数据帧的有效载荷,1为高电平,0为低电平,低位先行

校验位:用于数据验证,根据数据位计算得来

停止位:用于数据帧间隔,固定为高电平

不含校验位
含校验位

这就是串口发送一个字节的格式,这个格式是串口协议规定的,串口中每一个字节都装载在一个数据帧里面,每个数据帧都有起始位数据位停止位组成,这里数据位有八个,代表一个字节的八位,在下面这个数据帧里面,还可以在数据位的最后加一个奇偶校验位,这样数据位总共就是九位,其中有效载荷是前八位,代表一个字节,校验位跟在有效载荷后面占一位,这就是串口数据帧的整体结构

第一个参数就是波特率,它的用途是规定串口通讯的速率,,串口一般是使用异步通信,所以需要双方约定一个通信速率,比如我每隔一秒发送一位,那你就也得每隔一秒接受一位,如果接收快了,那就会重复接收某些位,如果接收慢了,那就会漏掉某些位,所以说发送和接收必须要约定好速率,这个速率参数就是波特率波特率本来的意思是每秒传输码元的个数,单位是码元/S或者直接叫波特(Baud),另外还有个速率表示叫比特率,比特率的意思是每秒传输的比特数,单位是bit/s,或者叫Bps。

在二进制调制的情况下,一个码元就是一个bit,此时波特率就等于比特率,像我们单片机的串口通信基本都是二进制调制,也就是高电平表示一,低电平表示零,一位就是一bit的,所以说这个串口的波特率经常会和比特率混用,不过这也是没关系的,因为这两个说法的数值相等,如果是多进制调制,那波特率就和比特率不一样了,,那反映到波形上,比如我们双方规定波特率为1000Bps,那就表示一秒要发1000位,每一位的时间就是1ms,,发送方每隔1ms发送一位;接收方,每隔1ms接收一位,这就是波特率,它决定了每隔多久发送一位。

起始位,它是标志一个数据帧的开始,固定为低电平,看下面这个波形,首先串口的空闲状态是高电平,也就是没有数据传输的时候,硬件必须要置高电平作为空闲状态,然后需要传输的时候,必须要先发送一个起始位,这个起始位必须是低电平,来打破空闲状态的高电平,产生一个下降沿,这个下降沿就告诉接收设备这一帧数据要开始了,如果没有起始位,那当发送八个一的时候,是不是数据线就一直都是高电平,没有任何波动,这样接收方怎么知道发送数据了呢?所以这里必须要有一个固定为低电平的起始位,产生下降沿来告诉接收设备,我要发送数据了。

同理在一个字节数据发送完成后,必须要有一个停止位,这个停止位的作用是用于数据帧间隔固定为高电平,同时这个停止位也是为下一个起始位做准备的。如果没有停止位,那当我数据最后一位是零的时候,下次再发动新的一帧,是不是就没法产生下降沿了,这就是起始位停止位的作用。起始位固定为零,产生下降沿,表示传输开始。停止位固定为1,把引脚恢复成高电平,方便下一次下降沿,如果没有数据了,正好引脚也为高电平,代表空闲状态。

数据位,这里数据位表示数据帧的有效载荷,1为高电平,0为低电平,低位先行,比如我要发送一个字节是0x0,f那就首先把0f转换为二进制,就是0000 1111,然后低位先行,所以数据要从低位开始发送,也就是1111 0000,像这样依次放在发送引脚上,,所以想发送0x0f这一个字节数据,那就按照波特率要求定时翻转引脚电平,产生一个波形就行了。

校验位,它的作用是用于数据验证,是根据数据位计算得来的,这里串口使用的是一种叫奇偶校验的数据验证方法,奇偶校验可以判断数据传输是不是出错了,如果数据出错了,可以选择丢弃或者要求重传,校验可以选择三种方式,无校验、奇校验和偶校验,无校验就是不需要校验位,波形就是上面这个起始位数据位停止位,总共三个部分。奇校验和偶校验的波形就是下面这个,起始位数据位校验位停止位总共四个部分。

如果使用了奇校验,那么包括校验位在内的9位数据会出现奇数个1,比如如果你传输0000 1111,目前总共四个一是偶数个,那么校验位就需要再补一个1,连同校验位就是0000 1111 1,总共五个1,保证1为奇;如果数据是00001110,此时三个1,是奇数个,那么校验位就补一个0,连同校验位就是0000 1110 0,总共还是三个1,1的个数为奇数,发送方在发送数据后会补一个校验位,保证一的个数为奇数。接收方在接收数据后会验证数据位校验位,如果1的个数还是奇数,就认为数据没有出错,如果在传输中因为干扰有一位由1变成0或者由0变成1了,那么整个数据的奇偶特性就会变化,接收方已验证发现一的个数不是奇数,那就认为传输出错,就可以选择丢弃或者要求重传,这就是奇校验的差错控制方法。

如果选择双方约定偶校验,那就是保证一的个数是偶数,校验方法也是一样的道理,当然奇偶校验的检出率并不是很高,比如如果有两位数据同时出错,奇偶特性不变,那就校验不出来了,所以奇偶校验只能保证一定程度上的数据校验,如果想要更高的检出率,可以了解一下CRC校验,这个校验会更加好用,当然也会更复杂,我们这个STM32内部也有CRC的外设,可以了解一下。

我们这里的数据位有两种表示方法,一种是把校验位作为数据位的一部分,就像上面这个时序一样,分为八位数据和九位数据,其中九位数据就是八位有效载荷和一位校验位,另一种就是把数据位校验位独立开,数据位就是有效载荷,校验位就是独立的1位,像上面的描述,就是把数据位和较量位分开描述了,在串口助手软件里也是用的这种分开描述的方法,数据为八位,校验位为一位,总之无论是合在一起还是分开描述,描述的都是同一个东西,

串口通信的实际波形

这些波形是用示波器实测的,操作方法是把探头的GND接在负极,探头接在发送设备的TX引脚,然后发送数据就能捕捉到这些波形了

0x55,9600,8位数据,1位停止,无校验

0x55,9600,8位数据,1位停止,无校验

这个波形是发送一个字节数据0x55,,在TX引脚输出的波形,波特率是9600,所以每一位的时间就是1÷9600,大概是104微秒,可以看到这里一位就是100微秒,多一点就是104微秒,没发送数据的时候是空闲状态高电平,数据帧开始,先发送起始位,产生下降沿,代表数据帧开始,数据0x55 转为二进制,低位先行,就是依次发送1010 1010,然后这个参数是八位数据,一位停止,无效验,所以之后就是停止位,把引脚置回高电平,这样一个数据帧就完成了。

在STM32中,这个根据字节数据翻转高低电平,自由USART外设自动完成的,不用我们操心,当然也可以软件模拟产生这样的波形,那就是定时器定一个104微秒的时间,时间到之后按照数据恢要求,调用GPIO_WriteBit置高低电平,产生一个和这一模一样的波形,这样也是可以完成串口通信的,TX引脚发送就是置高低电平,那在RX引脚接收,显然就是读取高低电平了,这也可以由USART外设自动来完成,不用我们操心,如果想要软件模拟的话,那就是定时调用GPIO_ReadInputDataBit来读取每一位,最终拼接成一个字节。当然接收的时候应该还需要一个外部中断,在起始位的下降沿触发,进入接收状态,并且对齐采样时钟,然后依次采样八次,这就是接收的逻辑。

0xAA,9600,8位数据,1位停止,无校验

0xAA,9600,8位数据,1位停止,无校验

如果发送0xAA波形就是这样的,起始位,然后0101 0101,停止位,结束。

0xFF,9600,8位数据,1位停止,无校验

0xFF,9600,8位数据,1位停止,无校验

如果发送0x ff就是八个一,那波形就是这样,起始位,8个1,停止位,结束。在起始位下降沿之后的一个数据帧的时间内,这个高电平就是作为数据一来看的,当数据帧结束后,这里虽然还是一没有任何变化,但此时的一已经是属于空闲状态了,他需要等待下一个下降沿来开启新的一帧数据。

0x00,9600,8位数据,1位停止,无校验

0x00,9600,8位数据,1位停止,无校验

如果发送0x00 就是八个零,那波形就是,起始位,八个零,停止位,置回高电平。

0x55,4800,8位数据,1位停止,无校验

0x55,4800,8位数据,1位停止,无校验

波特率改成4800,也就是波特率变为一半,那相应的波形时长就会变为原来的二倍,可以看到这里十位数据总共大概2ms多一点,具体应该在2.08ms,那一位就是208微秒,是之前的二倍,数据波形的时间拉宽,波形的变化趋势是不变的

0x55,9600,8位数据,1位停止,偶校验

0x55,4800,8位数据,1位停止,无校验

这里加了一个偶校验位,数据是0x55 数下1的个数是四个,已经是偶数了,所以输出的校验位是零,低电平,此时包括校验位在内的数据总共是偶数个1。

0x55,9600,8位数据,1位停止,无校验

0x55,9600,8位数据,1位停止,无校验

停止位的变化,串口的停止位是可以进行配置的,可以选择1位、1.5位、2位等,这上面的波形是一位停止位 ,连续发送两个0x55,两个数据真会接在一起,中间没有空闲状态,下面这个波形是两位停止位

0x55,9600,8位数据,2位停止,无校验

0x55,9600,8位数据,2位停止,无校验

连续发送两个0x5 ,可以看到这里停止位就是两位的宽度,中间也没有空间状态,不过这样数据分隔的就更宽一些了,这就是不同长度停止位的现象。

总结

TX引脚输出定时翻转的高低电平,RX引脚定时读取引脚的高低电平,每个字节的数据加上起始位停止位,可选的校验位,打包为数据帧,依次输出在TX引脚,另一端RX引脚依次接收,这样就完成了字节数据的传递,这就是串口通信。 ,

点击数:1

    暂无评论

    发送评论 编辑评论

    
    				
    |´・ω・)ノ
    ヾ(≧∇≦*)ゝ
    (☆ω☆)
    (╯‵□′)╯︵┴─┴
     ̄﹃ ̄
    (/ω\)
    ∠( ᐛ 」∠)_
    (๑•̀ㅁ•́ฅ)
    →_→
    ୧(๑•̀⌄•́๑)૭
    ٩(ˊᗜˋ*)و
    (ノ°ο°)ノ
    (´இ皿இ`)
    ⌇●﹏●⌇
    (ฅ´ω`ฅ)
    (╯°A°)╯︵○○○
    φ( ̄∇ ̄o)
    ヾ(´・ ・`。)ノ"
    ( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
    (ó﹏ò。)
    Σ(っ °Д °;)っ
    ( ,,´・ω・)ノ"(´っω・`。)
    ╮(╯▽╰)╭
    o(*////▽////*)q
    >﹏<
    ( ๑´•ω•) "(ㆆᴗㆆ)
    😂
    😀
    😅
    😊
    🙂
    🙃
    😌
    😍
    😘
    😜
    😝
    😏
    😒
    🙄
    😳
    😡
    😔
    😫
    😱
    😭
    💩
    👻
    🙌
    🖕
    👍
    👫
    👬
    👭
    🌚
    🌝
    🙈
    💊
    😶
    🙏
    🍦
    🍉
    😣
    Source: github.com/k4yt3x/flowerhd
    颜文字
    Emoji
    小恐龙
    花!
    上一篇
    下一篇