低速接口之IIC

PS:总结语句用红色标出,看红色字体即可
部分参考:I2C-双向二线制同步串线总线-IIC-详细理解整理
I2C的那些坑
I2C详解

本文部分参考自互联网,侵权请联系,马上删除。

先上时序图:
在这里插入图片描述
应答时,永远SCL一个完整的波形获取一个比特数据。

总的来说: 两线都需要上拉, 多主机通讯,每一个设备都有一个独一无二的地址,速率100k或者400k,最远距离1米。SDA稳定,一个SCL升降沿获取一位数据。

硬件上,需要接上拉电阻,因为根据I2C总线规范,总线空闲时两根线都必须为高;
I2C上拉电阻确定有一个计算公式:
Rmin={Vdd(min)-o.4V}/3mA
Rmax=(T/0.874) *c, T=1us 100KHz, T=0.3us 400KHz
C是Bus capacitance
关于iic的上拉电阻,个人最好的方式就是看参考设计,如果走线长了或好总线上有好几个芯片,就把电阻改小一些。如果参考设计没有就在1.5K~5k左右里面选一个就是了。像19楼说的确实有计算公式可以计算,但实际的时候我们没有去测量总线的电容问题,只能在选件/走线时候给与些许的关注。
如果只有一个设备10K是没关系,设备多了就要考虑驱动能力,用1k,1.5k,2.2K都比较好。
低速100khz的I2C上拉一般是10K,高速I2C(400kz)上拉选择1k

在这里插入图片描述
在这里插入图片描述

一. 技术性能:

S(标准模式) 测量与控制场合,100kb/s;F(快速模式) ,速率为 400kb/s;Hs(高速模式) ,速率为 3.4Mb/s。
支持多机通讯;
支持多主控模块,但同一时刻只允许有一个主控;
由数据线SDA和时钟SCL构成的串行总线;
每个电路和模块都有唯一的地址;
每个器件可以使用独立电源

二. 基本工作原理:

以启动信号START来掌管总线,以停止信号STOP来释放总线;
每次通讯以START开始,以STOP结束;
启动信号START后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位R/W,R. /W位为0表示由主控向被控器件写数据,R/W为1表示由主控向被控器件读数据;
当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;
每个数据字节在传送时都是高位(MSB)在前;

写通讯过程:
**加粗样式**

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
第6步和第7步可以重复多次,即顺序写多个寄存器
8.Master发起STOP结束传输

读通讯过程:
**加粗样式****加粗样式**

1.Master发起START
2.Master发送I2C addr(7bit)和r(读)操作1(1bit),等待ACK
3.Slave发送ACK
4.Slave发送data(8bit),即寄存器里的值
5.Master发送ACK
第7步和第8步可以重复多次,即顺序读多个寄存器
6.当master接收完想要的数据后,由Master发送NACK,告知slave停止发送数据
7.Master发送STOP结束传输

四. 总线信号时序分析
在这里插入图片描述

  1. 总线空闲状态
    SDA和SCL两条信号线都处于高电平,即总线上所有的器件都释放总线,两条信号线各自的上拉电阻把电平拉高;
    2. 启动信号START
    时钟信号SCL保持高电平,数据信号SDA的电平被拉低(即负跳变)。启动信号必须是跳变信号,而且在建立该信号前必修保证总线处于空闲状态;
    3. 停止信号STOP
    时钟信号SCL保持高电平,数据线被释放,使得SDA返回高电平(即正跳变),停止信号也必须是跳变信号。
    4. 数据传送
    SCL线呈现高电平期间,SDA线上的电平必须保持稳定,低电平表示0(此时的线电压为地电压),高电平表示1(此时的电压由元器件的VDD决定)。只有在SCL线为低电平期间,SDA上的电平允许变化。
    在这里插入图片描述
    5. 应答信号ACK
    I2C总线的数据都是以字节(8位)的方式传送的,发送器件每发送一个字节之后,在时钟的第9个脉冲期间释放数据总线,由接收器发送一个ACK(把数据总线的电平拉低)来表示数据成功接收。
    6. 无应答信号NACK
    在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个NACK,NACK有两种用途:
    a. 一般表示接收器未成功接收数据字节;
    b. 当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。

  I2C (Inter-Integrated Circuit):由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
  I2C 总线是一种简单、双向二线制同步串行总线。所有主机在 SCL 线上产生它们自己的时钟来传输总线上的报文,SDA 线传输每个字节必须为 8 位,每次传输可以发送的字节数量不受限制,每个字节后必须跟一个响应位。在空闲状态时,SCL 与 SDA 均为高电平。
通常一些低功耗 i2c 设备,芯片引脚使用上拉输出即可满足与其正常数据交互,还有一些 i2c 设备,则需要在总线上外加一个上拉电阻,此时相应的 I/O 配置成开漏输出 ,其他的按照芯片手册进行标准配置。

在这里插入图片描述
在这里插入图片描述

注意上拉电阻不能太大,否则驱动能力比较低,在多设备的时候会引发问题。
  I2C总线用两条线(SDA和SCL)在总线和装置之间传递信息,在微控制器和外部设备之间进行串行通讯或在主设备和从设备之间的双向数据传送。I2C是OD输出的,大部分I2C都是2线的(时钟和数据),一般用来传输控制信号。I2C是多主控总线,所以任何一个设备都能像主控器一样工作,并控制总线。总线上每一个设备都有一个独一无二的地址,根据设备它们自己的能力,它们可以作为发射器或接收器工作。多路微控制器能在同一个I2C总线上共存。用于短距离传输,传输距离一般不超过一米,传输速率由几百K到几Mbps,最高速率比SPI低

I2C总线死锁
正常I2C通信肯定不会出现死锁的,死锁即是I2C在某一特殊时刻出现了异常。
死锁的表现:SCL一直为高,SDA一直为低

场景1:在写阶段的ACK阶段,SDA被slave拉低作为ACK,master突然复位了,SCL也被复位为高电平,这样:master检查到SDA为低,会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平,而slave不知道master异常复位,还在傻傻等待SCL拉低,然后结束ACK信号,这样master与slave互相等待,造成死锁。
场景2:当I2C进行读操作时,slave应答后输出数据,如果在这个时刻master异常复位而此时slave输出的数据位正好为0,也会导致I2C总线进入死锁状态。
总的说来:SDA为低时,期待一个SCL的下降沿驱动,但是master由于异常复位导致SCL一直为高,这样就产生了死锁。

解决死锁的方法:
最好用模拟I2C实现,则不会死锁

将从机的电源设计为可控,当发生总线死锁的时将从机复位
可以在从机的程序中加入监测功能,如果总线长时间被拉低则释放对总线的控制
在主机中增加I2C总线恢复程序。每次主机复位后,如果检测到SDA被拉低,则控制SCL产生<=9个时钟脉冲(针对8位数据的情况),每发送一个时钟脉冲就检测SDA是否被释放,如果SDA已经被释放就再模拟产生一个停止信号,这样从机就可以完成被挂起的读写操作,从死锁状态中恢复过来。这种方法有一定的局限性,因为大部分主机的I2C模块由内置的硬件电路来实现,软件并不能够直接控制SCL信号模拟产生需要的时钟脉冲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夜灼华

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

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

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

打赏作者

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

抵扣说明:

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

余额充值