# IIC ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # 功能概述 ## IIC概述 ### 基本定义 IIC(Inter-Integrated Circuit,也称I2C)总线是一种由Philips公司开发的两线式串行总线,用于连接微控制器及其外围设备。 IIC是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。IIC接口使用主机和从机的概念,通常一个主机会搭配一个或多个从机,主机负责启动和结束通信会话。 IIC拓扑结构如下: ```{image} images/image_Fop6boeJAoEqNFxf2BWcfgBAnTd.webp :width: 602px :height: 233px :align: center ``` ### 核心特点 - **两线制设计**:仅需SDA(数据线)和SCL(时钟线)两根信号线,SDA用来传输数据,SCL用来同步数据收发。 - **多主多从架构**:支持多个主设备和多个从设备。 - **地址识别**:总线上每一个器件都有一个唯一的地址识别,只需知道器件地址,即可根据时序实现微控制器与器件之间的通信。 - **双向通信**:数据线SDA和时钟线SCL都是双向线路,都通过一个电流源或上拉电阻连接到正的电压,所以当总线空闲的时候,这两条线路都是高电平。 - **应答机制**:内置ACK/NACK确认机制,确保数据传输可靠性。 ### 传输速率 IIC支持多种传输速率模式: - **标准模式**:100 kbit/s - **快速模式**:400 kbit/s - **高速模式**:3.4 Mbit/s - **超快速模式**:5 Mbit/s(较少使用) ## IIC通信协议详解 ### 时序介绍 - **空闲电平**:SCL和SDA均为高电平。 - **起始信号时序**:SCL为高电平(空闲)时,SDA由高电平到低电平的跳变。 ```{image} images/image_C7E0bTYx8oq842xAcr7cx7wonlf.webp :width: 390px :height: 255px :align: center ``` - **结束信号时序**:SCL为高电平(空闲)时,SDA由低电平到高电平的跳变。 ```{image} images/image_O1GGbOQZLodoLpxfxI9cDfo6nrg.webp :width: 367px :height: 257px :align: center ``` - **应答信号时序**:接收端收到有效数据后向对方响应的信号,发送端每发送一个字节(8位)数据,在第9个时钟周期释放数据线去接收对方的应答。 当SDA是低电平为有效应答(ACK),表示对方接收成功;当SDA是高电平为无效应答(NACK),表示对方没有接收成功。 - **数据传输时序**:SCL低电平时,允许数据位变化。每8位数据传输完成后,从机将拉低SDA线,回传主机一位ACK信号;或拉高SDA线,回传主机一位NACK信号。 ```{image} images/image_Xy1ObDey5orjTYxokZXcPh59ngc.webp :width: 671px :height: 252px :align: center ``` ### 数据帧格式 IIC通信由起始信号、地址帧、应答信号(ACK/NACK)、数据帧、停止信号组成。 1. **起始条件(Start Condition)**:SCL为高电平时,SDA从高电平跳变到低电平,标志一次传输开始。 2. **地址帧(Address Frame)**:7位地址模式下,主设备发送7位从设备地址+1位读写控制位(0:写,1:读);10位地址模式(扩展模式)下分两次发送,第一字节前5位固定为11110,后接2位高位地址和读写位,第二字节为剩余8位地址。 3. **应答信号(ACK/NACK)**:每传输完一个字节(8位)后,接收方需在第9个时钟周期发送应答信号。ACK:SDA拉低,表示成功接收;NACK:SDA保持高电平,表示接收失败或传输结束。 4. **数据帧(Data Frame)**:数据按字节传输(8位),高位(MSB)在前,每个数据帧后必须跟随ACK/NACK信号。 5. **停止条件(Stop Condition)**:SCL为高电平时,SDA从低电平跳变到高电平,标志一次传输结束。 ### 完整通信过程 #### 主机写操作 1. 主机产生并发送起始信号。 2. 主机发送从机地址+写标志位(R/W=0)。 3. 从机接收到地址后返回ACK应答信号。 4. 主机发送要写入的寄存器地址。 5. 从机接收到寄存器地址后返回ACK应答信号。 6. 主机发送第一个数据字节。 7. 从机接收到数据后返回ACK应答信号。 8. 重复步骤6-7完成多个字节的写入。 9. 主机发送停止信号结束通信。 ```{image} images/image_F7vPb0clXoZOzexkAXvcOByMnff.webp :width: 860px :height: 208px :align: center ``` #### 主机读操作 1. 主机产生并发送起始信号。 2. 主机发送从机地址+写标志位(R/W=0),用于设置寄存器地址。 3. 从机接收到地址后返回ACK应答信号。 4. 主机发送要读取的寄存器地址。 5. 从机接收到寄存器地址后返回ACK应答信号。 6. 主机再次发送起始信号(重复起始)。 7. 主机发送从机地址+读标志位(R/W=1)。 8. 从机接收到读请求后返回ACK应答信号。 9. 从机开始发送数据字节。 10. 主机接收到数据后发送ACK(继续读取)或NACK(结束读取)。 11. 重复步骤9-10完成多个字节的读取。 12. 主机发送停止信号结束通信。 ```{image} images/image_UiucbHlkZoYdZExcGD4cOFLenSk.webp :width: 1060px :height: 205px :align: center ``` ### IIC的优缺点 **优点:** - **简化的硬件接口**:只需要两条线(SDA和SCL)即可实现多个设备之间的通信。 - **多主机能力**:支持多个主机同时连接到同一总线上。 - **同步通信**:数据传输是时钟同步的,确保数据的准确性和一致性。 - **可扩展性**:允许通过增加更多的从设备来扩展系统。 - **时钟伸展**:支持时钟伸展功能,允许从设备在需要时暂停总线。 - **广泛的支持**:许多微控制器和外围设备都内置了对IIC的支持。 - **可靠的应答机制**:从设备通过ACK确认接收,保证数据可靠性。 **缺点:** - **速度限制**:最高速率3.4 Mbit/s,低于SPI等高速协议。 - **总线冲突**:多主机系统中可能出现总线冲突。 - **总线仲裁复杂性**:多主机系统中需要复杂的仲裁机制。 - **信号完整性问题**:开漏输出结构在长距离传输或高速模式下可能影响信号质量。 - **错误检测限制**:没有内置的错误检测机制如CRC。 - **总线负载能力**:过多的从设备可能会导致总线响应变慢。 - **软件复杂性**:时序控制和错误处理相对复杂。 ### IIC与其他协议比较 | **特性** | **IIC** | **SPI** | **UART** | | --- | --- | --- | --- | | 通信方式 | 同步、半双工 | 同步、全双工 | 异步、全双工 | | 信号线数量 | 2根(SDA、SCL) | 4根(SCK、MOSI、MISO、CS) | 2根(TX、RX) | | 寻址方式 | 7/10位地址 | 硬件片选(CS) | 无(点对点) | | 多设备支持 | 多主多从 | 一主多从 | 点对点 | | 速率 | 中(标准模式100 kbit/s,高速模式3.4 Mbit/s) | 高(可达数十Mbit/s) | 低(通常低于1 Mbit/s) | | 应答机制 | 有(ACK/NACK) | 无 | 无 | | 硬件复杂度 | 中等 | 中等 | 低 | | 典型应用 | 低速多设备通信 | 高速外设通信 | 点对点通信 | ### IIC的选择建议 **适合选择IIC的场景** - **多设备低速组网**:主板内多个传感器、EEPROM等外设通信。 - **引脚资源有限**:仅需2根线即可连接多个设备。 - **简单的设备控制**:传感器、RTC、LED驱动等低速外设。 - **需要地址识别**:多个相同类型设备需要区分时。 - **功耗敏感应用**:支持低功耗模式和时钟伸展。 **不适合选择IIC的场景** - **高速数据传输**:如视频、音频等大数据量应用。 - **长距离通信**:超过1米的板间通信。 - **严格实时性要求**:需要微秒级响应的控制系统。 - **大量设备连接**:超过10个设备可能导致总线负载过重。 - **复杂的错误处理**:需要高级错误检测和恢复机制。 # IIC API ## 头文件 *qosa_iic.h* ## 函数概览 | **函数** | **说明** | | --- | --- | | *qosa_i2c_init()* | 初始化IIC配置 | | *qosa_i2c_deinit()* | 释放IIC资源 | | *qosa_i2c_write()* | 使用IIC发送数据 | | *qosa_i2c_read()* | 使用IIC读取数据 | ## 函数详解 ### qosa_i2c_init - **功能描述** 初始化IIC配置。 - **函数原型** ```c qosa_i2c_error_e qosa_i2c_init(qosa_i2c_channel_e i2c_no, qosa_i2c_mode_e Mode) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *i2c_no* | 输入 | *qosa_i2c_channel_e* | 需要初始化的IIC通道;详见 [*qosa_i2c_channel_e*](#qosai2cchannel_e) | | *Mode* | 输入 | *qosa_i2c_mode_e* | 配置IIC传输模式,如标准模式 *QOSA_IIC_STANDARD_MODE*;详见 [*qosa_i2c_mode_e*](#qosai2cmode_e) | - **返回值说明** *QOSA_I2C_SUCCESS*:函数执行成功 其他值(详见 [*qosa_i2c_error_e*](#qosai2cerror_e)):函数执行失败 ### qosa_i2c_deinit - **功能描述** 释放IIC资源。 - **函数原型** ```c qosa_i2c_error_e qosa_i2c_deinit(qosa_i2c_channel_e i2c_no) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *i2c_no* | 输入 | *qosa_i2c_channel_e* | 需要释放的IIC通道;详见 [*qosa_i2c_channel_e*](#qosai2cchannel_e) | - **返回值说明** *QOSA_I2C_SUCCESS*:函数执行成功 其他值(详见 [*qosa_i2c_error_e*](#qosai2cerror_e)):函数执行失败 ### qosa_i2c_write - **功能描述** 使用IIC发送数据。 - **函数原型** ```c qosa_i2c_error_e qosa_i2c_write(qosa_i2c_channel_e i2c_no, qosa_uint8_t slave, qosa_uint16_t addr, qosa_uint8_t *data, qosa_uint32_t length) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *i2c_no* | 输入 | *qosa_i2c_channel_e* | 需要写入数据的IIC通道;详见 [*qosa_i2c_channel_e*](#qosai2cchannel_e) | | *slave* | 输入 | qosa_uint8_t | 需要写入数据的从机设备地址 | | *addr* | 输入 | qosa_uint16_t | 需要写入数据的寄存器地址 | | *data* | 输入 | qosa_uint8_t * | 需要写入的数据 | | *length* | 输入 | qosa_uint32_t | 需要写入的数据长度;单位:字节 | - **返回值说明** *QOSA_I2C_SUCCESS*:函数执行成功 其他值(详见 [*qosa_i2c_error_e*](#qosai2cerror_e)):函数执行失败 ### qosa_i2c_read - **功能描述** 使用IIC读取数据。 - **函数原型** ```c qosa_i2c_error_e qosa_i2c_read(qosa_i2c_channel_e i2c_no, qosa_uint8_t slave, qosa_uint16_t addr, qosa_uint8_t *data, qosa_uint32_t length) ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *i2c_no* | 输入 | *qosa_i2c_channel_e* | 需要读取数据的IIC通道;详见 [*qosa_i2c_channel_e*](#qosai2cchannel_e) | | *slave* | 输入 | qosa_uint8_t | 需要读取数据的从机设备地址 | | *addr* | 输入 | qosa_uint16_t | 需要读取数据的寄存器地址 | | *data* | 输出 | qosa_uint8_t * | 用于接收读取的数据 | | *length* | 输入 | qosa_uint32_t | 需要读取的数据长度;单位:字节 | - **返回值说明** *QOSA_I2C_SUCCESS*:函数执行成功 其他值(详见 [*qosa_i2c_error_e*](#qosai2cerror_e)):函数执行失败 ## 枚举定义 ### qosa_i2c_channel_e IIC通道枚举定义如下: ```c typedef enum { QOSA_I2C_0 = 0, QOSA_I2C_1, QOSA_I2C_2, QOSA_I2C_3, } qosa_i2c_channel_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_I2C_0* | IIC通道0 | | *QOSA_I2C_1* | IIC通道1 | | *QOSA_I2C_2* | IIC通道2 | | *QOSA_I2C_3* | IIC通道3 | ### qosa_i2c_mode_e IIC传输模式枚举定义如下: ```c typedef enum { QOSA_IIC_SLOW_MODE = 1, QOSA_IIC_STANDARD_MODE = 2, QOSA_IIC_FAST_MODE = 3, QOSA_IIC_FAST_PLUS_MODE = 4, QOSA_IIC_HIGH_SPEED_MODE = 5, } qosa_i2c_mode_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_IIC_SLOW_MODE* | 慢速模式;速率:50 kbit/s | | *QOSA_IIC_STANDARD_MODE* | 标准模式;速率:100 kbit/s | | *QOSA_IIC_FAST_MODE* | 快速模式;速率:400 kbit/s | | *QOSA_IIC_FAST_PLUS_MODE* | 快速+模式;速率:1 Mbit/s | | *QOSA_IIC_HIGH_SPEED_MODE* | 高速模式;速率:3.4 Mbit/s | ### qosa_i2c_error_e IIC操作错误码枚举定义如下: ```c typedef enum { QOSA_I2C_SUCCESS = 0, QOSA_I2C_EXECUTE_ERR = 1 | QOSA_I2C_ERRCODE_BASE, QOSA_I2C_INVALID_PARAM_ERR, QOSA_I2C_INIT_ERR, QOSA_I2C_RELEASE_ERR, QOSA_I2C_WRITE_ERR, QOSA_I2C_READ_ERR, } qosa_i2c_error_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_I2C_SUCCESS* | 函数执行成功 | | *QOSA_I2C_EXECUTE_ERR* | IIC执行错误 | | *QOSA_I2C_INVALID_PARAM_ERR* | 参数无效 | | *QOSA_I2C_INIT_ERR* | 初始化失败 | | *QOSA_I2C_RELEASE_ERR* | 释放失败 | | *QOSA_I2C_WRITE_ERR* | 写入失败 | | *QOSA_I2C_READ_ERR* | 读取失败 | # 应用逻辑流程图 ```{figure} images/board_Pvktwahjcha4WdbrLXOcBwfHnYc.jpg :align: center :alt: image ``` # 示例代码 完整示例代码请查看 https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/peripheral/i2c/iic_demo.c