串口通信协议 UART+I2C+SPI

2023-05-16

UART【异步 串行 全双工】
I2C
SPI

不同通信协议比较

UART

UART协议详解
UART通信,接收与发送(详细版,附代码)

※※UART串行通信详解※※
待整理

UART是Universal Asynchronous Receiver/Transmitter通用异步收发传输器,使用RxD和TxD两根线实现【异步 串行 全双工】通信;为确保通信可靠,可以在通信两边接共地;因此,完整的UART通信只需最少3根线即可。

RxD是发送数据线,TxD是接收数据线,通信双方使用交叉互联,RxD接对方TxD,TxD接对方RxD。UART使用标准的TTL/CMOS电平(0-5V,0-3.3V,0-2.5V,0-1.8V)来表示数据,高电平表示1,低电平表示0.为了增强抗干扰能力,提高传输长度,可将TTL/CMOS 电平转换为RS232电平逻辑电平,3-12V表示0,-3~-12V表示1(RS232为负逻辑电平)

TTL电路的工作电压为5V
对于输出电路:电压大于等于(≥)2.4V为逻辑1;电压小于等于(≤)0.4V为逻辑0;
对于输入电路:电压大于等于(≥)2.0V为逻辑1;电压小于等于(≤)0.8V为逻辑0;

1)UART平时处于空闲状态(逻辑1状态)。

2)当有数据发送时,先发送起始位,即将TxD拉低并维持1位时间,接收方在检测到起始位下降沿,等待1.5位后开始一位一位检测数据。

3)发送数据,UART数据一帧可以是5,6,7,8位等,一般是8bit,一个字节。数据发送是先发送低位,依次发送,直到最高位。

4)【可选】可以使用0或者1bit的校验位,校验位可以是奇校验或者偶检验。数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验)

5)停止位,数据线恢复到空闲状态,停止位可以是1、1.5、2位高电平
【由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供 计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。】

在接收过程中,UART从消息帧中去掉起始位和结束位,对进来的字节进行奇偶校验,并将数据字节从串行转换成并行。UART也产生额外的信号来指示发送和接收的状态。例如,如果产生一个奇偶错误,UART就置位奇偶标志。

在这里插入图片描述
1位时间由波特率决定,在UART通信中,波特率(一秒钟传输的符号数)等于比特率(一秒钟传输的字符数),通信双方使用约定的一致的波特率进行通信,常见的波特率有4800,9600,115200等。
  波特率:是衡量资料传送速率的指标。表示每秒钟传送的二进制位数。例如资料传送速率为120字符/秒,而每一个字符为10位,则其传送的波特率为10×120=1200位/秒=1200波特。

全双工:三根线:理论上至少需要3根——TXD、RXD、GND。

UART指协议【类似于通信网络中的数据链路层】它实际只定义了数据链路层的规范,
也就是起始位、数据位、停止位。

而最底层的物理层则是RS232、RS499、RS423、RS422和RS485等【类似于网络通信中的物理层,与通信协议没有直接关系】
【更多的是规定电气特性和各个引脚的功能定义】
对应各种异步串行通信口的接口标准和总线标准,它规定了通信口的电气特性、
传输速率、连接特性和接口的机械特性等内容。

TTL串口:它是MCU芯片之间进行数据通信的串口,它以+5V(或者+3.3V)表示1,以GND表示0。 
是一般芯片的串口的输入和输出端,可以接不通的芯片完成不通的外设功能。
输出电路:电压大于等于(≥)2.4V为逻辑1;电压小于等于(≤)0.4V为逻辑0;
输入电路:电压大于等于(≥)2.0V为逻辑1;电压小于等于(≤)0.8V为逻辑0;

RS232串口:它是实现设备之间通信的串口,其主要将信号电压从05V的电压变为±15V(实际一般为±12V)。电压的增加,增大了数据传输的距离和可靠性。 
  RS232电平:使用315v有效电平
  采用负逻辑电平,即-15V ~ -3V代表逻辑"1"+3V ~ +15V代表逻辑"0"。这里的电平,是TxD线(或者RxD线)相对于 GND 的电压。
   接口有标准的DB9插头,台式电脑一般都有这个插头。




RS485串口:它是实现远距离通信的串口,可以实现上千米的数据传输。其主要特征是用差模信号(A、B两根线之间的电压)代替了RS232共模信号(信号线和GND之间的电压),从而能够抵抗共模干扰,实现更远距离的传。
>③RS485:
 【差分线】,术语叫A,B,通过双绞线连接。
	    →→能够抵抗共模干扰,实现更远距离的传。【实现上千米的数据传输】
	    →→没有独立的Tx/Rx→→半双工(可以双向,但同时只能单向)
	               硬件上通过方向切换来保证数据收发的不冲突。
 既然是差分线,那“1”,“0”就要通过差来得到了。
 发送驱动器A、B之间的正电平在+2~+6V,是一个逻辑状态,负电平在-2V~6V,是另一个逻辑状态。另有一个信号地C,
 解决RS232不能联网的问题
>③RS422: 也是差分 2对差分信号线ab+xy →全双工   而485只有一对差分信号线→半双工

具体实物表现为独立的模块化芯片,或作为集成于微处理器中的周边设备。在开发板设计和测试阶段被用来控制CPU与其余部分的信息传送。

COM口是指针对串行通信协议的一种端口,是PC上异步串行通信口的简写,大部分为9针孔D型。COM口里分RS232,RS422和RS485,传输功能依次递增。所以,RS485口也是9针孔D型。由于历史原因,IBM的PC外部接口配置为RS232,成为实际上的PC界默认标准。所以,现在PC机的COM口均为RS232。若配有多个异步串行通信口,则分别称为COM1、COM2…
 RS232或者RS485,是指通信协议传输方式的类别之一,采用这类通信方式的,可以有多种协议,包括串行通信,现场总线方式等像完成某个通信处理的,首先会问通信协议是什么,比如回答为串口,现场总线,以太网等;然后会确定该协议下的通信端口类型,比如回答:USB口,RS232,RS422,RS485。

总的来说,对于一项通信任务,通信协议可以使用UART协议,而UART协议可以通过COM端口来实现硬件连线,此协议下的传输方式可以选用RS232或者RS485等。
 PS:注意使用电脑上的串口与微处理器通信时,首先要经过转压芯片(例如MAX232)来实现电平转化。

COM口和RS232
COM口是指针对串行通信协议的一种端口,是PC上异步串行通信口的简写,大部分为9针孔D型。COM口里分RS232,RS422和RS485,传输功能依次递增。由于历史原因,IBM的PC外部接口配置为RS232,成为实际上的PC界默认标准。所以,现在PC机的COM口均为RS232。若配有多个异步串行通信口,则分别称为COM1、COM2…

I2C

当今全球有3种IIC总线,即飞利浦总线、ITT总线及索尼总线。
这3种IIC总线的数据传送格式不太一样。家电产品中应用最多的是飞利浦总线,
ITT总线使用较少,索尼总线几乎没有用于家电产品中。

https://tech.hqew.com/news_1051684
IIC总线的引出方式可分为3种,即单种单组方式、单种多组方式和多种多组方式。

康佳T2988P彩电的IIC总线系统示意图。它属于单种单组方式,
因为CPU上只存在飞利浦总线,且引出的组数只有一组,
因此所有的被控器全部挂在这组总线上。
在这里插入图片描述
下图为黄河HC2188彩电的IIC总线系统示意图。它属于单种多组方式,CPU上只存在飞利浦总线,引出的组数为两组:一组与存储器D902相连;另一组与小信号处理器N201相连。目前,绝大多数国产小屏幕数码彩电都使用这种方式。
在这里插入图片描述

下图为东芝32DW5UXE彩电IIC总线系统示意图。它属于多种多组方式,CPU上共引出3组总线。其中,(11)脚和(12)脚引出的总线属于飞利浦总线,用来挂接存储器;(37)脚和(38)脚引出的总线也属于飞利浦总线,用来挂接主调谐器/副调谐器、小信号处理器等电路;(40)脚和(41)脚引出的总线属于ITT总线(ITT总线上一般标有“ITT”字样),挂有主中频组件和PIP中频组件,整机由这3组总线进行控制。
在这里插入图片描述
 国产彩电大都使用前两种形式,也有少数机型使用第3种形式,例如:我国长虹NC-6机芯就使用第3种形式。但无论哪种形式,在IIC总线的引出端或引入端都标有SCL和SDA字样(少数机型标成CLK和DATA或IIC字样)。因此我们只需从CPU上或被控器上找到SCL和SDA端子,即可找到IIC总线。

Inter-Integrated Circuit(集成电路总线)

I2C总线图解http://blog.csdn.net/w89436838/article/details/38660631
I2C总线详解https://www.cnblogs.com/BitArt/archive/2013/05/27/3101037.html

1 I2C总线物理拓扑结构

在这里插入图片描述
I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成。通信原理是通过对SCL和SDA线高低电平时序的控制,来产生I2C总线协议所需要的信号进行数据的传递。

①操作简单:是否把线路接地(在物理实现上,SCL线和SDA线都是漏极开路(open-drain),通过上拉电阻外加一个电压源。当把线路接地时,线路为逻辑0,当释放线路,线路空闲时,线路为逻辑1。)

②结构简单:只有2根线SCL+SDA

基于IIC总线的设计,线路上不可能出现电平冲突现象。
  当多个设备同时向I2C数据线写入数据时,如果一支设备发送逻辑0,其它发送逻辑1,那么线路看到的只有逻辑0。也就是说,如果出现电平冲突,发送逻辑0的始终是“赢家”。总线的物理结构亦允许主设备在往总线写数据的同时读取数据。这样,任何设备都可以检测冲突的发生。当两支主设备竞争总线的时候,“赢家”并不知道竞争的发生,只有“输家”发现了冲突——当它写一个逻辑1,却读到0时——而退出竞争。

地址长度:
  10位设备地址任何IIC设备都有一个7位地址,理论上,现实中只能有127种不同的IIC设备。实际上,已有IIC的设备种类远远多于这个限制,在一条总线上出现相同的地址的IIC设备的概率相当高。为了突破这个限制,很多设备使用了双重地址——7位地址加引脚地址(external configuration pins)。IIC 标准也预知了这种限制,提出10位的地址方案。10位的地址方案对 IIC协议的影响有两点:
第一,地址帧为两个字节长,原来的是一个字节;
第二,第一个字节前五位最高有效位用作10位地址标识,约定是“11110”。

传输(速度)模式:
普通模式:100kHz;
快速模式:400kHz;
高速模式:3.4MHz;

没有任何必要使用高速SCL,将SCL保持在100k或以下,然后忘了它吧。

2 I2C总线特征

I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址(总线上每个设备都有自己的一个addr,共7个bit,广播地址全0. 系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。
  地址通过物理接地或者拉高,可以从I2C器件的数据手册得知,如TVP5158芯片,7位地址依次bit6~bit0:x101 1xxx, 最低三位可配,如果全部物理接地,则该设备地址为0x58, 而之所以7bit因为1个bit要代表方向,主向从和从向主),主从设备之间就通过这个地址来确定与哪个器件进行通信,在通常的应用中,我们把CPU带I2C总线接口的模块作为主设备,把挂接在总线上的其他设备都作为从设备。
  I2C总线上可挂接的设备数量受总线的最大电容400pF 限制,如果所挂接的是相同型号的器件,则还受器件地址位的限制。
  一般通过I2C总线接口可编程时钟来实现传输速率的调整,同时也跟所接的上拉电阻的阻值有关。I2C最大的从机数量受从机地址和最大总线电容400pF电容的限制。
  I2C总线上的主设备与从设备之间以字节(8位,从高位到地位的顺序)为单位进行双向的数据传输。

I2C协议流程

I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生

在起始条件产生后,总线处于忙状态,由本次数据传输的主从设备独占,其他I2C器件无法访问总线;而在停止条件产生后,本次数据传输的主从设备将释放总线,总线再次处于空闲状态。起始和结束如图所示:
在这里插入图片描述

I2C的数据帧格式如下:
开始位S | 7bit从机地址 | 1bit读写方向位(0写,1读) | 1bit应答 |
8bit数据1 | 1bit应答1|

8bit数据N |1bit非应答N |
停止位P

I2C总线上的每一个设备都对应一个唯一的地址,主从设备之间的数据传输是建立在地址的基础上,也就是说,主设备在传输有效数据之前要先指定从设备的地址,地址指定的过程和上面数据传输的过程一样,只不过大多数从设备的地址是7位的,然后协议规定再给地址添加一个最低位用来表示接下来数据传输的方向,0表示主设备向从设备写数据,1表示主设备向从设备读数据。向指定设备发送数据的格式如图所示:(每一最小包数据由9bit组成,8bit内容+1bit ACK, 如果是地址数据,则8bit包含1bit方向)

下图是完整的一帧I2C数据:

4 I2C总线操作
对I2C总线的操作实际就是主从设备之间的读写操作。大致可分为以下三种操作情况:

主设备往从设备中写数据。数据传输格式如下:
在这里插入图片描述
主设备从从设备中读数据。数据传输格式如下:
在这里插入图片描述
主设备往从设备中写数据,然后重启起始条件,紧接着从从设备中读取数据;
或者是主设备从从设备中读数据,然后重启起始条件,紧接着主设备往从设备中写数据。数据传输格式如下:
在这里插入图片描述


空闲时,SCL,SDA同时处于高电平。此时,各器件的输出场效应管处于截止状态,
释放总线,总线信号由上拉电阻上拉至高电平。

SDA数据线:
{
	发生变化
	{
		于SCL=0时发生变化 发送者写入数据
		于SCL=1时发生变化 主设备发送开始S/结束P信号(故写入数据只能在SCL=0时进行)
	}
	
	于SCL ↑ 上升沿时 接收者进行数据采样
	
	数据传输时要求SDA于SCL=1时能够稳定(不然会被视为S/P信号)
	数据传输:数据传输以字节为单位,第一个字节表示从机地址+读写方向,后续数据格式由器件自己定义。
	
	物理结构决定了闲置时SDA=1
	ACK机制:接收者在第9个时钟周期发送ACK(SDA=0)信号 表示我接收到了
			反之,发送NACK(SDA=1)信号 →引起主控发生RESTART或STOP流程
}



开始信号S:SCL为高电平时,SDA ↓ 由高电平向低电平跳变,开始传送数据。
结束信号P:SCL为高电平时,SDA ↑ 由低电平向高电平跳变,结束传送数据。
[S和P信号是一种电平跳边时序信号(边沿),而不是一个电平信号]

I2C位传输
	数据传输:SCL为高电平时,SDA线必须保持稳定(如果发生变化则会被视为S或者P信号)
	数据改变:SCL为低电平时,SDA线才能改变电平
	数据采样:SCL在上升沿进行数据采样

I2C应答信号
	发送器每发送完8bit数据(数据位按从高位到地位的顺序发送)后等待接收者发送ACK
	(有效应答位=0,还要确保在该时钟高电平期间是稳定的低电平,说明这不是最后一个字节)。

控制权:
  ①前8个时钟周期发送器控制SDA用于发送数据
  ②第9个时钟周期,SDA的控制交给接收者(用于发送ACK)

即在第9个clock,若接收者发回ACK(表示我收到了),SDA会被拉低。(若接收失败则SDA→非应答位NACK=1)
若没有ACK【即NACK,SDA被置高】,这会引起主控发生RESTART或STOP流程

没有ACK信号的3种情况:
	1没有去相应(忙于其他事而没有去相应IIC总线 / 这个地址没有对应的从机)
	2接收者没法接受更多的数据时
	3接收到最后一个字节时

时钟拉伸

在 IIC 通信中,主设备决定了时钟速度。因为时钟脉冲信号是由主设备显式发出的。但是,当从设备没办法跟上主设备的速度时,从设备需要一种机制来请求主设备慢一点。这种机制称为时钟拉伸,而基于I2C结构的特殊性,这种机制得到实现。当从设备需要降低传输的速度的时候,它可以按下时钟线,逼迫主设备进入等待状态,直到从设备释放时钟线,通信才继续。

高速模式

高速模式原理上讲,使用上拉电阻来设置逻辑1会限制总线的最大传输速度。而速度是限制总线应用的因素之一。这也说明为什么要引入高速模式(3.4 Mbps)。在发起一次高速模式传输前,主设备必须先在低速的模式下(例如快速模式)发出特定的“High Speed Master”信号。为缩短信号的周期和提高总线速度,高速模式必须使用额外的I/O缓冲区。另外,总线仲裁在高速模式下可屏蔽掉。更多的信息请参与总线标准文档。

协调握手

握手机制:I2C提供握手机制,当主机速度太快而从机无法满足快速通信时,从机可以拉低SCL来与主机握手,从而延长SCL低电平的时间。(SCL高电平由所有器件发出最短的高电平决定,低电平则有低电平最长的决定)。

仲裁:SDA是线与逻辑,因此,只要有一端输出低,总线就为低电平,因此是低电平优先仲裁。仲裁规则是发送低电平个数多的主机获得总线权。(没有仲裁逻辑电路,但是有仲裁机制?)

写和读的具体工作过程

(dummy过程)
下面是是I2C的读写流程:

写寄存器的标准流程为:

  1. Master发起START
  2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
  3. Slave发送ACK
  4. Master发送reg addr(8bit),等待ACK
  5. Slave发送ACK
  6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
  7. Slave发送ACK
  8. 第6步和第7步可以重复多次,即顺序写多个寄存器
  9. Master发起STOP

读寄存器的标准流程为:
[读的过程比较复杂,在从slave读出数据前,你必须先要告诉它哪个内部寄存器是你想要读取的,因此必须先对其进行写入(dummy write):]

  1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
  2. Slave发送ACK
  3. Master发送reg addr(8bit),等待ACK
  4. Slave发送ACK
  5. Master发起RESTART
  6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
  7. Slave发送ACK
  8. Slave发送data(8bit),即寄存器里的值
  9. Master发送ACK(当读取了最后一个字节数据后MASTER不会发送ACK)
  10. 第8步和第9步可以重复多次,即顺序读多个寄存器
    在这里插入图片描述
    (重启机制RS要比用终止P+再次开启S更有效率。)

SPI 串行外设接口(Serial Peripheral Interface)

SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;
提供频率可编程时钟;发送结束 中断标志;写冲突保护;总线竞争保护等

由于主设备的SDO连接从设备的SDI,从设备的SDO连接主设备的SDI
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
SPI 主设备 【时钟极性】的配置 应该和 从设备SDI的【极性】相反,
【【主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据。因此主设备这边SPI时钟极性应该配置为下降沿有效。】】
从设备决定主设备【根据从设备模式→设定主设备模式】
从设备模式:
  ①固定的CPOL和CPHA---查阅datasheet  
  ②可配置,有软件自己决定
4. 优缺点
SPI接口具有如下优点:
1) 支持全双工操作;
2) 操作简单;
3) 数据传输速率较高。

同时,它也具有如下缺点:
1) 需要占用主机较多的口线(每个从机都需要一根片选线);
2) 只支持单个主机。

SPI,是Serial Peripheral interface的缩写,顾名思义就是【串行外围设备接口】。是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。
在这里插入图片描述

SPI是同步全双工串行通信协议。SPI定义了4根信号线:
 ①SCK:时钟线,主机提供Serial Clock (output from master);
 ②MISO:主入从出(output from slave);
 ③MOSI:主出从入(output from master);
多个从设备的3条信号线并联至SPI总线上→→所有从设备,都共同只使用这3 条总线
 ④SS:片选,Slave Select (active low, outputfrom master) or CS or NSS.
   每个从设备都有一条CS 信号线,对应独占主机的一个引脚
   多少个从设备,就有多少条片选信号线
   当只有一个从设备时不需要片选→因此通信最少需要3根信号线。

寻找从设备的方式的差异:
  ①I2C 协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯;
  
  ②SPI 协议中没有设备地址,它使用CS 信号线来寻址【将需要选择的从设备的CS信号线设置为低电平—即片选有效—选中从设备】
  
故SPI的开始信号是:将某一条片选信号置低电平
    结束信号:将该片选信号线拉高

SPI是[单主设备( single-master )]通信协议,这意味着总线中的只有一支中心设备能发起通信。当SPI主设备想读/写[从设备]时,它首先拉低[从设备]对应的SS线(SS是低电平有效),接着开始发送工作脉冲到时钟线上,在相应的脉冲时间上,[主设备]把信号发到MOSI实现“写”,同时可对MISO采样而实现“读”。

2、 SPI特点
2.1采用主-从模式(Master-Slave) 的控制方式
两个 SPI 设备之间通信必须由主设备 (Master) 来控制从设备 (Slave).
一个 Master 设备可以通过提供 Clock 以及对 Slave 设备进行片选 (Slave Select) 来控制多个 Slave 设备,

SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作

2.2采用同步方式(Synchronous)传输数据
Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse), 时钟脉冲组成了时钟信号(Clock Signal) , 时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样, 来保证数据在两个设备之间是同步传输的.

2.3数据交换(Data Exchanges)
SPI 设备间的数据传输之所以又被称为数据交换,
在SPI中一个设备既是"发送者(Transmitter)",同时也是 “接收者(Receiver)”
  SPI只有主模式和从模式之分。没有读和写的说法,因为实质上每次SPI是主从设备在交换数据。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。
  在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据(不管主设备还是从设备), 相当于两个设备的一个 bit 大小的数据被交换了.

交换1bit数据后要紧接着去读取,不然会被后面的交换数据覆盖而丢失:
  在数据传输的过程中, 每次接收到的数据必须在下一次数据传输之前被采样. 如果之前接收到的数据没有被读取, 那么这些已经接收完成的数据将有可能会被丢弃, 导致 SPI 物理模块最终失效. 因此, 在程序中一般都会在 SPI 传输完数据后, 去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的(虽然发送后紧接着的读取是无意义的,但仍然需要从寄存器中读出来)。

2.4 SPI有四种传输模式
上升沿、下降沿、前沿、后沿触发。当然也有MSB和LSB传输方式.(数据传输时, MSB 先行或LSB 先行并没有作硬性规定,但要保证两个SPI 通讯设备之间使用同样的协定,一般都会采用MSB 先行模式。)
SPI有四种操作模式——模式0、模式1、模式2和模式3,它们的区别是定义了在时钟脉冲的哪条边沿转换(toggles)输出信号,哪条边沿采样输入信号,还有时钟脉冲的稳定电平值(就是时钟信号无效时是高还是低)。每种模式由一对参数刻画,它们称为时钟极(clock polarity)CPOL与时钟期(clock phase)CPHA。

时钟极性CPOL:   Clock Polarity时钟极性
 0:空闲时SCK为0,1:空闲时SCK为1.
时钟相位CPHA:即CHOH    Clock Phase
 0:数据在第一个时钟跳沿采样捕获【另一个跳边沿上传数据】
 1:数据在第二个时钟跳沿采样捕获【另一个跳边沿上传数据】
比如CPHA=0时(变成忙的跳变):
  当时钟极性为0时,取上升沿(变成忙的跳变)采样;
  当时钟极性为1时,取下降沿(变成忙的跳变)采样
比如CPHA=1时(回归空闲跳变):
  当时钟极性为0时,取下降沿(回归空闲跳变)采样;
  当时钟极性为1时,取上升沿(回归空闲跳变)采样
 

下图的时间左侧早右侧晚
在这里插入图片描述
在这里插入图片描述
下图时间右侧造左侧晚:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
[主从设备]必须使用相同的工作参数——SCLK、CPOL 和 CPHA,才能正常工作。如果有多个[从设备],并且它们使用了不同的工作参数,那么[主设备]必须在读写不同[从设备]间重新配置这些参数。

SPI不规定最大传输速率,没有地址方案;SPI也没规定通信应答机制,没有规定流控制规则。事实上,SPI[主设备]甚至并不知道指定的[从设备]是否存在。这些通信控制都得通过SPI协议以外自行实现。例如,要用SPI连接一支[命令-响应控制型]解码芯片,则必须在SPI的基础上实现更高级的通信协议。SPI并不关心物理接口的电气特性,例如信号的标准电压。在最初,大多数SPI应用都是使用间断性时钟脉冲和以字节为单位传输数据的,但现在有很多变种实现了连续性时间脉冲和任意长度的数据帧。

3、 工作机制

https://www.cnblogs.com/aaronLinux/p/6219146.html
及同分组博客
在这里插入图片描述
SPI在时钟上升沿下进行双向数据交换,主机在输出的同时,也会接收到从机的数据。在设计上,主机从机均需要一个移位寄存器。SPI不区分读写方向,只进行数据交换,要读也必须写,才能将数据交换过来。

主机和从机都有一个串行移位寄存器,主机通过向它的SPI 串行寄存器写入一个字节来发起一次传输。寄存器通过MOSI 信号线将字节传送给从机,从机也将自己的移位寄存器中的内容通过MISO 信号线返回给主机。这样,两个移位寄存器中的内容就被交换。外设的写操作和读操作是同步完成的。如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的传输。

在一个SPI时钟周期内,会完成如下操作:

  1. 主机通过MOSI线发送1位数据,从机通过该线读取这1位数据;
  2. 从机通过MISO线发送1位数据,主机通过该线读取这1位数据。
    这是通过移位寄存器来实现的。如图2所示,主机和从机各有一个移位寄存器,且二者连接成环。随着时钟脉冲,数据按照从高位到低位的方式依次移出主机寄存器和从机寄存器,并且依次移入从机寄存器和主机寄存器。当寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。
    在这里插入图片描述

不同串口通信协议比较

①总线拓扑结构/信号路由/硬件资源耗费:【IIC优势】
  IIC 只需两根信号线【有限的7位地址空间–用10位地址】
  标准SPI至少四根信号,如果有多个从设备,信号需要更多。一些SPI变种虽然只使用三根线——SCLK, SS和双向的MISO/MOSI,但SS线还是要和从设备一对一根。另外,如果SPI要实现多主设备结构,总线系统需额外的逻辑和线路。
  
②数据吞吐/传输速度
  如果应用中必须使用高速数据传输,那么SPI是必然的选择。因为SPI是全双工,IIC 半双工。SPI没有定义速度限制,一般的实现通常能达到甚至超过10 Mbps。IIC 最高的速度也就(100Kbps 400Kbps 3.4 Mbps),后面的模式还需要额外的I/O缓冲区,还并不是总是容易实现的。

③特色:
  IIC:用很轻盈的架构实现了多主设备仲裁和设备路由。但是对使用的工程师来讲,理解总线结构更费劲,而且总线的性能不高。
  SPI的优点在于它的结构相当的直观简单,容易实现,并且有很好扩展性。但是SPI需要搭建一个有用的通信平台,还需要在SPI之上构建特定的通信协议软件。也就是说要想获得SPI特有而IIC没有的特性——高速性能,工程师们需要付出更多的劳动。另外,这种自定的工作是完全自由的,这也说明为什么SPI没有官方标准。
  IIC和SPI都对低速设备通信提供了很好的支持,不过,SPI适合数据流应用,而IIC更适合“字节设备”的多主设备应用

(1)SPI 主要特点有: 可以同时发出和接收串行数据; 可以当作主机或从机工作; 提供频率可编程时钟; 发送结束中断标志; 写冲突保护; 总线竞争保护等。
(2)与I2C 总线相比它的缺点是:没有指定的流控制,没有应答机制确认是否接收到数据。

I2C通信方式为半双工(支持双向,但不支持同时双向)485也为半双工
SPI和uart为全双工(支持同时双向传输)。

小结在数字通信协议簇中,IIC和SPI常称为“小”协议,相对Ethernet, USB, SATA, PCI-Express等传输速度达数百上千兆字节每秒的总线。但是,我们不能忘记的是各种总线的用途是什么。“大”协议是用于系统外的整个系统之间通信的,“小”协议是用于系统内各芯片间的通信,没有迹象表明“大”协议有必要取代“小”协议。IIC和SPI的存在和流行体现了“够用就好”的哲学。回应文首,IIC和SPI如此的流行,它是任何一位嵌入式工程师必备的工具。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

串口通信协议 UART+I2C+SPI 的相关文章

  • Raspberry Pi 与Arduino SPI通信

    本教程介绍了使用SPI 串行外围设备接口总线 进行Raspberry Pi与Arduino通讯和控制的基本框架 SPI代表了一种非常完善的芯片间通信方法 该方法在两种设备的硬件中均实现 在这里 我们将详细探讨SPI 讨论硬件和软件注意事项
  • GD32E23x的USART被断点打断后重新运行,会一直进入中断的问题

    GD32E23x的USART被断点打断后重新运行 会一直进入中断的问题 GD32E230K8单片机USART0连接一个从机芯片 该芯片每100ms发来一串16Bytes的数据 MCU中断接收 没有开启FIFO 只开启了RBNE 接收缓存非空
  • 【总线】I2C 通信协议

    目录 I2C 总线协议概述 参数总结 I2C 的工作原理 寻址 读 写位 数据帧 I2C数据传输的步骤 具有多个从机的单个主机 具有多个从机的多个主机 I2C的优缺点 优点 缺点 文章参考 I2C 总线协议概述 I2C 总线广泛应用在 OL
  • ESP32-C3入门教程 基础篇(三、UART模块 — 与Enocean无线模块串口通信)

    测试第三课 ESP32 C3的串口通信测试 老样子 使用Enocean无线模块和ESP32 C3进行串口通信 目录 前言 1 UART示例测试 1 1 UART 基础测试 1 2 与Enocean无线模块串口通信测试 2 ESP32 C3
  • Java SPI机制

    一 SPI机制简介 SPI的全名为Service Provider Interface java spi机制的思想 系统里抽象的各个模块 往往有很多不同的实现方案 在面向的对象的设计里 一般推荐模块之间基于接口编程 模块之间不对实现类进行硬
  • Spring Factories

    该文章转载自 https blog csdn net lvoyee article details 82017057 Spring Boot中有一种非常解耦的扩展机制 Spring Factories 这种扩展机制实际上是仿照Java中的S
  • 难懂?这样理解SPI与CAN很简单!

    难懂 这样理解SPI与CAN很简单 什么是串行通讯 为什么仍需使用串行通讯 SPI与CAN SPI 接口特点 CAN现场总线特点 什么是串行通讯 在正式进入主题前 我么先来介绍一下什么叫做 串行通信 串行通信是计算机的一种数据传输通信方式
  • SD卡系列之---SD初始化(SPI)

    SD卡分为SDIO模式与SPI模式 SDIO模式使用SD总线协议 使用4根数据线进行数据传输 SPI使用1收1发2根数据线数据传输 理论上SDIO模式会比SPI模式速度快4倍 但SDIO模式还牵扯到CRC校验位的计算 所以 如果使用CPU有
  • Linux,spidev:为什么它不应该直接在设备树中?

    我想定义一个具有用户模式访问权限的 SPI 设备 如中所述http linux sunxi org SPIdev 按照这些示例 我在设备树中添加了以下内容 ecspi1 other stuff mydev 0 compatible spid
  • Linux:从用户空间实例化:eeprom new_device

    环境 x86 Ubuntu 14 04 我想获得类似的东西 i2c0 eeprom eeprom 50 compatible at 24c32 reg lt 0x50 gt 但因为在 x86 中没有可用的设备树 所以我遵循i2c insta
  • Android Things:连接到串行调试控制台

    我一直在尝试连接到串行控制台树莓派 3 with 安卓事物 using USB to TTL cable从我的Linux Ubuntu 机器 尽管我按照文档连接了电缆 但执行时我得到的只是minicom命令如下 with 没有机会输入任何字
  • 以字符串形式接收数字(uart)

    我正在尝试通过 uart 接收一个包装为字符串的数字 我发送数字 1000 所以我得到 4 个字节 空字符 但是 当我使用 atoi 将数组转换为数字并将整数与 1000 进行比较时 我并不总是得到正确的数字 这是我用于接收号码的中断处理函
  • IOError:[Errno 2]没有这样的文件或目录(当它确实存在时)Python [重复]

    这个问题在这里已经有答案了 我正在通过 python 中的 uart 传输文件文件夹 下面您可以看到简单的功能 但有一个问题 因为我收到如标题所示的错误 IOError Errno 2 No such file or directory 1
  • SPI 电子墨水显示屏与 PIC 18F46K22 连接时出现问题

    我正在使用一个图18F46K22 https ww1 microchip com downloads en DeviceDoc 40001412G pdf在 SPI 主模式下与Waveshare 1 54 电子纸模组 https www w
  • ADXL345 与 ESP32 I2C 垃圾值问题

    我已根据以下教程使用 I2C 接口将 ESP32 与 ADXL345 连接起来Tutorial http www esp32learning com code esp32 and adxl345 sensor example php 但是
  • 树莓派 pico rfid rc522 (Micropython)

    我想使用 RPi Pico 从 mfrc522 Iduino RFID rc522 读卡器读取数据 但我不知道如何操作 我试图使用为此目的制作的 mfrc522 py MicroPython 库 阅读器正在通过 SPI 与 Pi 通信 我将
  • C语言UART通信(十六进制)

    我想向写入函数发送一个十六进制值 例如 0 90 这是因为需要通信的设备接收到的是十六进制数的命令 未使用的变量在测试时出现 并注释为丢失十六进制值 稍后将被删除 如何编写具有字符串以外的十六进制值的写入函数 对于初学者 请告诉我们如何通过
  • 跨线程操作无效:从创建它的线程以外的线程访问控制“textBox1”[重复]

    这个问题在这里已经有答案了 我想使用 UART 将温度值从微控制器发送到 C 接口并显示温度Label Content 这是我的微控制器代码 while 1 key scan get value of temp if Usart Data
  • ESP8266 I2C从机不确认数据

    我有一个 TM4C123 处理器作为 I2C 主处理器 一个 ESP8266 作为从处理器 对于 ESP 我使用的是 Arduino IDE 并在 2 5 2 版安装了 ESP8266 支持 它应该支持 I2C 从模式 但是 我无法让它工作
  • 使用 /dev/tty* 进行 9 位 uart 仿真

    我有一个不常见的协议 它需要 9600 波特率 9 位和 1 个停止位 我找不到任何可以实现此发送 接收的驱动程序 我可以寄东西到 dev tty 用于模拟这些查询 我应该发送什么 如何模拟 9600 波特率 您可以使用粘性奇偶校验 也称为

随机推荐

  • 哈希表/哈希冲突及解决方法(较全)

    哈希表的概念请参阅他人文章 xff0c 关于哈希冲突的解决这篇文章基本都整理到了 xff0c 还有几个常见的面试题 解决hash冲突的几种方法 前导 xff08 题外话 xff09 xff1a 一 开放定址法 xff08 闭散列 xff09
  • 关于构造函数,拷贝构造函数,析构函数的调用顺序(1)

    导言 对象是由 底层向上 开始构造的 xff0c 当建立一个对象时 xff0c 首先调用基类的构造函数 xff0c 然后调用下一个派生类的构造函数 xff0c 依次类推 xff0c 直至到达派生类次数最多的派生次数最多的类的构造函数为止 因
  • vector的内存释放

    xff11 vector内存分配机制 C 43 43 中vector的一个特点是 xff1a 内存空间只会增长 xff0c 不会减小 即为了支持快速的随机访问 xff0c vector容器的元素以连续方式存放 xff0c 每一个元素都挨着前
  • MFC多人在线聊天室

    我已经在我的资源里上传了这个聊天室的代码了 基于MFC的C 43 43 的select模型的TCP聊天室 采用select网络模型 xff0c 支持多人同时登陆 xff0c 功能有上线 下线 群聊 私聊 使用CjsonObject进行数据传
  • linux---进程间通信(ipc)之共享内存

    前面我们讲解了进程间通信之管道 xff0c 这段我们讲解我们的共享内存 共享内存是所有进程间通信方式最快的一种 内存共享模型就像下面的图一样 xff0c 就是将物理内存映射到我们进程的虚拟地址上 xff0c 我们就可以直接操作我们虚拟地址空
  • Effective C++总结

    explicit关键字 C 43 43 中的explicit关键字只能用于修饰只有一个参数或者是其他参数有默认值的类构造函数 它的作用是表明该构造函数是显式的 而非隐式的 跟它相对应的另一个关键字是implicit 意思是隐藏的 类构造函数
  • 计算机网络(5)TCP之重传机制

    重传机制 超时重传数据包丢失确认应答丢失 快速重传SACKD SACK例一 ACK 丢包例2 xff1a 网络延时 TCP 是通过序列号 确认应答 重发控制 连接管理以及窗口控制等机制实现可靠性传输的 TCP 实现可靠传输的方式之一 xff
  • 中断与回调

    1 xff0c 回调函数 回调函数的原理是使用函数指针实现类似 软中断 的概念 比如在上层的两个函数A和B xff0c 把自己的函数指针传给了C xff0c C通过调用A和B的函数指针达到 当做了什么 xff0c 通知上层来调用A或者B 的
  • CUDA 程序的优化(3) 任务划分

    4 3 1任务划分原则 首先 xff0c 需要将要处理的任务划分为几个连续的步骤 xff0c 并将其划分为CPU端程序和GPU端程序 划分时需要考虑的原则有 列出每个步骤的所有可以选择的算法 xff0c 并比较不同算法在效率和计算复杂度上的
  • C++ Matlab混合编程时“函数或变量 ‘matlabrc‘ 无法识别”

    在QT中调用Matlab初始化时 xff0c 出现了 函数或变量 matlabrc 无法识别 的情况 xff0c 接着崩溃 而且比较神奇的是 xff0c 前一次是可以初始化的 xff0c 但运行过程中发生了崩溃 直接搜解决办法 xff0c
  • Notepad++全选一整列的靠谱办法

    遇到行数较少的可以直接按住ALT手动选取 xff0c 但遇到行数较多 xff0c 就得这么干 xff1a 鼠标放在第一行某一列 xff0c 按住Alt 43 Shift xff0c 然后鼠标选择最后一行该列 xff0c 输入内容即可 xff
  • 对象转xml格式工具类

    import com ruiyun gui store haikang haikang bean FCSearchDescription import com ruiyun gui store haikang haikang bean FD
  • 【无标题】MQ静态图片获取

    public void getImageV40 String path Integer buildingProjectId HttpServletResponse response JSONObject param 61 new JSONO
  • 数据加解密时Base64异常:Illegal base64 character 3a

    现象 用base64工具类对中文进行处理时出现异常 xff0c 在数据加解密场景中经常使用 java lang IllegalArgumentException Illegal base64 character 3a at java uti
  • Winsock编程实例---TCP&UDP

    0x1 基于TCP的通信 1 服务端 1 1 创建基本流程 创建一个TCP服务端的程序需要调用的函数流程 xff1a 初始化函数库 gt gt WSAStartup 创建套接字 gt gt socket 绑定套接字 gt gt bind 监
  • 数据结构---选择排序(直接选择排序和堆排序图解)

    选择排序思想 xff1a 每一次从待排序的数据元素中选出最小 xff08 或最大 xff09 的一个元素 xff0c 存放在序列的起始位置 xff0c 直到全部待排序的 数据元素排完 直接选择排序 在元素集合array i array n
  • Java HttpUtils类

    Java HttpUtils类 Java HttpUtils类 定义 Public class HttpUtils 收集HTTP Servlet使用的静态的有效方法 方法 1 getRequestURL public static Stri
  • Ubuntu打造家用NAS三——网盘与影视中心

    Ubuntu打造家用NAS三 网盘与影视中心 一 Ubuntu 挂载硬盘 通过 Putty 连接 NAS查看硬盘位置 xff1a sudo fdisk l找到需要挂载的硬盘 xff0c 我的是 Disk dev sdb xff1a xxx
  • Ardupilot笔记:Rover auto模式下的执行流程

    先从mode auto cpp的update 开始分析 流程如图 xff1a 进入函数update 后会执行函数navigate to waypoint mode auto cpp span class token keyword void
  • 串口通信协议 UART+I2C+SPI

    UART 异步 串行 全双工 I2C SPI 不同通信协议比较 UART UART协议详解 UART通信 xff0c 接收与发送 xff08 详细版 xff0c 附代码 xff09 UART串行通信详解 待整理 UART是Universal