协议篇-IIC协议

        IIC简介

        IIC是一种同步串行通信接口,采用半双工模式,即同一时刻只能是输入模式或者输出模式。

        如下图所示为IIC结构图:

                                                                图1 IIC总线结构图

        简单总结IIC特性如下:

        1、IIC由SCL和SDA组成,并配有上拉电阻,上拉电阻阻值一般为4.7K;

        2、SDA线用于数据的双向传输,‌而SCL线由主设备控制,‌生成时钟信号以同步通信过程。

        3、IIC总线可以挂多个主从设备,每个设备公用两条总线,,一般由主设备发起读写访问,上图以FPGA作为主设备访问多个从设备读写操作;

        4、每个从设备都有自己的唯一地址,地址不可以重复;

        5、IIC速度一般在100~400KHz,最高时钟频率在1MHz左右。

        IIC设备内部硬件设计:

        SCL和SDA均设置为开楼模式输出,如下图所示为IIC内部设计图:

                                                        图2 IIC设备内部设计图

        如上图所示,IIC总线设计的开漏输出,其工作原理如下:

        1、当设备输出低电平时,经过反向电路后到CMOS管的G端为1,CMOS导通,输出到总线OUT端的点平稳定在低电平。

        2、设备输出高电平时,CMOS管G端为0,CMOS管不导通,OUT处于断开状态,经过上拉电阻后输出高电平。

        开漏设计的优点很明显,多个设备可能会同时尝试控制总线。由于开漏设计,任何设备都可以安全地将总线拉低而不会对其他设备造成伤害,任何一个设备需要输出低电平,该设备的CMOS管导通,可以令总线拉低。

        上拉电阻的特点如下:

        1、提供拉高电平:

        设备将总线释放时,上拉电阻将SDA和SCL线拉高到正逻辑电平(通常是Vcc),确保线路在非驱动状态时为高电平。

        2、限制电流:

        当总线设备将SDA或SCL线拉低时,上拉电阻起到限流的作用,防止电流过大导致设备损坏。

        3、增强信号完整性:

        上拉电阻也有助于维护信号的完整性,减少因为长线路或者其他电气特性引起的信号退化。

        选择合适的上拉电阻值是很重要的。电阻值太大,电流太小,导致总线拉高速度变慢,影响通信速率;电阻值太小,可能导致电流过大,浪费功率,且拉低总线时可能会对设备造成损害。通常,上拉电阻的选择取决于总线容量(总线上设备的数量和总线长度)和系统工作的电源电压。常见的电阻值范围从1.8kΩ到10kΩ不等。

        IIC协议

这里先了解IIC的四个标志信号特性,分别是起始信号、终止信号、应答信号、非应答信号。如下图所示:

                                                        图3 IIC 信号标志

        SCL在高电平期间 SDA由高到低代表起始始信号;

        SCL在高电平期间 SDA由低搭到高代表终止信号;

        应答信号ACK=1;代表从设备通信成功;

        非应答信号NACK=0,代表从设备未通信成功;

       IIC通信图如下图所示:

                                                                图4 IIC通信图

        通信过程中,SCL为高电平时需要保证数据已稳定并采样,SCL为低电平时数据可变化。比较稳妥的设计时SCL在上升沿到来之前,SDA已经准备好数据。

        如下图所示位数据通信时序图:

                                                        图5 IIC数据传输时序图

        IIC通信写动作要比读流程简单,单个Byt写操作流程如下(绿色代表主到从,蓝色代表从到主):

Start

addr

0

ack

data

ack

stop

                                                   

多个Byte写流程如下:

Start

addr

0

ack

data

ack

data

ack

......

stop

        不同于单个Byte操作的是会连续编写多个data,每个写data后面会紧跟着一个ack应答。

        以BMP581传感器举例,如下图所示代表寄存器单个Byte写操作:

                                                            图6 BMP581IIC单个Byte写操作

        写操作和上面介绍的一致,需要注意的是上图中由于register寄存器地址只有7位,所以register地址最高位X是无效的意思,0或者1都可以。

        如下图所示BMP581连续写操作

                                                        图7 BMP581IIC多个Byte写操作

        多个写操作数据的地址会自动在起始写地址的基础上累加,传感器寄存器读写配置基本都符合该操作。

        读操作相比较会复杂一些,依然用bmp581传感器为例,IIC读操作如下图所示:

                                                图8 RESTART IIC读操作

        IIC读操作需要先进行写地址配置,只有确认要读的地址后,再进行读操作。上图黄色的代表主设备输出,蓝色的代表从设备返回的数据,操作流程如下:

        1、主设备发起IIC起始位;

        2、主设备发送要操控的从设备地址+写(0);

        3、主设备释放SDA总线,从设备返回ACK表示已接收到命令;

        4、主设备发送要访问的寄存器地址;

        5、主设备释放SDA总线,从设备返回ACK表示已接收到命令;

        到这里读操作的第一步已经完成,接下来进行指定寄存器读操作:

        1、主设备发送RESTART信号,该信号和START信号一样;

        2、主设备发送要操控的从设备地址+读(1);

        3、主设备释放SDA总线,从设备返回ACK表示已接收到命令;

        4、从设备返回前面指定的寄存器地址所存储的值;

        5、主设备返回ACK;

        6、主设备持续发送SCL时钟,从设备返回地址+1寄存器的值以此类推;

        7、主设备发送停止位,读通信结束;

        如果对上面RESTART不好理解,读操作也可进行如下通信:

                                        图9 STOP-START IIC读操作

        这里操作上和RESTART基本类似,不同的是每一个START都配有一个STOP,首先写指定要读的地址,再对指定地址读操作。

        

        如有疑问可以留言。

        

### I2C协议时序图及其通信机制 I2C(Inter-Integrated Circuit)是一种广泛应用于嵌入式系统的同步串行通信协议,主要用于短距离通信。它通过两根线实现多设备之间的数据交互:一根时钟线(SCL),另一根数据线(SDA)。以下是关于I2C协议时序图及相关硬件设计的关键点: #### 1. 基本时序结构 I2C协议的时序由启动条件、停止条件以及数据传输组成。具体描述如下: - **启动条件**:当SCL保持高电平时,SDA从高电平变为低电平表示一次通信的开始[^1]。 - **停止条件**:当SCL保持高电平时,SDA从低电平变为高电平表示一次通信的结束[^4]。 #### 2. 数据传输过程 在每次数据传输过程中,每8位数据之后都会有一个应答位(ACK/NACK)。主设备发送每一位数据后,等待从设备返回一个确认信号(ACK)或者不确认信号(NACK)。这种机制确保了数据传输的可靠性[^2]。 #### 3. 上拉电阻的作用 由于I2C总线采用开漏输出的方式工作,因此需要外部上拉电阻来保证线路能够被正确驱动到逻辑高电平状态。通常情况下,这些电阻连接至电源电压Vcc,并且阻值范围一般选取几千欧姆级别以平衡功耗与速度需求。 #### 4. 不同模式下的波特率设置 标准模式下,I2C支持最高达100kHz 的频率;快速模式则可达到400kHz 。某些扩展版本还提供了更快的速度选项比如高速模式(High Speed Mode),可达3.4MHz [^2]. #### 示例代码展示如何利用库函数完成单字节写操作: ```c #include <linux/i2c-dev.h> int file; if ((file = open("/dev/i2c-1", O_RDWR)) < 0){ perror("Failed to open the bus."); } ioctl(file, I2C_SLAVE, ADDRESS); i2c_smbus_write_byte(file, DATA); // 使用此函数向指定地址写入单一字节的数据 close(file); ``` 上述代码片段展示了如何借助Linux环境下的`i2c-tools`工具包所提供的API接口执行简单的I2C事务处理流程——即针对某个特定目标节点推送给定数值的操作实例说明[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值