Precondition: I2C的基础概念
- 飞利浦开发的双向二线制的同步串行总线, 两根线SCL+SDA,以bit为单位传输
- Bus 空闲状态:SCL和SDA均为高电平
- 起始信号
Start Condition - 停止信号
Stop Condition - 数据传输位
- 从机地址,I2C网络中只有一个主机,从机可有多个,具体数量取决于主从之间所定义的address的位数,7bit address还是10bit address.
(1)7bit address data format
(2)10bit address data format
[Note]: R/W bit meaning: 0 = write, 1= read
Additional Process: 读写的过程
[Note]: 注意所有的通信数据传输都是由Master发起的,不论是读写!两种模式的前提都是总线空闲(Bus Free)
写数据 (也可以叫做master向slave发送数据)
(1)Master 发送起始信号
(2)Master 发送I2C从机地址
[Note]:需要注意主机访问从机地址时由于是7bit address, 所以master在发送时会将从机地址右移一位发送。如从机地址是0x80(1000 0000),在发送的帧里的地址就是0x40 (0100 0000)
(3)Master 发送写信号(1 bit) = 0, 等待从机回复ACK。
(4)Master收到ACK之后, 开始多个字节发送, 格式可参考precondition 第6节的帧格式中的format. 并且每发送完一个字节之后都需要等待从机的ACK。
(5)发送完所有数据之后,发送停止信号,确保总线进入空闲状态。
读数据 (也可以叫做master向slave读取数据)
(1)Master 发送起始信号
(2)Master 发送I2C从机地址
[Note]:需要注意主机访问从机地址时由于是7bit address, 所以master在发送时会将从机地址右移一位发送。如从机地址是0x80(1000 0000),在发送的帧里的地址就是0x40 (0100 0000)
(3)Master 发送写信号(1 bit) = 1, 等待从机回复ACK。
(4)Master收到ACK之后, 开始多个字节读取, 格式可参考precondition 第6节的帧格式中的format. 并且每发送完一个字节之后都需要等待从机的ACK。
(5)发送完所有数据之后,发送停止信号,确保总线进入空闲状态。
**
I2C slave 调试过程中关注到的问题
一些共识性的问题潜在的误区:SCL信号一直是有Master端控制的
[Note]:I2C slave 模式下发送数据的过程中会有一个短暂的时间去hold SCL信号,直到本机发送数据准备好放进TXBuffer
引用一张MSP430中对于I2C slave transmit data的图来说明问题。
- [注意]:数据流里面灰色的表示Master控制的信号阶段,空白的表示Slave控制的信号阶段
造成最上面误区的地方就在于,在Master发完起始信号,从机地址,读写标志之后,Slave需要去拉低SCL电平,直到Slave准备好数据放入TxBuffer (Bus stalled: SCL held low until data available)
下图是遇到问题的I2C波形
在调试过程中发现在从机应该去held SCL low的阶段从机没能拉住SCL的电平等待数据准备完成,导致Slave发送的数据错位,整体master收到的数据右移一位,经过示波器和原理图,以及datasheet的分析,初步定为问题在此,反查原理图发现I2C在选用隔离芯片的时候,选用SCL信号端是单向导通的隔离器件。
[Additional]还有一个问题呢就是,主机发送从机收数据的时候存在问题,最终结果是自己在接收终端服务子函数里debug的信息太多,导致错过了Slave回ACK的时间,这个问题也要注意,I2C receive ISR里尽量少处理,可能存在错过回复ACK的时间导致发送接收失败。
Finally
硬件设计者也要注意选用I2C隔离芯片的时候,需要使用SCL和SDA均为双向导通的隔离器。那系统设计必须要考虑到CLK也需要双向导通这个问题,如果SCL用单向导通,那必须得有解决这个问题的设计在系统里面。