一、UART
UART,全称UniversalAsynchrONous Receiver/Transmitter,译为通用异步收发器(异步串行通信口),比SPI、I2C这两种同步串口的结构要复杂很多,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成。硬件上有两根线,一根用于发送,一根用于接收。数据是异步传输的,对双方的时序要求比较严格。串口按位(bit)发送和接收字节,尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。在多机通信上面用的最多。如果用GPIO口模拟UART总线,则需一个输入口,一个输出口。
1、UART几个相关的概念
部分参考,GPIO,I2C,SPI,UART,USART,USB的区别_步印的博客-CSDN博客_spi和gpio的区别
UART包括了RS232、RS499、RS423、RS422和RS485等接口标准规范和总线标准规范,即UART是异步串行通信口的总称。而RS232、RS499、RS423、RS422和RS485等,是对应各种异步串行通信口的接口标准和总线标准,它规定了通信口的电气特性、传输速率、连接特性和接口的机械特性等内容。是属于通信网络OSI模型中的物理层 的概念。具体可以看《嵌入式硬件通信接口协议-UART(二)不同电气规范下的标准》这篇文章。
UART的电平信号由MCU芯片决定,TTL/CMOS,是嵌入式硬件系统的信号电平。日常的开发过程中,MCU管脚上的UART通信电平就是TTL/CMOS电平信号。TTL电平,逻辑“0”等于0V电压,逻辑“1”等于+5V电压。CMOS电平,逻辑“0”接近0V电压,逻辑“1”接近电源电压(3.3V或其他)。TTL电路与CMOS电路比较,TTL电路是电流控制器件,而CMOS电路是电压控制器件;TTL的速度快,传输延迟时间短(5-10ns),但是功耗大。CMOS电路的速度慢,传输延迟时间长(25-50ns),但功耗低。CMOS电路本身的功耗与输入信号的脉冲频率有关,频率越高,芯片即越热,这是正常现象。
COM口是PC(个人计算机)上,异步串行通信口的简写。在PC等操作系统上,COM口区别于USB、SATA接口的串行接口,定义了在操作系统中的规范。由于历史原因,IBM的PC外部接口配置为RS232,成为实际上的PC界默认标准。所以,现在PC机的COM口均为RS232。若配有多个异步串行通信口,则分别称为COM1、COM2等等,但由于串口(COM)不支持热插拔及传输速率较低,目前部分新主板和大部分便携电脑已开始取消该接口。目前串口多用于工控和测量设备以及部分通信设备中。
UART多应用两个设备之间的通信,如用单片机的设备和计算机的通信。这样的通信可以做长距离的。UART速度比SPI、I2C两者者快,最高达100K左右,用与计算机与设备或者计算机和计算之间通信,但有效范围不会很长,约10米左右,UART优点是支持面广,程序设计结构很简单,随着USB的发展,UART也逐渐走向下坡。
我们常说的串口,是指使用RS232标准进行传输的UART接口(9针)。
2、UART通讯需要配置的参数
1)波特率
波特率部分文章参考,DigCore:嵌入式硬件通信接口协议-UART(一)协议基础
由于UART属于异步通信,在通信过程中没有同步时钟CLK来提供给接收方,接收方也就无法同步地确定每个bit的宽度,也就无法对每个bit进行正确的采样。因此接收方必须依靠设置与发送方相同的波特率参数,这样接收方对信号管脚进行采样和解码时,才能正确判断每个bit的值是“1”还是“0”,这也就是异步通信的特点。
在各类MCU的UART配置中,常用的波特率值有:4800Bd、9600Bd、19200Bd、115200Bd,单位Bd。
在维基百科的介绍中,可看到,波特率的值,直接以bit/s的单位取倒数后得到单位s/bit。在示波器端对UART发出的波形进行抓取实验,可见每bit的宽度在误差允许范围内基本就是波特率的倒数值。
在百度百科的词条介绍中
调制速率,指的是有效数据信号调制载波的速率,即单位时间内载波调制状态变化的次数。它是对符号传输速率的一种度量,1波特即指每秒传输1个符号,而通过不同的调制方式,可以在一个码元符号上负载多个bit位信息。单位“波特”本身就已经是代表每秒的调制数,以“波特每秒”(Baud per second)为单位是一种常见的错误。
它代表的是信号的变化,而不是传输数据的多少。它表示每秒钟内通信线路状态改变的次数。如果数据不压缩,波特等于每秒钟传输的数据位数,如果数据进行了压缩。那么每秒钟传输的数据位数通常大于调制速率,使得交换使用波特和比特/秒有时会产生错误。
但是在现代的实际使用中,多数情况下,配置了MCU的波特率后,对输出信号进行观测发现,此时波特率就等于比特率。也正是因为此时传输的符号即8bit一个Byte的数据量,从而波特率等于比特率。
其中,fck为 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。
如果拿到一块板子或者一套设备,但没有源码程序,纯靠硬件抓取通信串口的数据内容,首先利用示波器观测每个bit的宽度,后换算成比特率,这时候比特率基本上就是波特率了。利用串口助手模块,在PC端下载个串口助手,设置匹配的波特率进行数据抓取。
比如抓到波形116us/bit, 直接转换得:1bit/116us = 1 bit/(116/1000000)s = 8620.68 bit/s,此时配置串口助手的波特率,利用串口助手模块与被测信号管脚进行连接,即可实现串口数据的抓取。
2)数据格式
起始位:数据线空闲状态为高电平,要发送数据时将其拉低一个时钟周期表示起始位。
数据位:使用校验位时,数据位可以有5~8位;如果不使用校验位,数据位可以达9位。
校验位:奇偶校验,保证包括校验位和数据位在内的所有位中1的个数为奇数或偶数。
停止位:为了表示数据包发送的结束,发送端需要将信号线从低电平变为高电平,并至少保持2个时钟周期。
3)流控制
流控制,俗话说就是“握手”。流控制的作用,在不同处理性能的设备之间,数据传输之前,接收方会以“流控制”来通知发送方,是否可以继续进行接下来的数据传输。这样的应用场景多见于计算机与低性能的微控制器通信,也可见于PC与打印机之间进行的数据传输,该特点都是接收方的接收缓存已满或处理事务较慢时,从而需要流控制来告知发送方稍后再发送。
流控制的方式分别有软件和硬件两种。
软件的流控制方式,在UART通信中,只需RxD、TxD、GND三根即可,数据在传输过程中,依靠代码的判断处理,并通过收发双方进行的数据交互完成控制,在现有通信物理信号线基础上,使用控制字符(ASCII表中的0x00~0x0x1F、0x7F)完成控制指令的交互。一般在私有协议下也会定义一些特殊字符设为控制指令。
硬件的流控制方式,即在原有的RxD、TxD、GND三根信号线的基础上,再增加RTS/CTS和DTR/DSR这两组信号线。第一组线是RTS(Request toSend)和CTS(Clear toSend)。当接收方准备好接收数据,它置高RTS线表示它准备好了,如果发送方也就绪,它置高CTS,表示它即将发送数据。第二组线是DTR(DataTerminal Ready)和DSR(Data SetReady)。这些线主要用于Modem通信。使得串口和Modem通信他们的状态。例如:当Modem已经准备好接收来自PC的数据,它置高DTR线,表示和电话线的连接已经建立。读取DSR线置高,PC机开始发送数据。一个简单的规则是DTR/DSR用于表示系统通信就绪,而RTS/CTS用于单个数据包的传输。
3、UART的优缺点
1)优点
只使用两根电线,不需要时钟信号。有一个奇偶校验位,只要双方设置后,就可以改变数据包的结构
2)缺点
数据帧的大小限制为最多9位,不支持多个从属或多个主系统,每个UART的波特率必须在10%之内
二、SPI
参考文章, SPI、I2C、UART、CAN_一只大笨猫的博客-CSDN博客
SPI,Serial Peripheral interface,顾名思义就是串行外围设备接口,是Motorola首先在其MC68HCXX系列处理器上定义的。SPI总线是微控制器四线的外部总线(相对于内部总线)。与IIC不同,SPI没有明文标准,只是一种事实标准,对通信操作的实现只作一般的抽象描述,芯片厂商与驱动开发者通过data sheets和application notes沟通实现上的细节。
SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,比如AT91RM9200。
SPI分为主、从两种模式,一个SPI通讯系统需要包含一个(且只能是一个)主设备,一个或多个从设备。SPI接口的读写操作,都是由主设备发起。当存在多个从设备时,通过各自的片选信号进行管理。
1、SPI使用的四根信号线
SCLK: Serial Clock (output from master):串行时钟,用来同步数据传输,由主机输出;
MOSI SIMO: Master Output, Slave Input(output from master):主机输出从机输入数据线,通常先传输MSB;
MISO SOMI: Master Input, Slave Output(output from slave):主机输入从机输出数据线,通常先传输LSB;
SS: Slave Select (active low, output from master):片选线,低电平有效,由主机输出。
SSCS:控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(一般默认为低电位),对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。也就是说:当有多个从设备的时候,因为每个从设备上都有一个片选引脚接入到主设备机中,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低。
2、SPI的四种操作模式
SPI的四种操作模式,它们的区别是定义了在时钟脉冲的哪条边沿转换(toggles)输出信号,哪条边沿采样输入信号,还有时钟脉冲的稳定电平值(就是时钟信号无效时是高还低)。
对于STM32等MCU自带的硬件SPI外设来说,可能没有那么重要,只需要配置一下模式就行了,但是对于使用使用GPIO模拟或者FPGA来实现SPI的时序,这一点是非常非常重要的。
Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse),时钟脉冲组成了时钟信号(Clock Signal) ,每种模式由时钟信号中的时钟极性(clock polarity)CPOL与时钟周期(clock phase)CPHA来定义。
不同的从设备可能在出厂是就是配置为某种模式,这是不能改变的,但我们的通信双方必须是工作在同一模式下,所以我们可以对我们的主设备的SPI模式进行配置,从而实现主从通讯。
时钟极性CPOL是用来配置SCLK的电平出于哪种状态时是空闲态或者有效态;时钟相位CPHA是用来配置数据采样是在第几个边沿。
CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时;
CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时;
CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿;
CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿。
在高电平有效状态时,第一边沿为上升沿,第二边沿为下降沿;在低电平有效状态时,第一边沿为下降沿,第二边沿为上升沿
具体四种模式如下:
CPOL = 0,CPHA = 0:时钟高电平时为有效状态,时钟上升沿(第一个边沿)采样。
CPOL = 0,CPHA = 1:时钟高电平时为有效状态,时钟下降沿(第二个边沿)采样。
CPOL = 1,CPHA = 0:时钟低电平时为有效状态,时钟下降沿(第一个边沿)采样。
CPOL = 1,CPHA = 1:时钟低电平时为有效状态,时钟上升沿(第二个边沿)采样。
3、SPI的数据交换
参考文章,不撑了不撑了:SPI通信协议介绍
SPI可分为主、从两种模式,并且支持全双工模式,所以这也就导致STM32的SPI接口比较复杂。比如:配置SPI为主模式、配置SPI为从模式、配置SPI为单工通信、配置SPI为双工通信等等。
在每个 Clock 周期内,SPI 设备都会发送并接收一个 bit 大小的数据(不管主设备还是从设备),相当于该设备有一个 bit 大小的数据被交换了。
1)主从机的选择:
SPI 规定了两个 SPI 设备之间通信必须由主设备 (Master) 来控制次设备 (Slave)。一个 Master 设备可以通过提供 Clock 以及对 Slave 设备进行片选 (Slave Select) 来控制多个 Slave 设备,当我们的主设备和某个从设备通信时将需要将从设备对应的片选引脚电平拉低或者是拉高。SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock,没有 Clock 则 Slave 设备不能正常工作。
2)数据交换的流程:
参考文章:曾小庆:SPI通信协议详解(spi总线)
主机和从机都有一个串行移位寄存器(SSPSR) 。它的主要作用是根据 SPI 时钟信号状态,往 SSPBUF 里移入或者移出数据,每次移动的数据大小由 Bus-Width 以及 Channel-Width 所决定。Bus-Width 的作用是指定地址总线到 Master(主)设备之间数据传输的单位。Channel-Width 的作用是指定 Master(主)设备与 Slave(从)设备之间数据传输的单位。
主机通过向它的SPI串行寄存器写入一个字节来发起一次传输。串行移位寄存器通过MOSI信号线将字节传送给从机,同时从机也将自己的串行移位寄存器中的内容通过MISO信号线返回给主机。这样,两个移位寄存器中的内容就被交换。外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。
SPI的时序其实很简单,主要是在SCLK的控制下,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。
假设主机的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。那么第一个上升沿来的时候,主机将会通过MOSI信号线传输给从机最高位1,自身寄存器变成0101010x。同时,MISO信号线会从从机处返回一个数据给主机,那么这时寄存器为0101010MISO,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个SPI时序。
主机和从机的发送数据是同时完成的,两者的接收数据也是同时完成的。也就是说,当上升沿主机发送数据的时候,从机也发送了数据。所以为了保证主从机正确通信,应使得它们的SPI具有相同的时钟极性和时钟相位。
3)SPI的传输速率:
参考文章;王超:一文看懂SPI协议
SCLK的速率就是SPI的传输速率,SPI协议没有一个固定的速率,不像I2C标准模式100K,快速模式400K,高速模式3.4M,SPI的传输速率取决于器件本身支持多高的速率。最初的标准定义总线速度为100kbps。经历几次修订,主要是1995年的400kbps,1998的3.4Mbps。
4)SPI的传输的特点:
参考文章:对三种总线SPI、UART、I2C分析理解 - 接口/总线/驱动 - 电子发烧友网
SCLK时钟线存在使得数据是一位一位传输的。由SCLK提供时钟脉冲,SDI、SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCLK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCLK时钟线的控制可以完成对通讯的控制。
主从设备必须使用相同的工作参数——SCLK、CPOL 和 CPHA,才能正常工作。如果有多个从设备,并且它们使用了不同的工作参数,那么主设备必须在读写不同从设备间重新配置这些参数。
参考文章: 华清远见:史上讲得最清楚的I2C和SPI总线协议
SPI也没规定通信应答机制,没有规定流控制规则。事实上,SPI主设备甚至并不知道指定的从设备是否存在。这些通信控制都得通过SPI协议以外自行实现。例如,要用SPI连接一支命令-响应控制型 解码芯片,则必须在SPI的基础上实现更高级的通信协议。SPI并不关心物理接口的电气特性,例如信号的标准电压。在最初,大多数SPI应用都是使用间断性时钟脉冲和以字节为单位传输数据的,但现在有很多变种实现了连续性时间脉冲和任意长度的数据帧。
三、IIC
参考文章:SPI、I2C、UART、CAN_一只大笨猫的博客-CSDN博客_i2c spi
IIC(Inter-Integrated Circuit)开发于1982年,当时是为了给电视机内的CPU和外围芯片提供更简易的互联方式。电视机是最早的嵌入式系统之一,而最初的嵌入系统是使用内存映射(memory-mapped I/O)的方式来互联微控制器和外围设备的。要实现内存映射,设备必须并联入微控制器的数据线和地址线,这种方式在连接多个外设时需大量线路和额外地址解码芯片,很不方便并且成本高。为了节省微控制器的引脚和和额外的逻辑芯片,使印刷电路板更简单,成本更低,位于荷兰的Philips实验室开发了IIC ,一种只使用二根线接连所有外围芯片的总线协议。
IIC 是多主设备的总线,IIC没有物理的芯片选择信号线,没有仲裁逻辑电路,只使用serial data (SDA)数据线 和 serial clock(SCL)时钟线两条信号线,数据线用来传输数据,时钟线用来同步数据收发。两根信号线都是双向传输的,这两条线都是漏极开路或者集电极开路结构,使用时需要外加上拉电阻,可以挂载多个设备。
1、IIC的传输流程
参考文章:Kevin Zhang:硬件知识——IIC传输
IIC协议标准规定发起通信的设备称为主设备,主设备发起一次通信后,其它设备均为从设备。
1)IIC 通信过程大致如下
首先,主设备发一个START信号。然后其它设备开始监听总线以准备接收数据。当START起始信号产生后,I2C总线就处于被占用的状态,当停止信号产生后,总线就处于空闲状态。
接着,主设备发送一个8位的数据帧(IIC规定数据帧大小必须为8位的字节),包括7位设备地址数据帧(每一个IIC设备都有一个唯一的七位设备地址)和 1位的读写操作的数据帧(读/写位用于确定主设备是向从设备发送数据还是主设备从从设备接受数据,0代表写,1代表读)。
当所有设备接收到数据后,比对地址自己是否为目标设备。如果比对不符,设备进入等待状态,等待STOP信号的来临;如果比对相符,该设备会发送一个应答信号ACKNOWLEDGE作回应。这时主设备就和该从设备建立了连接。
当主设备收到应答后便开始传送或接收数据。数据帧大小为8位,尾随一位的应答信号。主设备发送数据,从设备应答;相反主设备接收数据,主设备应答。
当数据传送完毕,主设备发送一个STOP信号,向其它设备宣告释放总线,其它设备回到初始状态。
2)两条数据线在各个通讯过程中高低电平的状态
参考文章:Serendipity:Linux驱动篇(七)——I2C(一)
空闲时SDA和SCL被拉高,处于高电平的位置。连到IIC总线上的任一设备输出低电平都会把总线信号拉低,即各器件的SDA和SCL都是与的关系。根据这两条线的高低电平、上升沿、下降沿就可以实现主机与I2C设备的通讯。
开始与结束:当SCL保持高电平期间,SDA从高电平跳变到低电平,即为开始条件START。当SCL保持高电平期间,SDA从低电平跳变到高电平,即为结束条件STOP。
传输:IIC总线标准规定SDA线的数据转换必须在SCL线的低电平期。在SCL线的高电平期,SDA线的上数据是稳定不变的。数据传输时先传数据位。
主设备在SCL线上产生每个时钟脉冲的过程中将在SDA线上传输一个数据位,当一个字节按数据位从高位到低位的顺序传输完后,紧接着,从设备在每个字节后的第9个时钟周期将SDA保持低电平进行确认数据,回传给主设备一个ACK,此时才认为一个字节真正的被传输完成。
当然,并不是所有的字节传输都必须有一个ACK,比如:当从设备不能再接收主设备发送的数据时,从设备将回传一个否定ACK,SDA线为高表示否定ACK。
应答:当IIC主机(不一定是发送端还是接受端)将8位数据或命令传出后,会将SDA信号设置为输入,等待从机应答(等待SDA由高电平拉为低电平)。若从机正确应答,表明数据或者命令传输成功,否则传输失败,注意,应答信号是数据接收方发送给数据发送方的。
3、IIC的一些拓展知识
参考文章:华清远见:史上讲得最清楚的I2C和SPI总线协议
1)10位设备地址
任何IIC设备都有一个7位地址,理论上,现实中只能有127种不同的IIC设备。实际上,已有IIC的设备种类远远多于这个限制,在一条总线上出现相同的地址的IIC设备的概率相当高。为了突破这个限制,很多设备使用了双重地址——7位地址加引脚地址(external configuration pins)。IIC 标准也预知了这种限制,提出10位的地址方案。
2)设备冲突的解决办法
如果有两个设备同时向SCL线和SDA线发送信息,基于IIC总线的设计,线路上不可能出现电平冲突现象。如果一支设备发送逻辑0,其它发送逻辑1,那么线路看到的只有逻辑0。也就是说,如果出现电平冲突,发送逻辑0的始终是“赢家”。
总线的物理结构亦允许主设备在往总线写数据的同时读取数据。这样,任何设备都可以检测冲突的发生。当两支主设备竞争总线的时候,“赢家”并不知道竞争的发生,只有“输家”发现了冲突——当它写一个逻辑1,却读到0时——而退出竞争。
3)IIC的传输速率
IIC 数据传输速率有标准模式(100 kbps)、快速模式(400 kbps)和高速模式(3.4 Mbps),另外一些变种实现了低速模式(10 kbps)和快速+模式(1 Mbps)。
四、三种通讯方式的特点与区别:
同步通讯:I2C,SPI 异步通讯:UART
采集数据是否用的是时钟的沿,如果是时钟沿采数据,同步传输,如果电平采集数据是异步。串口接受数据其实就是一个串转并的过程。
SPI和UART可以实现全双工,但I2C不行
IIC 和 SPI 这两种通信协议非常适合近距离低速芯片间通信。通信方式都是短距离的,芯片和芯片之间或者其他元器件如传感器和芯片之间的通信。SPI和IIC是板上通信,IIC有时也会做板间通信,不过距离甚短,不过超过一米,例如一些触摸屏,手机液晶屏那些薄膜排线很多用IIC,IIC能用于替代标准的并行总线,能连接的各种集成电路和功能模块。
I2C是多主控总线,所以任何一个设备都能像主控器一样工作,并控制总线。总线上每一个设备都有一个独一无二的地址,根据设备它们自己的能力,它们可以作为发射器或接收器工作。多路微控制器能在同一个I2C总线上共存这两种线属于低速传输。
编辑:黄飞
评论
查看更多