I2C总线大家都不陌生,标准模式下7位地址最多挂127个从机,但实际项目中经常遇到地址冲突的问题——两个传感器刚好地址一样怎么办?大多数人的第一反应是换地址引脚,但很多从设备根本没地址引脚可选。这时候9位地址扩展(也叫CBUS模式或者TCAA)就能派上用场。
先说原理。标准I2C的地址是7位加1位读写位,共8位一个字节。9位地址模式把地址扩展到了8位,读写位单独放在下一个字节里。主机发第一个字节是8位地址(高7位+扩展位),如果从设备支持9位地址且地址匹配,就响应;然后主机再发第二个字节,高7位是读/写标志,最低位是原来的读写位。这样可用地址空间从127个扩展到了上千个,解决地址冲突的能力大大增强。
但9位地址不是所有I2C设备都支持的。从设备必须实现TCAA(Two Byte Addressing with ACK)机制,也就是收到8位地址后能正确匹配并响应。现在支持9位地址的芯片越来越多了,比如TI的LDC1314/LDC1614电感数字转换器、ADI的ADXL355加速度计都是支持的。买芯片之前查数据手册,看有没有"9-bit addressing"或者"TCAA"的说明。
软件上怎么实现?以STM32 HAL库为例,HAL_I2C_Mem_Read这类函数的参数里,DeviceAddress可以传8位地址(左移一位后的完整地址),如果从设备支持9位地址,就把完整的8位地址传进去,不用左移。但要注意,9位地址模式下所有挂载的设备都必须支持9位寻址,标准7位地址的设备混在一起会导致通讯失败,因为7位设备收到9位地址的第一个字节后可能不响应或者响应混乱。
还有一种变通办法是用I2C开关或者多路复用器,比如PCA9548A。它本身是个I2C设备,通过寄存器控制把主I2C总线切换到8路从总线中的某一路。这样每组从总线里可以有相同地址的设备,只要不跨组冲突就行。这种方法比9位地址兼容更好,老设备也能用,但代价是多了一个开关芯片,占了一个额外的I2C地址。
实际项目中怎么选?如果用的芯片原生支持9位地址,而且总线上没有7位设备,那就直接上9位地址,软件改动不大。如果总线上有老设备混用,或者芯片不支持9位地址,那就用多路复用器更稳妥。另外要注意9位地址模式下的起始条件和停止条件跟标准模式一样,ACK/NACK的处理也一样,只是地址字节多了一位,读操作时主机要发两次地址字节。
上一篇:caiji-test
下一篇:没有了