1. I2C 时钟延展:从设备的'叫停'艺术
简单来说,时钟延展就是 I2C 从设备的一种'叫停'机制。在标准 I2C 协议中,主设备像是个急性子的领导,不停地向下属(从设备)下达指令。但如果下属需要时间处理当前任务,他就会举手说'请稍等'。在 I2C 世界里,这个'举手'动作就是从设备拉低 SCL 时钟线的行为。
2. 时钟延展的工作原理与触发条件
2.1 时钟延展的底层机制
时钟延展的本质是从设备对总线控制权的临时获取。在标准 I2C 协议中,时钟线 SCL 完全由主设备控制,但从设备在特定情况下可以介入并延长时钟低电平的时间。
从硬件层面来看,当时钟延展发生时,从设备会在主设备释放 SCL 线(试图拉高)后立即将其拉低并保持。这个过程发生在纳秒级别,要求主设备必须实时检测 SCL 线的实际状态,而不是简单地输出时钟信号。
// 错误的做法(不检测时钟延展)
void i2c_write_byte(uint8_t data) {
for(int i = 0; i < 8; i++) {
set_scl_low();
delay_us(1);
set_sda((data >> (7-i)) & 0x01);
delay_us(1);
set_scl_high();
// 直接拉高,不检测从设备是否延展
delay_us(1);
}
}
// 正确的做法(处理时钟延展)
void i2c_write_byte(uint8_t data) {
for(int i = 0; i < 8; i++) {
set_scl_low();
delay_us(1);
set_sda((data >> (7-i)) & 0x01);
delay_us(1);
// 释放 SCL 并检测是否被从设备拉低
set_scl_high();
while(read_scl() == 0) {
// 等待从设备释放 SCL
delay_us(1);
}
}
}

