STM32 HAL库学习(四):I2C 协议篇

1. I2C

1.1 I2C 简介

I2C(Inter-integrated Circuit)总线支持设备之间的短距离通信,用于处理器和一些外围设备之间的接口,它只需要两根信号线来完成信息交换。

1.2 常见的串行通信接口对比

在这里插入图片描述
1.UART

  • 串行端口是异步的(不传输时钟相关数据),两个设备在使用串口通信时,必须先约定一个数据传输速率,并且这两个设备各自的时钟频率必须与这个速率保持相近,某一方的时钟频率相差很大都会导致数据传输混乱。
  • 异步串行端口在每个数据帧中都要插入至少一个起始位和一个终止位,意味着每传输8bits的数据实际要花费10bits的传输时间,从而降低了数据传输速率。
  • 异步串行端口的设计就是针对两个设备之间通信的,那么如果有多个设备连接到一个串口上,就必须解决信号碰撞的问题(bus contention),通常要通过额外硬件来完成。
  • 最后就是数据传输速率,异步串行通信并没有一个理论上的速率限制,大部分UART设备只支持一些特定的波特率,最高通常在230400bps左右。

2.SPI

  • SPI最明显的缺点就是引脚数量,使用SPI总线相连的一个master和一个slave需要四根线(MISO/MOSI/SCK/CS),每增加一个slave,就需要在master上增加一个CS引脚。当一个master接多个slaves的时候,疯狂增长的引脚连接是难以忍受的,并且对紧凑的PCB layout是一个挑战。
  • SPI总线上只允许有一个master,但可以有任意多个slaves(只受限于总线上设备的驱动程序的能力,以及设备上最多能有多少个CS引脚)。
  • SPI可以很好的用于高速率全双工的连接,对一些设备可支持高达10MHz(10Mbps)的传输速率,因此SPI吞吐量大得多。
  • SPI两端的设备通常是一个简单的移位寄存器,让软件的实现简单

3.I2C

  • I2C最少只需要两根线,和异步串口类似,但可以支持多个slave设备。一个IIC理论上最多可挂载127个设备,但除去保留地址,最多可挂载112个设备。
  • 和SPI不同的是,I2C可以支持mul-master系统,允许有多个master并且每个master都可以与所有的slaves通信(master之间不可通过I2C通信,并且每个master只能轮流使用I2C总线)。
  • I2C的数据传输速率位于串口和SPI之间,大部分I2C设备支持100KHz和400KHz模式。
  • 使用I2C传输数据会有一些额外消耗:每发送8bits数据,就需要额外1bit的元数据(ACK或NACK)。
  • I2C支持双向数据交换,由于仅有一根数据线,故通信是半双工的。
  • 硬件复杂度也位于串口和SPI之间,而软件实现可以相当简单。

2. I2C 物理层

在这里插入图片描述

(1) 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个I2C 通讯总线中,可连接多个I2C 通讯设备,支持多个通讯主机及多个通讯从机

(2) 一个I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。

(3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。

(4) 总线通过上拉电阻接到电源。当I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。

(5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

(6) 具有三种传输模式:标准模式传输速率为100kbit/s ,快速模式为400kbit/s ,高速模下可达 3.4Mbit/s,但目前大多I2C 设备尚不支持高速模式。

2. I2C 协议层

以主机向从机写数据为例,其基本结构如图所示,依次为
起始信号——从机地址——读写信号——数据位——应答位——… … ——停止位
在这里插入图片描述

2.1 起始和停止信号

起始信号(S):当 SCL 线是高电平时,SDA 线从高电平向低电平切换;
停止信号§:当 SCL 是高电平时,SDA 线由低电平向高电平切换。
在这里插入图片描述

2.2 地址和数据方向

(1)地址帧

  • I2C 总线上的每个设备都有自己的独立地址,主机发起通讯时,通过 SDA 信号线发送设备地址(SLAVE_ADDRESS)来查找从机。
  • I2C 协议规定设备地址可以是7 位或10 位,实际中7 位的地址应用比较广泛。

(2)数据方向

  • 数据方向位在设备地址后一位
  • “1”——“0”——

在这里插入图片描述

2.3 数据的有效性

I2C 使用SDA信号线来传输数据,使用SCL 信号线进行数据同步。

SDA数据线在SCL的每个时钟周期传输一位数据。

传输时,SCL为高电平的时候SDA表示的数据有效,即此时的SDA为高电平时表示数据“1”,为低电平时表示数据“0”。
当SCL为低电平时,SDA的数据无效,一般在这个时候SDA进行电平切换,为下一次表示数据做好准备。
在这里插入图片描述

2.4 响应

I2C 的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。

作为数据接收端时,当设备(无论主从机)接收到I2C 传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。
在这里插入图片描述
传输时主机产生时钟,在第9 个时钟时,数据发送端会释放SDA 的控制权,由数据接收端控制SDA,SDA 为高电平表示非应答信号(NACK),低电平表示应答信号(ACK)

2.5 速度

I2C由两根线组成,数据线SDA,时钟线SCL,标准模式的时候,SCL的频率可达100KHZ,高速模式的时候,频率可达400KHZ。频率越高,对上升沿的要求越高。

现在拿100KHZ的频率来说,一个SCL周期为10uS,这其中包括一个上升沿,一个下降沿,一个高电平时间和一个低电平的时间。如果SCL的上升沿要15uS,那么波形都还么有上升到1就开始向0变化了,这样连I2C的起始条件都不能达到。

因为I2C从设备一般都是MOS工艺,所以I2C总线都有上拉电阻,而传输线是有电容效应的,你接的设备越多,电容会增大,在上升的时候就会造成延时,连接到总线的接口数量只由总线电容限制决定。

我们也曾经遇到过类似问题,就是外围从设备I2C的速度太慢,用主设备的I2C去通讯出错,最后的解决方法是不用主设备的I2C,而是用I/O去模拟I2C去跟外围设备通讯。希望对你有帮助。

参考资源

IIC总线传输协议
软件模拟IIC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

la_fe_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值