1. I2C总线协议基础
I2C(Inter-Integrated Circuit)总线是由Philips公司(现NXP)开发的一种同步、多主从、串行通信总线。它仅需两根信号线即可完成设备间的数据交换,是嵌入式系统中连接传感器、EEPROM、ADC/DAC、实时时钟等外设最常用的总线之一。理解I2C总线的物理层特性、信号时序和拓扑结构,是编写正确、健壮的Linux I2C设备驱动的前提。
学习提示: I2C总线协议虽然简单,但物理层细节(如上拉电阻选择、总线电容限制、电平标准)直接影响驱动稳定性和通信速率。在驱动调试中,超过70%的I2C通信故障源于物理层配置不当,而非软件逻辑错误。
1.1 I2C总线物理层特性
I2C总线使用两根双向开漏(Open-Drain)信号线:串行数据线(SDA)和串行时钟线(SCL)。所有设备通过开漏输出连接到总线,并通过外部上拉电阻将总线拉至高电平。
| 特性 | 说明 | 典型值/范围 |
|---|---|---|
| 信号线数量 | SDA(数据)、SCL(时钟) | 2根 |
| 输出类型 | 开漏(Open-Drain) | — |
| 上拉电阻 | 外部上拉至VDD | 1kΩ ~ 10kΩ(取决于总线电容和速率) |
| 逻辑电平 | 低电平=GND,高电平=VDD | 1.8V / 3.3V / 5V(需兼容) |
| 最大总线电容 | 限制从设备数量和布线长度 | 标准模式400pF,快速模式550pF |
| 最大从设备数量 | 受限于7位或10位地址空间 | 7位地址:最多112个(保留地址除外) |
| 通信速率 | 标准模式 / 快速模式 / 高速模式 | 100kHz / 400kHz / 3.4MHz |
工程注意: 上拉电阻的选择需权衡功耗和信号上升时间。电阻过小会导致低电平电流过大,增加功耗;电阻过大会使上升沿变缓,限制通信速率。对于400kHz快速模式,3.3V系统通常选用4.7kΩ上拉电阻。
1.2 SDA与SCL信号
SDA和SCL信号在I2C总线中承担不同角色,两者配合完成数据帧的传输。SCL由主设备产生,用于同步数据传输;SDA用于传输地址、读写标志、数据和应答信号。
I2C总线的信号定义遵循以下规则:
- 数据有效性: 在SCL高电平期间,SDA上的数据必须保持稳定;SCL低电平期间,SDA允许变化。
- 起始条件(START): SCL为高电平时,SDA从高电平切换到低电平。
- 停止条件(STOP): SCL为高电平时,SDA从低电平切换到高电平。
- 应答(ACK): 每传输8位数据后,接收方在第9个SCL周期将SDA拉低,表示应答。
- 非应答(NACK): 接收方在第9个SCL周期保持SDA为高电平,表示非应答。
1.3 I2C总线拓扑结构
I2C总线采用多主从总线拓扑结构。所有设备通过SDA和SCL两条线并联连接,每个设备都有一个唯一的地址。主设备(Master)负责产生时钟、发起通信和终止通信;从设备(Slave)监听总线地址,响应主设备的请求。
I2C总线拓扑的关键特征:
- 多主设备支持: 多个主设备可以共享同一总线,通过仲裁机制决定总线控制权。
- 地址唯一性: 每个从设备必须拥有唯一的7位或10位地址,地址冲突会导致通信混乱。
- 总线长度限制: 受总线电容限制,标准模式总线长度一般不超过1米(400pF电容限制)。
- 设备数量限制: 7位地址模式下,除去保留地址(0x00~0x07、0x78~0x7F),最多可挂载112个从设备。
1.4 I2C总线通信流程
一次完整的I2C通信流程包含以下步骤:
- 主设备发送起始条件(START): SCL高电平时,SDA从高变低。
- 主设备发送从设备地址和读写位: 7位地址 + 1位读写标志(0=写,1=读),共8位。
- 从设备应答(ACK): 地址匹配的从设备在第9个SCL周期拉低SDA。
- 数据传输: 主设备(写操作)或从设备(读操作)逐字节发送数据,每字节后跟ACK。
- 主设备发送停止条件(STOP): SCL高电平时,SDA从低变高,释放总线。
驱动开发要点: 在Linux内核中,I2C通信流程被封装在
struct i2c_msg 结构体和 i2c_transfer() 函数中。驱动开发者无需手动操作SDA/SCL时序,只需构造消息数组并调用传输接口。但理解底层时序对调试通信异常(如ACK丢失、时钟拉伸)至关重要。
1.5 I2C地址与速率模式
| 参数 | 7位地址模式 | 10位地址模式 |
|---|---|---|
| 地址范围 | 0x00 ~ 0x7F | 0x000 ~ 0x3FF |
| 可用地址数 | 112(保留16个) | 1024 |
| 地址帧长度 | 1字节(地址+读写位) | 2字节(首字节1111 0XX + 第二字节) |
| 兼容性 | 所有设备支持 | 仅10位地址设备支持 |
| Linux驱动支持 | 完全支持 | 支持(需设置I2C_M_TEN标志) |
I2C总线支持多种速率模式,驱动开发中需根据从设备数据手册选择正确的速率:
- 标准模式(Standard-mode, Sm): 100kHz,兼容性最好,适用于大多数低速传感器。
- 快速模式(Fast-mode, Fm): 400kHz,常用速率,需注意总线电容和上拉电阻。
- 快速模式+(Fast-mode Plus, Fm+): 1MHz,需要更强的驱动能力和更小的上拉电阻。
- 高速模式(High-speed mode, Hs-mode): 3.4MHz,需特殊硬件支持,驱动中需处理高速模式切换。
速率选择警告: 在Linux设备树中,通过
clock-frequency 属性设置I2C控制器速率。切勿将速率设置得高于从设备支持的最大值,否则可能导致通信失败或数据损坏。对于未知设备,优先使用100kHz标准模式进行调试。