首页 > 版块 > STM32 > 帖子正文

STM32 UART、I2C、SPI串口通信对比分析

张角 发布于 2021-10-27 13:58
收藏 1 回复 0 浏览 452 原创

      大家好,我是张飞实战电子张角老师!

所有通信协议,应该都是一个速度、成本的折中,这里的成本包括完成通信所占据的接口资源(或者说需要几根线)以及硬件电路模块设计的复杂度。

    我们前面分析过,如果想要实现高速的数据通信,通信双方的时钟是必须同步的,否则可能会出现数据错位的情况,尤其是通信双方本身的时钟频率相差较大的时候。那么自然的,uart作为一种异步通信协议,它的传输速率肯定不会太高,或者说肯定是小于同步通信协议的。反过来说,如果异步通信协议采用采用发送方或者接受方中的一个时钟频率,作为通信的波特率,那么在两者的时钟频率相差较大的情况下,一定会出现数据错配的情况。甚至有可能,每次传递8个数据都不一定传输得了。信号传输的波特率降低了以后,可以降低对通信双方频率相差的要求,反正最后都要把自身的频率和波特率之间进行一次转换,归一到统一的波特率上来。但是归一化之后依然会有误差的,这个我们前面讨论过,所以依然不能每次传递较多的数据。再加上,uart通信协议中,各种辅助位占据了一定的资源(大约25%),数据传递的速度肯定就更慢了。

    虽然uart传输的速度相对较慢,但是如果只是单向通信的话,着实相对来说,非常简单。只需要两根线就可以了,一根Tx就行(大多数情况下,通信的双方都是共地的)。

那么现在我们达成了共识,如果要进行高速的串口通信,必须在通信的双方之间进行时钟同步。那么SPII2C这两种协议,应运而生了。那么SPII2C有什么区别呢?我感觉这两个有点像TCPUDP的区别一样,TCP有校验和握手机制;UDP则没有,只是不管不顾发数据。具体表现就是I2C是有应答机制的,但是SPI没有,那么自然I2C这种通信协议的传输速率是没有SPI快的。再一个,在I2C通信中,不管是读指令还是写指令,首先进行的是不是寻址呀,找到相应的芯片以后,才能进行下一步的数据传输,是吧。但是SPI就不用搞这个操作,它是通过硬件的片选信号之间指定从机的,从地址寻址上看,它的速度要远比I2C高。还有一个,不管是读数据还是写数据,一般都是还还要再指定寄存器的地址,然后主机才能通过SDA总线去读取从机中的数据,但是SPI一般是直接通过指令读取相应的寄存器,这中间又少了一次寻址的过程,那么有效数据传递的速度相比I2C,肯定是高了许多。

从通信双工的角度来讲,SPI还支持双工通信,那数据传输的速度就更快了,在这个方面作为半双工通信的I2C自然是更比不了。

虽然传输速度,I2C比不上SPI,但是I2C也是有自己的优点呀,那就是占用的端口资源更少。只要两根线就行了,一根数据线,一根时钟线,就足够了,就可以实现双向通信了。但是SPI可不行了,SPI要实现这种双向通信,至少需要四根线,CLKMOSIMISOCSS。俗话说,一分价钱一分货,此言不虚。

image.png

        I2CSPI都是可以实现点对多点进行通信的,既然要实现点对多点进行通信,那么就必须解决寻址的问题。SPI,我们说过了,仗着自己数据传输速度快的优点,财大气粗,对每一个从机都安排了一个片选信号线。这种操作,着实占用了不少单片机的接口资源。但是I2C就不行了,因为数据传递的速度相对较慢,自然得节省开支,包括在点对多点的寻址上也是如此。I2C通信协议是通过地址码的方式来解决多机寻址问题的,这个就有点像SPI的片选线。

系统中的所有外围器件都具有一个7位的"从器件专用地址码",其中高4位为器件类型,由生产厂家制定,低3位为器件引脚定义地址,由使用者定义。主控器件通过地址码建立多机通信的机制,因此I2C总线省去了外围器件的片选线,这样无论总线上挂接多少个器件(当然终端在要在有效个数范围内),其系统仍然为简约的二线结构。终端挂载在总线上,有主端和从端之分,主端必须是带有CPU的逻辑模块,在同一总线上同一时刻只能有一个主端,可以有多个从端,从端的数量受地址空间和总线的最大电容 400pF的限制。

image.png

基于IIC总线的物理结构,总线上的STARTSTOP信号必定是唯一的。如果同时又两个设备同时发起数据传送怎么办?这就涉及到时钟同步和SDA仲裁的问题。我们这里注意到SDASCL都是开漏输出设计,那么自然SDASCL都具有线与功能。在SCL总线上只有所有的设备的SCL都为高的时候,SCL才为高,只要有一个为低,那么SCL就为低。不管怎样,所有从设备设备的SCL总是同步的。要么是高,要么是低。

那么SDA的仲裁问题是怎么回事呢?SDA线的仲裁也是建立在总线具有线“与”逻辑功能的原理上的。节点在发送1位数据后,比较总线上所呈现的数据与自己发送的是否一致。是,继续发送;否则,退出竞争。这里的比较功能是I2C设计的亮点,有了这个功能为基础,SDA的总线仲裁才能是自动执行的。SDA线的仲裁可以保证I2C总线系统在多个主节点同时企图控制总线时通信正常进行并且数据不丢失。总线系统通过仲裁只允许一个主节点可以继续占据总线。

image.png


上图是以两个节点为例的仲裁过程。DATA1DATA2分别是主节点向总线所发送的数据信号,SDA为总线上所呈现的数据信号,SCL是总线上所呈现的时钟信号。当主节点12同时发送起始信号时,两个主节点都发送了高电平信号。这时总线上呈现的信号为高电平,两个主节点都检测到总线上的信号与自己发送的信号相同,继续发送数据。第2个时钟周期,2个主节点都发送低电平信号,在总线上呈现的信号为低电平,仍继续发送数据。在第3个时钟周期,主节点1发送高电平信号,而主节点2发送低电平信号。根据总线的线“与”的逻辑功能,总线上的信号为低电平,这时主节点1检测到总线上的数据和自己所发送的数据不一样,就断开数据的输出级,转为从机接收状态。这样主节点2就赢得了总线,而且数据没有丢失,即总线的数据与主节点2所发送的数据一样,而主节点1在转为从节点后继续接收数据,同样也没有丢掉SDA线上的数据。因此在仲裁过程中数据没有丢失。

这里大家注意一下,SCL同步与SDA仲裁是同时发生的,不存在先后问题。这些实现都是由于I2C设备的特殊设计实现的,堪称非常优雅。


0 1
发表评论 侵权投诉
评论 (0)

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表乌云踏雪网立场。

文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。