一、IIC总线概述
- IIC(Inter-Integrated Circuit)即集成电路总线,用于板级芯片间通信,常见于传感器与主控芯片之间的数据交互。
- IIC由飞利浦公司开发,采用两线制:SCL(时钟线)和SDA(数据线),支持多主多从架构,通信中任一时刻仅一个主机主导。

- IIC通信方式为半双工、同步、串行,因其仅有一根数据线且有时钟线控制时序。
- 线与特性指当多个设备连接在同一总线上时,若任一设备将总线拉低,则整体呈现低电平,高电平需所有设备均释放总线。

- 总线空闲时为高电平,便于任意设备发起通信;上拉电阻(典型值4.7kΩ–10kΩ)用于提升驱动能力、延长传输距离,推荐默认选用10kΩ。

二、IIC通信时序

- 通信开始由主机发送起始信号(SCL高电平时SDA下降沿),结束于停止信号(SCL高电平时SDA上升沿)。
- 数据在SCL低电平时可改变,在SCL高电平时必须稳定供接收方采样,确保正确读取。
- 数据传输以字节为单位,高位(MSB)先行;每发送一个字节后需跟随一个应答位(ACK应答/NACK非应答)。
- 应答位由接收方在第9个时钟周期内拉低SDA表示ACK(确认收到),保持高电平则为NACK(未应答)。(注:第八个时钟周期后释放拉高数据总线便与区别从机的应答信号,第九个时钟周期后拉低数据总线为了区分结束信号)
- 单次通信可在START与STOP之间连续传输多个字节,每个字节后均有应答位,最终由主机发出STOP信号终止通信。
三、IIC协议层机制
- 起始信号后紧跟的第一个字节包含7位从机地址和1位数据方向位(R/W),用于指定目标设备及数据流向。

- 从机地址由厂商向飞利浦申请获得,保证全球唯一;若存在地址冲突,可通过挂接不同I²C总线解决。
- 数据方向位为0时表示主机写(主机发,从机收),为1时表示主机读(主机收,从机发)。
- 所有通信均由主机控制START与STOP信号,应答由接收方发出,确保通信有序进行。
四、AT24C02存储芯片应用
- AT24C02是一款I2C接口的EEPROM芯片,容量为2K比特(256字节),支持1.8V–5.5V宽电压工作。
- 芯片引脚包括SCL、SDA、VCC、GND、WP(写保护)以及A0–A2(地址选择引脚),通过A0–A2配置可实现 同一总线上最多挂载8个相同型号器件。
- 字节写操作流程:主机发送START → 发送设备地址+写位(0)→ 接收ACK → 发送字地址 → 接收ACK → 发送数据 → 接收ACK → 发送STOP。

- 页写操作允许连续写入多个字节,地址自动递增,受限于每页8字节边界。

- 当前地址读操作无需指定地址,直接从上次操作位置继续读取;随机读操作需先发送设备地址+写位及目标地址,再重启START并发送设备地址+读位以启动读取过程。


- 随机读采用两次START信号(无中间STOP),第一次用于发送地址(写模式),第二次用于启动读取(读模式),实现跨方向的数据访问。
五、I2C控制器原理与结构
- 介绍了IDOMAX芯片中I2C控制器的基本结构,包括时钟线(SCL)和数据线(SDA),以及内部包含的多个关键寄存器。
- 解释了I2C总线的主从机模式:主机发起通信(start信号),从机响应;控制器可作为主机或从机使用。
- 说明了I2C总线采用半双工通信方式,只有一根数据线,读写操作共用同一数据寄存器。
- 指出IDOMAX芯片内有四个I2C总线控制器(I2C1-I2C4),可通过引脚复用功能选择具体使用的控制器。
六、关键寄存器功能解析
- FREQUENCY寄存器(IFDR)用于设置分频系数,将66MHz外设时钟分频至目标频率(如100KHz),最接近的可用值为640分频(IC域值为0x15)。

- 控制寄存器(I2CR)包含多个控制位:IEN为模块使能位,MSTA为主从模式选择位(置1发start信号,清0发stop信号),MTX为发送/接收模式选择位。




- 状态寄存器(I2SR)包含重要状态标志:IIF为中断标志位(通信过程中需频繁检查),IBB为总线忙碌标志,IAL为仲裁丢失标志。

- 数据寄存器(I2DR)用于存放待发送或已接收的数据字节,读写操作均通过此寄存器完成。
- 地址寄存器(IADR)存储设备作为从机时的地址,本次实验作为主机使用故不涉及。
I2C初始化流程
- 首先进行引脚复用配置,将UART4的TXD/RXD引脚复用为I2C1的SCL/SDA功能,并设置SION位以支持物理引脚状态检测。
- 配置引脚电气特性,设置上拉电阻(PUE=1, PUS=0b11)和其他相关参数(PKE=1等),确保信号完整性。
- 初始化I2C模块:先清除IEN位使模块失能并触发硬件复位,然后设置IFDR分频值为0x15(640分频),最后重新使能IEN位完成初始化。
写操作函数实现
- 封装i2c_write函数,参数包括I2C基地址、从机地址、寄存器地址、数据指针和长度。
- 写操作流程:清除IAL和IIF标志 → 设置MTX为发送模式 → 置位MSTA产生start信号 → 发送(从机地址<<1)|0 → 等待应答(Ack)。
- 继续发送寄存器地址 → 等待应答 → 循环发送每个数据字节并等待每次应答。
- 所有数据发送完成后,清除MSTA位产生stop信号,并循环检测IBB位直到总线空闲。
- 实现wait_iif函数用于等待IIF标志置位,判断应答类型(RXAK),返回-1表示NACK异常。

读操作函数实现
- 封装i2c_read函数,基本流程前半部分与写操作相同:发送start信号 → 发送从机地址(写模式) → 发送寄存器地址 → 等待应答。
- 关键区别在于后续步骤:再次置位RSTA位产生restart信号 → 发送(从机地址<<1)|1(读模式) → 等待应答。
- 切换MTX为接收模式(MTX=0),根据数据长度设置应答方式:非最后一个字节回复ACK(TXAK=0),最后一个字节回复NACK(TXAK=1)。
- 实现伪读机制:首次读取数据寄存器以启动接收过程,随后在循环中等待IIF置位、读取数据,直至所有数据接收完毕。
- 最后产生stop信号并等待总线空闲,完成读取操作。
