I2C总线介绍

简介

I2C(也常写作IIC,I2C),全称为Inter-Integrated Circuit(“互连集成电路”),用于在集成电路之间进行短距离、低速率数据传输。它由Philips(现在的NXP半导体)公司于1980年代初开发,并成为一种广泛应用于电子设备之间通信的标准。I2C协议简单、灵活且广泛支持,常用于连接传感器、存储器、显示屏和其他外设到微控制器、微处理器或其他集成电路上。这是一种简单的双向双线总线,非常适合用于微控制器与外设之间,或者多个微控制器之间的高效互连控制。

i2c的应用非常广泛,常见的i2c设备有sensor、camera、touchscreen、codec、PA、rtc、charger等等等等,是软硬件工程师必须掌握的知识。

硬件介绍

I2C硬件电路非常简单,只有SCL(Serial Clock)串行时钟和SDA(Serial Data)串行数据两根线组成。SCL是时钟线,用于同步通信速率;SDA是数据线,用于双向传输数据和控制信号,因为同一时间只能往一个方向传输数据,所以I2C是一种半双工同步串行总线。

SDA和SCL都是双向I/O线,接口电路为开漏输出。需通过上拉电阻(常用4.7k和10k)接电源VCC(常用1.8v和3.3v)。

为什么需要上拉:为了支持多个设备共享总线,防止其中一个设备尝试传输高电平,而另一个设备传输低电平,导致短路(电源电平到地)。

应用电路

支持“一主多”从和“多主多从”模式,多个从设备通过不同的i2c地址进行区分。

一主多从

多主多从

多主多从模式下,需要提供仲裁和冲突检测机制。

控制器内部结构

I2C控制器里面一般会有很多的寄存器。比如:

controller_register可以设置I2C控制器的频率
tx_register、rx_register控制数据的传输
status_register控制I2C的状态
int_register控制I2C的中断
当CPU需要发送数据时,只需要写给tx_register。后面的I2C控制器会自动帮忙做好,在SDA上发送数据。
当程序写入tx_register后,就不用管了。直到数据发送结束,会产生一个发送完成的中断。

IMX6ULL的I2C控制器内部结构

I2C_IFDR(频率寄存器)
I2C_I2CR(控制寄存器
I2C_I2SR(状态寄存器)
I2C_I2DR(数据I/O寄存器)
I2C_IADR(地址寄存器)

STM32MP157的I2C控制器内部结构体

i2c_ker_ck时钟
Data control(数据控制),shift register(移位寄存器)
当CPU把数据写入移位寄存器后,通过寄存器、通过SDA发送出去。接收数据则是相反的路径。
Clock control(时钟控制)

通信速率模式

其中Ultra-Fast Mode只能写,不能读,也就是单项模式

传输协议

I2C总线是一种标准的双向接口,使用控制器(即主设备)与从设备进行通信。除非被主设备寻址,否则从设备不能传输数据。I2C总线上的每个设备都有一个特定的设备地址,以区分其他在同一I2C总线上的设备。

i2c传输协议非常简单,以最简单的8位地址单字节为例,如下图所示

开始和停止条件

图中S代表起始信号,P代表停止信号。空闲状态,SCL和SDA保持高电平。起始信号对应的波形为,SCL保持高,SDA从高到低变化;停止信号对应的波形为SCL保持高,SDA从低到高变化;

重复起始条件

重复的起始条件(Repeated START condition)类似于起始条件(START condition),用作连续的停止条件和起始条件的替代。它在外观上与起始条件相同,但与起始条件不同,因为它发生在停止条件之前(总线不处于空闲状态)。这在主设备希望启动新的通信,但不希望通过停止条件使总线空闲,从而可能失去对总线的控制权(在多主设备环境中)时非常有用。
 

数据采样

在每个SCL时钟脉冲期间传输一个数据位。一个字节由SDA线上的八个位组成。一个字节可以是设备地址、寄存器地址或从从设备写入或读取的数据。数据以最高有效位(MSB)优先的顺序传输。在START和STOP条件之间,可以从主设备向从设备传输任意数量的数据字节。在时钟周期的高电平期间,SDA线上的数据必须保持稳定,因为当SCL为高电平时,数据线的变化被解释为控制命令(START或STOP)。

应答(ACK)和非应答(NACK)

接收器在每个数据字节(包括地址字节)后发送一个ACK位。ACK位允许接收器向发送器传达字节已成功接收,并且可以发送另一个字节。

在接收器发送ACK之前,发送器必须释放SDA线。为了发送ACK位,接收器在ACK/NACK相关的时钟周期(周期9)的低电平期间拉低SDA线,以便在ACK/NACK相关的时钟周期的高电平期间,SDA线保持稳定低电平。必须考虑到设置时间和保持时间。

当SDA线在ACK/NACK相关的时钟周期中保持高电平时,这被解释为非应答(NACK)。有几种情况会导致产生NACK:

1. 接收器由于执行某些实时功能并且尚未准备好与主设备开始通信,因此无法接收或发送。
2. 在传输过程中,接收器接收到无法理解的数据或命令。
3. 在传输过程中,接收器无法接收更多的数据字节。
4. 主设备接收器完成数据读取,并通过NACK向从设备表示这一点。

波形实例

下图是向设备地址0xA0的寄存器0x0C写数据的实际波形

要点总结

I2C的地址位有7bit和10bit两种。对于7bit地址,最多支持寻址127设备(实际情况要考虑负载容值,总容值不允许超过400PF)。对于10bit地址,最多支持1023个设备。

SCL高电平是对SDA进行数据采样, 如果此时SDA发生电平变化,则是起始终止条件。

当主机传送8位数据结束后,主机会将SDA线拉高,此时如果从机正确接收数据则会将SDA拉低并在SCL高电平时保持低电平,这个信号为ACK信号。如果在传输8位数据后从机没有将SDA拉低则该信号为NACK。如果出现NACK则表示数据传输出错。

波形常见的问题

1. SCL上升时间tr大于datesheet标准
上升时间大,则意味着与标准相比,上升的较为平缓,驱动能力弱。这种问题往往是上拉电阻阻值选择不合理导致的。负载本身含有电容,如果上拉电阻的选取过大,RC延时电路,进而导致上升变得平缓。
解决办法:减小上拉电阻;软件调节驱动能力。

2. SDA SCL波形整体略微被抬高,低电平很难接近0V,甚至超过0.4V
这类问题,存在两种可能性。
A:测试时,示波器探头未进行校准,导致测试时,出现这类问题。
B:上拉电阻选取过小导致驱动电流过大。
解决办法:校准示波器;适当的减小上拉电阻阻值。

3. SDA信号出现毛刺。
小编曾在以前的项目中就遇到过。这种问题必须要重视。I2C的每个高电平以及低电平都有特殊含义,如果地址位,写或者应答位的低电平因毛刺的存在,误被识别成高电平,都是会影响到从机的正常工作的。

解决办法:PCB走线包地;SDA信号串小电阻。

4. I2C地址冲突
在硬件设计时,我们往往会在一组I2C上挂多组器件。有时稍不注意就会将地址一样的两个设备挂在同一组I2C上。
解决办法:有些芯片带有AD脚,例如smart pa芯片,可根据AD接地或者接电源来改变地址。亦或者回板后,手动返工。

5. SDA出现短暂脉冲
I2C中,在master向slave传输8bit数据之后,sda控制权由master交由slave,此时slave控制sda发送一个ack反馈信号,sda为低电平信号,在经过clk为高时接收到sda的低电平信号,在sclk变为低电平时,sda控制权由slave交回到master,在交回过程中有一小段时间sda处于既不由master又不为slave控制的空闲阶段,在空闲阶段sda默认为高电位(因为有上拉电阻),如果master要马上传输低电平,sda将由高电平转为低电平,便产生了一个小的毛刺。
这属于正常现象,不会影响通信。

 参考文章

一文详解I2C总线 - 接口/总线/驱动 - 电子发烧友网 (elecfans.com)

浅谈I2C知识_i2c速率-CSDN博客

Linux内核的I2C驱动框架详解_linux i2c驱动架构-CSDN博客

详解I2C-CSDN博客

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值