2. I2C协议基础:7位与10位寻址模式、读写操作位、ACK/NACK机制
I2C(Inter-Integrated Circuit)总线是一种由Philips(现NXP)开发的两线式串行通信协议,广泛应用于嵌入式系统中连接微控制器与外围设备(如传感器、EEPROM、ADC/DAC、IO扩展芯片等)。在QNX I2C驱动开发中,深刻理解协议层的寻址模式、读写控制与应答机制是正确配置通信接口参数、定位总线故障的前提。
2.1 7位与10位寻址模式
I2C总线上的每个从设备都有一个唯一的地址。标准模式支持7位地址,最多可挂载112个节点(保留地址除外);扩展模式支持10位地址,允许更多设备共存。QNX的I2C驱动接口(如 i2c_open()、i2c_read()、i2c_write())通过标志位区分两种寻址模式。
2.1.1 7位寻址
- 地址范围:0x00 ~ 0x7F(其中0x00为通用呼叫地址,0x01~0x07为保留地址,实际可用0x08~0x77)。
- 传输格式:主设备发送起始条件后,先发送7位从机地址 + 1位读写位(R/W),共8位。
- 典型应用:大多数I2C传感器(如温度传感器TMP102、加速度计MPU6050)使用7位地址。
QNX驱动配置要点:在
i2c_send() 或 i2c_recv() 的参数中,地址字段直接填入7位地址(左对齐,高7位有效),驱动内部会自动左移1位并拼接读写位。
2.1.2 10位寻址
- 地址范围:0x00 ~ 0x3FF(10位地址空间)。
- 传输格式:分两阶段发送。第一阶段:11110XX + R/W(其中XX为10位地址的高2位);第二阶段:发送剩余8位地址。
- 兼容性:10位寻址设备可与7位设备共存于同一总线,但主设备必须支持10位寻址模式。
| 对比项 | 7位寻址 | 10位寻址 |
|---|---|---|
| 地址位数 | 7 bit | 10 bit |
| 最大设备数 | 112(扣除保留地址) | 1024 |
| 首字节格式 | AAAAAAA + R/W | 11110AA + R/W(AA为高2位) |
| 传输字节数 | 1字节地址 + 数据 | 2字节地址 + 数据 |
| QNX驱动标志 | I2C_ADDR_7BIT |
I2C_ADDR_10BIT |
开发建议:在QNX Resource Manager(资源管理器)中实现I2C驱动时,务必在
i2c_iofunc_attr_t 结构体中正确设置 addr_mode 字段。错误配置将导致地址无法被从设备识别,产生NACK响应。
2.2 读写操作位(R/W)
I2C通信中,每个地址字节的最低位(LSB)为读写控制位:
- R/W = 0:表示主设备将要写入数据到从设备(写操作)。
- R/W = 1:表示主设备将要读取从设备的数据(读操作)。
在QNX I2C驱动中,读写操作通常通过不同的API函数或标志位来区分:
| 操作类型 | QNX API函数 | R/W位值 | 数据方向 |
|---|---|---|---|
| 写操作 | i2c_write() / i2c_send() |
0 | 主设备 → 从设备 |
| 读操作 | i2c_read() / i2c_recv() |
1 | 从设备 → 主设备 |
| 复合操作 | i2c_write_read()(先写寄存器地址再读数据) |
0 → 1(重复起始条件) | 双向 |
常见故障点:在QNX驱动中,如果
i2c_write() 调用后未等待从设备内部处理完成(如EEPROM写入周期),紧接着调用 i2c_read() 可能导致总线冲突或数据错误。建议在写操作后加入适当延时或轮询从设备状态。
2.3 ACK/NACK机制
I2C总线使用应答(ACK)和非应答(NACK)机制来确保数据可靠传输。每个字节(包括地址字节和数据字节)传输完成后,接收方必须在第9个SCL时钟周期内拉低SDA线表示ACK,或保持高电平表示NACK。
2.3.1 应答规则
- 地址字节应答:从设备在收到匹配的地址后,必须发送ACK。如果总线上没有设备响应此地址,SDA保持高电平(NACK),主设备应发送停止条件终止传输。
- 数据字节应答:
- 写操作:从设备每收到一个数据字节后发送ACK。
- 读操作:主设备每收到一个数据字节后发送ACK;当主设备希望停止读取时,发送NACK并随后发送停止条件。
2.3.2 QNX驱动中的ACK/NACK处理
QNX I2C驱动框架在底层硬件抽象层(HAL)中处理ACK/NACK检测。驱动开发者需要关注以下状态:
/* QNX I2C驱动返回状态示例 */
#define I2C_STATUS_OK 0 /* 传输成功,收到ACK */
#define I2C_STATUS_NACK_ADDR -1 /* 地址NACK:无设备响应 */
#define I2C_STATUS_NACK_DATA -2 /* 数据NACK:从设备拒绝数据 */
#define I2C_STATUS_ARB_LOST -3 /* 仲裁丢失 */
故障排查要点:当QNX I2C驱动返回
I2C_STATUS_NACK_ADDR 时,应检查:① 从设备地址是否正确(7位/10位模式匹配);② 从设备是否上电并处于正常工作状态;③ 总线SCL/SDA电平是否被异常拉低(总线锁死)。返回 I2C_STATUS_NACK_DATA 时,通常表示从设备不支持当前操作(如写保护、寄存器不存在)。
2.4 本章小结
- 7位寻址是I2C最常用的模式,地址范围0x08~0x77,QNX驱动默认使用此模式。
- 10位寻址用于需要更多从设备的场景,需在QNX驱动中显式设置
I2C_ADDR_10BIT标志。 - 读写位(R/W)控制数据方向,QNX通过
i2c_write()和i2c_read()等API封装了底层位操作。 - ACK/NACK机制是I2C总线可靠性的核心,QNX驱动返回的状态码直接反映应答结果,是故障排查的第一手信息。