I2C在通信的过程中,在接收数据时,由主机对时钟线(SCL)进行控制,而从机对数据线(SDA)进行控制,这时主机要释放数据线(SDA),从机才能操作
1.1 启动信号(S)
-
SDA
,SCL
都处于高电平状态,持续时间需大于4.7us
; -
在
SCL
处于高电平阶段,将SDA
拉到低电平阶段,SDA
低电平阶段持续时间需大于4.7us
,这时,启动信号已经发送; -
将
SCL
拉至低电平阶段,进入位数据准备阶段; -
代码实例
void m_i2cStartCond(void) { m_setSDA(); //将SDA置位,拉到高电平 m_i2cDelay(); //持续时间需大于4.7us m_setSCL(); //将SCL置位,拉到高电平 m_i2cDelay(); //持续时间需大于4.7us m_clearSDA(); //将SDA复位,拉到低电平,发送启动信号 m_i2cDelay(); //持续时间需大于4.7us m_clearSCL(); //将SCL复位,进入位数据准备阶段 }
1.2 主机发送位(bit)数据
-
SCL
处于低电平阶段; -
根据要发送的位数值设置
SDA
的电平状态,比如发送0
,则复位SDA
,将SDA
拉到低电平,发送0
,则置位SDA
,将SDA
拉到高电平,持续时间需大于4.7us
; -
置位
SCL
,将SCL
拉至高电平状态,使得SDA
数据线上的数据有效,持续时间需大于4.7us
,使得从机在这段时间内可以读取SDA
数据线的状态; -
复位
SCL
,将SCL
拉至低电平状态,进入下一位数据发送准备阶段; -
代码示例:
void m_i2cWriteBit(bit b) { /*在发送完启动信号或发送一位后,SCL已经复位进入下次位数据发送准备阶段*/ if(b) //根据发送的数值,设置SDA的电平状态 m_setSDA(); else m_clearSDA(); m_i2cDelay(); //持续时间需大于4.7us m_setSCL(); //置位SCL,使得SDA数据有效,从机可以读取SDA的电平状态 m_i2cDelay(); //持续时间需大于4.7us m_clearSCL(); //复位SCL,进入下一位的数据发送准备阶段 }
1.3 主机读取位(bit)数据
i2c读取一位的数据方式跟发送一位数据方式差不多,两者的区别在于读取位数据时,主机操作时钟线SCL
,释放SDA
线,由从机操作SDA
的状态。
-
SCL
处于低电平阶段,之前我们不管在发送完启动信号或者发送完一位的数据后,我们都会把SCL
复位,进入位数据准备阶段;