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

下面通过SVG图展示标准单字节读写时序的波形抽象:

标准I2C Sensor寄存器读写时序(单字节) 写时序: START SLAVE_W ACK REG_ADDR ACK DATA ACK STOP 读时序: START SLAVE_W ACK REG_ADDR ACK RESTART SLAVE_R ACK DATA NACK STOP 关键说明: 1. 写时序:主机发送从机地址+W位后,直接发送寄存器地址,再发送数据字节。 2. 读时序:主机先写寄存器地址,然后产生RESTART条件,重新发送从机地址+R位,从机返回数据。 3. 读时序最后一个字节主机发送NACK,表示读取结束,从机释放总线。

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访问通常包含以下步骤:

  1. 上电延迟:VDD上电后需等待至少10ms,等待内部上电复位完成。
  2. 读WHO_AM_I寄存器(地址0x75):验证从机地址和通信链路是否正常,期望值0x12。
  3. 写电源管理寄存器(PWR_MGMT_1,地址0x6B):清除休眠位,写入0x00唤醒Sensor。
  4. 配置采样率与量程:写SMPLRT_DIV(0x19)和GYRO_CONFIG(0x1B)等寄存器。
  5. 读取数据寄存器:从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寄存器空间布局:

APDS-9930 光感Sensor I2C寄存器空间布局 0x80 控制寄存器 0x14 ALS数据低8位 0x15 ALS数据高8位 0xE0 中断标志 0xE4 中断阈值 控制与配置区(0x80-0x8F) 使能、增益、等待时间等配置 数据读取区(0x14-0x17) ALS和Proximity原始数据 中断控制区(0xE0-0xE7) 中断标志、阈值设置 光感Sensor I2C调试要点: 1. 光感Sensor通常支持自动递增地址,读取ALS数据时只需发送起始地址0x14,然后连续读取4字节。 2. 中断寄存器读取后自动清零,驱动中应在中断服务程序(ISR)中立即读取数据寄存器。 3. 部分光感Sensor(如LTR-559)的寄存器地址为16位,需要发送2字节地址。

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寄存器,验证通信链路完整性。