详解UART、I2C、SPI常用通信协议(全是细节)

article/2025/9/21 14:00:14

前言

        UART、I2C和SPI是我们在嵌入式开发中比较常见的通信协议了,没有最好的通信协议,每个通信协议都有自己的优缺点。如果想要通信速度快,SPI 将是理想的选择;如果用户想要连接多个设备而不是过于复杂,I2C 将是理想的选择,因为它最多可以连接 127 个设备并且易于管理;UART的通信速度相对较慢,通信也比较简单,单对单。

        uart接口比较常用于主设备与蓝牙、wifi模块的通信、打印调试等。

        i2c接口多用于和传感器的通信,例如触摸屏、计步器、温度传感器、EEPROM等。

        spi接口多用于对速率要求高一些的场景,如spi flash、spi lcd屏、SD卡等。

1. UART通信

1.1 UART基本概念

UART(Universal Asynchronous Receiver/Transmitter):解释为通用异步接收传输,是一种串行、异步、全双工的通信协议。

UART 没有时钟线,使用两条数据线进行设备通信,每个设备上都有一个 RX 引脚和一个 TX 引脚(RX 用于接收,TX 用于传输), RX 引脚连接到另一个设备的 TX 引脚;

由于 UART 没有时钟线,因此添加了起始位和停止位以表示数据的开始和结束;

③ 两个通信设备间必须以大致相同的波特率(误差不超过10%)运行,否则就可能操作数据错乱;

④ 异步通信以一个字符为传输单位,通信中两个相邻字符之间的时间间隔是不固定,但同一字符中相邻两个位之间的时间间隔是固定的。

1.2 通信数据格式

空闲:空闲时总线为高电平,通常软件上把数据线配置为推挽、上拉;

起始位:主设备发送一个逻辑“0”信号表示传输字符的开始

数据位:数据位可以是5~9位组成的一个字符(通常为8位),从最低位开始传输

校验位:通常我们设置为无奇偶检验位;

                奇校验:如果数据位中“1”的个数为偶数,则校验位为“1”,为奇数,则校验位为‘0’;

                偶校验:如果数据位中“1”的个数为偶数,则校验位为“0”,为奇数,则校验位为“1”;

停止位:可以是 1 、1.5 位或 2 位的逻辑“1”电平,由于同一字符间相邻位的传输时间是固定的,每个设备uart都有自己的时钟,在通信中两个设备之间很可能会出现一点不同步,所以停止位不仅表示传输结束,还能提供纠正时钟的作用,停止位越多,数据传输越稳定,但数据传输速度越慢。

1.3  UART、USART区别

USART (通用同步/异步接收器/发送器)可以说和uart是包含关系,uart有的功能usart都有(异步功能模式),usart可以工作在异步和同步模式下。

        在同步模式下,有自己的时钟线,此时接收端不需要知道发送端的波特率,数据是以帧的形式传输的,传输速率比uart高。

        uart的协议结构很简单,而USART 更为复杂,可以生成与许多不同标准协议相对应的形式的数据,例如 IrDA、LIN、智能卡、RS-485 接口的驱动程序启用和 Modbus 等。

2.  I2C通信

2.1.  I2C基本概念

I2C(内部集成电路)接口有2条线,分别是SCL(串行时钟线)SDA(串行数据线)。SCL用作数据的同步传输,一般由主设备提供给从设备;另外,由于数据线只有一条;因此,它是个串行、同步、半双工的通信接口。

 I2C支持多主、多从;任何设备都可以同时作为主从,但同时只能有一个主控,一个I2C控制器可以支持挂多个I2C从机设备,其中每个从机的设备地址都是不一样的,以便I2C主控制器访问到该设备;

硬件I2C的SCL和SDA接口电路必须外接上拉电阻,空闲时,两条线都为高电平;

 起始、停止信号都是由主机端发出的,在起始信号产生后,总线就处于被占用的状态;在停止信号产生后,总线就处于空闲状态;

④ I2C总线以一个字节(8bit)为单位传输数据,每传输一个字节时,必须得到数据接收方的应答信号,数据都是从最高有效位开始传输,

 I2C的每次通信都是由主设备发起的,在这个过程中,发起端扮演了两个角色,当处于应答时段发起端扮演从端,其余时间都扮演主端;

 主设备每次发送数据和读写位时,都会等待从设备的响应信号ACK。

2.2  通信协议格式

空闲态:SCL和SDA线均为高电平,处于空闲状态;

起始信号:当SCL为高电平期间,SDA由高到低电平的跳变(启动信号是一种电平跳变时序信号,而不是一个电平信号);

地址位:由7位或者10位组成,主设备端发送从设备的设备地址;

读写位:逻辑“0”表示主向从写操作,逻辑“1”表示主向从读操作;

应答位:从设备通过将SDA线拉为低电平来表示ACK(有效应答)成功,SDA被拉高表示NACK(无效应答);

数据位:一个字节代表一个数据,SCL为高电平的时候读取SDA的有效数据,每字节数据后都需要接收从设备的应答,检测是否接收成功;

停止信号:当SCL为高电平期间,SDA由低到高的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。

2.3  工作过程

在空闲状态的时候,主设备向从设备发送起始信号,告诉从设备将要开始i2c通信了;

发送完起始信号后,接着发送需要通信的从设备的设备地址,该i2c控制器下的每个从设备对比该设备地址,比对不正确的忽略此次通信,匹配成功的继续通信;

接着主设备发送读写位,主设备释放总线,并等待从设备的应答信号,发起端接收到应答信号后,从设备就会释放总线控制,总线控制权归还给发起端;

写操作:

        发送需要操作的从设备寄存器地址 + 写入寄存器的值;

读操作:

        相对写操作会复杂些,写入需要读的从设备寄存器地址,等待从设备的应答后,主设备重新向从设备发送起始信号 + 从设备地址 ,并将读写位设备为读,等待从设备应答,最后就会开始接收从设备发送过来的数据,直到停止信号发生。

2.4  传输模式

        除超快速模式外,其它都是可以向后兼容的,也就是说快速模式设备向后兼容,可以与 0 至 100 kbit/s I2C 总线系统的标准模式设备通信,然而,由于标准模式设备不向上兼容,它们不能在快速 I2C 总线系统中运行。

网图

2.5.  I2C死锁问题

死锁是什么意思呢?就是你在等我做某件事,而我又在等你做某件事,然后双方就互相等待,啥也不去做了,这就是死锁。

发生死锁的常见情况有两种

① 从设备回复ACK时主设备异常复位

② 从设备回复数据位为0时,主设备异常复位

两者的共同点就是SDA在主设备异常复位时,处于被从设备拉为低电平的状态,而SCL在主设备复位后处于空闲状态(高电平)。此时从设备会等待主设备拉低SCL取ACK或数据位,主设备会等待从设备释放SDA线。主设备和从设备互相等待,进入死锁状态。

解决死锁问题的可尝试方法:

  • 主设备检测到SDA拉低超过一段时间后,主动复位从设备并释放SDA线。这种方法的前提是从设备有复位引脚,MCU可以控制从设备的复位引脚对其进行复位。
  • 主设备检测到SDA拉低超过一段时间后,将9个时钟信号推入时钟总线(即接收应答信号),然后取出从设备的ACK位,使从设备释放SDA到高电平。
  • 在主设备和从设备之间串联一个 I2C 缓冲器,可以自动检测死锁情况。当检测到死锁时,会主动断开与主设备的连接,并向从设备发送9个时钟信号,从设备释放SDA线后,会重新与主设备建立连接。

I2C死锁问题无法从根本上避免。除了MCU异常复位导致I2C死锁外,正常通信过程中从设备也可能异常拉低SDA导致死锁。因此,软件应该设计成当死锁发生时能够从死锁中恢复,这样I2C通信才能继续进行。

3. SPI通信

3.1  SPI基本概念

SPI(Serial Peripheral Interface):串行外设接口,它是由摩托罗拉开发的一种串行同步全双工的通信协议,可以同时发送和接收数据,发送的数据先发到发送数据缓存区中,然后再到移位寄存器中按位传送,数据都是以字节为单位,高位优先发送。

① SPI 总线总共有 4 条线:   

  • MOSI :主设备数据输出,从设备数据输入;
  • MISO :主设备数据输入,从设备数据输出;
  • SCLK: 主设备产生的时钟信号;
  • CS/SS:(Chip select)由master设备控制,选择与哪个SPI从设备通信;通常设为低电平表示使能该从设备;

②  支持一主多从,一个主设备控制多个从设备,通常配置为每个从设备对应一条CS线,通过拉低CS信号,选择需要通信的从设备,如果同时将两个SS信号线拉低,则可能会出现乱码,因为从机可能都试图在同一条MISO线上传输数据,最终导致接收数据乱码;

③ 在一个时钟周期内,SPI 设备会进行1 bit 数据的发送和接收,其实就是主从间数据交换的过程,在数据传输的过程中,接收到的数据必须在下一次数据传输之前被采样,如果之前接收到的数据没有被采样,那么之前的数据就会被覆盖掉,丢失。

④ 主、从设备必须工作在同一模式下。

3.2  四种工作模式

SPI通信时钟信号是由主设备产生的,其工作模式就涉及到时钟极性(CKP/CPOL)和时钟相位(CKE/CPHA)了,时钟极性和时钟相位共同决定SPI读取数据的模式;

时钟极性:设为“0”表示空闲状态时钟为低电平,

                  设为“1”表示空闲状态时钟为高电平;

时钟相位:设为"0"表示在时钟信号的第一个跳变沿采样,

                   设为"1"表示在时钟信号的第二个跳变沿采样;

要理解这四个工作模式,你必须要知道的一点就是,SPI通信传输过程其实就是主、从设备数据交换的一个过程,MOSI 和 MISO在一个时钟周期内都会进行数据位的发送和接收,如果不需要接收的数据,直接忽略就可以了,不做处理。

3.2.1  模式0 (CPOL = 0,CPHA = 0)

在空闲状态下,SCLK处于低电平,在第1个时钟边沿进行数据采样。SCLK由低电平到高电平的跳变进行数据采样(第一个跳变沿采样),采样完在下一个跳变沿发送数据。

 3.2.2 模式1 (CPOL = 0,CPHA = 1)

在空闲状态下,SCLK处于低电平,在第2个时钟边沿进行数据采样,第一个时钟沿进行发送数据。

 3.2.3 模式2 (CPOL = 1,CPHA = 0)

在空闲状态下,SCLK处于高电平,在第1个时钟边沿进行数据采样。SCLK由高电平到低电平的跳变进行数据采样(第一个跳变沿采样),采样完在下一个跳变沿发送数据。

 3.2.4 模式3 (CPOL = 1,CPHA = 1)

在空闲状态下,SCLK处于高电平,在第2个时钟边沿进行数据采样,第一个时钟沿进行发送数据。


http://chatgpt.dhexx.cn/article/p7h2PcGg.shtml

相关文章

【总线】SPI 通信协议

目录 SPI总线协议概述 串行与并行通信 SPI通信介绍 SPI的工作原理 时钟 从属选择 多个从机 常规方法 菊花链方法 MOSI 和 MISO SPI 数据传输的步骤 SPI 的优缺点 优点 缺点 文章参考 SPI总线协议概述 SPI是许多不同设备使用的通用通信协议。例如,SD卡…

SPI通信协议详解,一篇就够!

一、什么是SPI? SPI 的英文全称为 Serial Peripheral Interface,顾名思义为串行外设接口。SPI 是一种同步串行通信接口规范,主要应用于嵌入式系统中的短距离通信。该接口由摩托罗拉在20世纪80年代中期开发,后发展成了行业规范。 …

2021年游戏项目的十大编程语言:C++、Java、C#均上榜

在这个技术驱动的世界里,游戏行业是全球增长最快的行业之一。在每一款华丽精美的电子游戏背后,都有一种编程语言,为用户提供优质的体验。游戏开发者利用顶级的编程语言来构建游戏。不同的游戏项目使用了不同的编程语言,这取决于游…

2021 编程语言排行榜

点击“终码一生”,关注,置顶公众号 每日技术干货,第一时间送达! IEEE Spectrum 发布了 2021 年编程语言排行榜,官方的标题是:Python 在新技术领域依然是主导地位。 Python 近几年随着大数据、数据挖掘、人…

2020 年最牛逼的 10 门编程语言

先看再点赞,给自己一点思考的时间,微信搜索【沉默王二】关注这个有颜值却假装靠才华苟且的程序员。 本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试题。 对于很多初学编程的人来说,尤其是马上要入…

世界上到底有多少种编程语言?

最近,网站上看到一个很有意思的问题:世界上到底有多少种编程语言? 查遍网络之后,仍然没有找到准确答案,只知道几千的数量是有的,但是我们常用的也就几十来个,其中最常见的便是Java、Python、C、…

世界上最难的5种编程语言

世界上最难的5种编程语言 每个程序员都熟悉许多编程语言。许多编程语言都是高级的,它们的语法是人类可读的。然而,也有一些低级语言,对于一个人来说,读起来很困难,但是可以理解。然而,您是否遇到过一种既不…

2018年最流行的十大编程语言,有你用的吗?

对于编程界的初学者来说,最大的困难是决定从何处入手,或者应掌握哪种语言才能在职场上平步青云。有时,专业程序员也面临学习一门新语言似乎更卓有成效的情形。 无论是什么原因,下面列出了世界上最流行的编程语言,以便了…

5月编程排行榜出炉,最佳编程语言是谁?

技术的发展日新月异,作为开发者,应该时刻关注这些变化,不断学习才能跟上时代步伐。 编程语言层出不穷,关于“ 最佳编程语言 ”的争论也从未停止,网友们各抒己见...... 网友A: 人生苦短,我选Pyt…

十大热门编程语言的介绍

小编给大家分享一篇关于现阶段十大热门编程语言的文章:经过流行的搜索引擎,如谷歌,必应,雅虎,维基百科,亚马逊,YouTube和百度,用于计算评级;得出十大热门编程语言排行榜的…

GitHub2022年十大热门编程语言榜单

全球知名代码托管平台 GitHub发布的2022年GitHub Octoverse年度报告公布了全球最流行的十大编程语言,其中JavaScript蝉联第一,Python位列次席。 编程是技术革新的核心,对于所有的编程开发人员来说,对世界范围内编程语言发展和趋势…

2021年十大热门编程语言

几乎可以肯定,每个人都知道,在当今数字先进的世界中,技术是如何快速变化的。经常通过定期更新和改进来观察替代技术之间的相互超越已成为一种正常现象。在这一切之中,一个领域因技术世界的如此多变的性质而受到很大的影响&#xf…

十大编程语言,每一个都不容易学,但每一个又很有用,黑客必备

一定要注意,您选择的编程将在很大程度上取决于您要定位的系统类型和计划使用的漏洞。因此,根据您的策略,任何语言都会很棒。 1. C语言 它被称为“所有编程语言之母”,也是Hacking社区中的关键语言。今天,我们拥有的大…

抖音照片图集怎么制作,如何将图片做成视频上传抖音?

抖音最近被很多人当做茶余饭后不可或缺的娱乐项目,丰富了很多人的业余生活,也成就了很多抖音人,经常在抖音上会看到很多不是直接拍摄的视频,而是通过图片图集的方式展示出来的视频,图片中还可以配上相应的文字&#xf…

手把手教你抖音怎么用图片做视频!

抖音是一款短视频APP,在抖音里人们可以上传视频,录制视频,看到别人的视频,抖音目前很受年轻人的欢迎,使用抖音的人高达几个亿;我们在抖音上看到的照片视频,其实大部分是在电脑制作后上传的一般比…

如何用照片做抖音视频?这样剪辑电子相册

如果只是在抖音中拍摄视频的话,相信这个操作大家都会吧?毕竟现如今的抖音可以说是全民在用了,关于如何拍摄视频发布到抖音,这个操作也几乎是人人都会的。但是拍摄视频你会,你又知道应该如何用照片来制作一个抖音视频吗…

[短视频运营] 抖音最新风口,漫改图文号,变现模式非常简单

这几天抖音出现了一个新的风口,千万不要错过,抖音召开了抖音创作者大会,在大会上有几件事的披露引起了广泛关注,对于每一个在抖音上的创作者来说都是重大的事件。 ​第一、抖音在大会上确定未来一年将会把更多的重点放在图文和中…

抖音开放平台-视频切片-视频分片上传-不合法的参数ID-不合法的对象ID

问题描述 1、最近遇到个问题,做业务需要管理几个抖音账号,用抖音开放平台做分片上传视频,多次返回不合法参数id,提交工单之后给的回复没有任何参考价值。 2、例如视频文件按15M进行切片,调用分片上传初始化接口&#…

抖音上css照片动态旋转怎么做,抖音里单张图片平移视频怎么制作?影音制作实现一张图片从左到右滑动视频效果...

今天的影音制作,是实现视频画面中有一张图片从左往右慢慢滑动的视频效果。一张横屏图片要制作成竖视频的时候,要么就会出现图片显示不全的情况,要么显示全了就会出现上下有黑边的情况,基本很难解决这个问题~但是小编今天通过这款常…

仿抖音上下滑动分页视频

如果要是不想看这么代码的话,我整理了一下项目,下载到本地直接进行运行也可以; 代码下载地址 目录介绍 01.先来看一下需求02.有几种实现方式 2.1 使用ViewPager2.2 使用RecyclerView03.用ViewPager实现 3.1 自定义ViewPager3.2 ViewPager和…