3. Sensor I2C接口规范:常见Sensor的从机地址与寄存器读写时序
在RK平台驱动开发中,I2C通信是连接主控与Sensor最常用的物理层协议。理解Sensor的I2C接口规范,包括从机地址、寄存器映射以及读写时序,是进行故障排查的基础。本章将系统梳理IMU、温湿度、光感这三类典型Sensor的I2C规范差异,并给出标准时序分析。
3.1 I2C从机地址:7位与8位之争
Sensor的I2C从机地址通常由器件型号和外部引脚电平共同决定。驱动开发中最大的混淆点在于7位地址与8位地址的表示差异。
| 地址类型 | 说明 | 示例(ICM-20602) | 驱动中常用写法 |
|---|---|---|---|
| 7位地址 | 器件手册给出的原始地址,高7位有效 | 0x68 | I2C_SLAVE_ADDR = 0x68 |
| 8位地址 | 7位地址左移1位,最低位为R/W位 | 0xD0(写)/ 0xD1(读) | Linux内核使用7位地址 |
常见踩坑点:部分Sensor数据手册中标注的地址为8位格式(如0xD0),若直接写入驱动,会导致I2C控制器发送错误的从机ID,产生NACK。务必确认手册中地址是7位还是8位,RK平台I2C驱动统一使用7位地址。
3.2 寄存器读写时序标准模型
所有I2C Sensor的寄存器读写都遵循“先写寄存器地址,再读写数据”的复合帧格式。以下为标准时序模型:
写寄存器时序: START + 从机地址(W) + ACK + 寄存器地址 + ACK + 数据字节 + ACK + STOP
读寄存器时序: START + 从机地址(W) + ACK + 寄存器地址 + ACK + (RESTART) + 从机地址(R) + ACK + 数据字节 + NACK + STOP
读寄存器时序: START + 从机地址(W) + ACK + 寄存器地址 + ACK + (RESTART) + 从机地址(R) + ACK + 数据字节 + NACK + STOP
下面通过SVG图展示标准单字节读写时序的波形抽象:
3.3 常见Sensor I2C规范对比
不同Sensor的I2C接口在从机地址、寄存器位宽、最大速率、是否支持多字节读写等方面存在差异。下表汇总了RK平台开发中常见的Sensor型号:
| Sensor类型 | 典型型号 | 7位从机地址 | 寄存器位宽 | 最大速率 | 多字节支持 |
|---|---|---|---|---|---|
| IMU(6轴) | ICM-20602 | 0x68 / 0x69 | 8位 | 400kHz(FM) | 支持(Burst Read) |
| IMU(9轴) | MPU-9250 | 0x68 | 8位 | 400kHz(FM) | 支持 |
| 温湿度 | SHT30 | 0x44 / 0x45 | 16位 | 1MHz(Fm+) | 支持(命令模式) |
| 温湿度 | HDC1080 | 0x40 | 16位 | 400kHz(FM) | 支持 |
| 光感 | APDS-9930 | 0x39 | 8位 | 400kHz(FM) | 支持(Burst Read) |
| 光感 | LTR-559 | 0x23 | 8位 | 400kHz(FM) | 支持 |
3.4 IMU Sensor典型寄存器读写流程
以ICM-20602为例,IMU Sensor的I2C访问通常包含以下步骤:
- 上电延迟:VDD上电后需等待至少10ms,等待内部上电复位完成。
- 读WHO_AM_I寄存器(地址0x75):验证从机地址和通信链路是否正常,期望值0x12。
- 写电源管理寄存器(PWR_MGMT_1,地址0x6B):清除休眠位,写入0x00唤醒Sensor。
- 配置采样率与量程:写SMPLRT_DIV(0x19)和GYRO_CONFIG(0x1B)等寄存器。
- 读取数据寄存器:从ACCEL_XOUT_H(0x3B)开始连续读取14字节(加速度+温度+陀螺仪)。
调试技巧:在RK平台驱动probe函数中,第一步应读取WHO_AM_I寄存器。如果返回0xFF或0x00,说明I2C通信异常,应检查硬件连接、电平匹配和从机地址配置。
3.5 温湿度Sensor特殊时序:命令触发模式
与IMU不同,部分温湿度Sensor(如SHT30)采用命令触发模式,主机需要先发送特定命令码,Sensor才会启动测量并返回数据。SHT30的典型读写流程如下:
/* SHT30 单次测量命令:0x2C 0x06 */
/* 写命令时序 */
uint8_t cmd[2] = {0x2C, 0x06};
i2c_master_send(client, cmd, 2); // 发送命令,无寄存器地址
/* 等待测量完成(约15ms) */
mdelay(15);
/* 读取6字节数据:温度高8位 + 温度低8位 + CRC + 湿度高8位 + 湿度低8位 + CRC */
uint8_t buf[6];
i2c_master_recv(client, buf, 6); // 直接读取,无需指定寄存器地址
注意:SHT30等Sensor的I2C接口没有传统意义上的寄存器地址映射,而是通过命令码控制。驱动中不能使用标准的regmap API,需要直接调用i2c_transfer。在RK平台调试时,应使用i2c-tools的i2cset/i2cget命令发送原始命令进行验证。
3.6 光感Sensor:中断寄存器与轮询模式
光感Sensor(如APDS-9930)通常支持中断输出和轮询读取两种模式。其I2C寄存器访问具有以下特点:
- 控制寄存器(0x80):使能ALS和Proximity功能,写入0x0F开启所有功能。
- 中断标志寄存器(0xE0):读取后自动清除中断状态。
- 数据寄存器(0x14-0x17):ALS数据为16位,分两个8位寄存器存储。
- 多字节读取:支持从起始地址连续读取,地址自动递增。
下面通过SVG图展示APDS-9930的I2C寄存器空间布局:
3.7 多字节读写与Burst模式
为提高数据读取效率,大多数Sensor支持Burst模式(多字节连续读取)。驱动中应优先使用多字节传输,减少I2C总线开销。
| 传输模式 | I2C帧结构 | 适用场景 | 效率对比 |
|---|---|---|---|
| 单字节读写 | 每字节一次START-STOP | 配置寄存器、单次控制 | 低(每次约200μs@400kHz) |
| 多字节连续读写 | 一次START,连续传输N字节后STOP | 读取IMU 6轴数据、ALS数据 | 高(14字节约35μs) |
| Burst模式 | 指定起始地址后,自动递增地址连续读取 | 批量数据采集、FIFO读取 | 最高(适合DMA传输) |
RK平台驱动优化建议:在读取IMU加速度计和陀螺仪数据时,应使用i2c_master_send发送起始寄存器地址,然后使用i2c_master_recv一次性读取14字节,避免逐字节读取导致的时序延迟和数据不一致。
3.8 常见I2C时序故障与排查方向
基于上述接口规范,Sensor I2C通信故障可归纳为以下几类:
- 从机地址不匹配:7位/8位混淆、ADDR引脚电平配置错误、地址冲突(多设备共用总线)。
- 寄存器地址错误:16位地址只发送了8位、地址未左移、寄存器映射版本不匹配。
- 时序违规:SCL频率超过Sensor最大速率、START条件保持时间不足、STOP条件建立时间不够。
- NACK响应:从机忙(如温湿度Sensor正在转换)、地址错误、总线被拉死。
- 数据错位:多字节读取时字节顺序错误(大端/小端)、CRC校验失败(温湿度Sensor常见)。
快速定位方法:使用RK平台的i2c-tools工具,通过i2cdetect -y <bus>扫描总线上的设备,确认从机地址是否响应。然后使用i2cget -y <bus> <addr> <reg>读取WHO_AM_I寄存器,验证通信链路完整性。