IIC协议编程要点,24C04为例

对于IIC编程来说,以下几点最为重要:

1、SCL和SDA必须用硬件或者软件上拉。

2、接收方总是在SCL为高电平期间采样bit位,等价于:发送方必须在SCL高电平期间保持SDA不变;

3、Ack的本质上就是发送1个bit的数据,它发生在接收完一个字节后(接收方可能是主机也可能是从机),也即第9个SCL的高电平期间。在SCL高电平期间,若SDA为0,就称为ACK,若SDA为1(默认上拉),称为NoAck。

4、Ack和NoAck都是是由接收方发出的,也即:
若主机在接收数据,那么Ack或者NoAck将由主机发出,典型场景如主机接收到从机传回的字节后;
若从机在接收数据,那么Ack或者NoAck将由从机发出,典型场景如从机接收到主机发起的片选字节后,又如从机接收到主机发起的寄存器选字节后;

实际应用中的IIC从机,只要收到了主机发来的字节,就必须向主机回复Ack,我至今都没见过从机向主机回复NoAck的从机。

而主机,有时会向从机发ACK,有时会向从机发NoAck。

也即:ACK这个概念,对于主机编程来说,涉及到4个函数(或者直接写成代码片段也行):①检查从机发来的是ack吗?②检查从机发来的是NoAck吗?③要向从机发Ack吗?④要向从机发NoAck吗?

5、SCL全程只被主机控制,从机无权控制SCL;

 

 

举一个24C04的例子:

(大多数IIC从机都是7bit的地址,第8bit指示读/写,主机发送芯片地址,这一过程称为片选)

1、单字节写

主机发出start ---> 主机发出片选字节(写) ---> 主机检测从机是否回复了Ack ---> 主机发送字节地址 --->  主机检测从机是否回复了Ack --> 如果上一步从机Ack了,主机发送一个数据字节 ---> 主机检测从机是否发出了Ack ---> 主机发出stop。

PS:“主机检测从机是否回复了Ack”,这一过程本质上就是:主机把SDA拉高,然后发出一个SCL高脉冲,并检测在高脉冲期间SDA是否被从机给拉低了,如果被拉低了,就意味着从机回复了Ack信号。

2、页内连续写多个字节(24C04不支持跨页写,如果本页写满了,则会返回本页的页首覆盖写)

主机发出start ---> 主机发出片选字节(写) ---> 主机检测从机是否回复了Ack---> 主机发送字节地址 ---> 主机检测从机是否回复了Ack --> 循环{ 主机发送数据字节 -->  主机检测从机是否回复了Ack } ---> 主机发出Stop

3、单字节读

主机发出start ---> 主机发出片选字节(写) ---> 主机检测从机是否发出了Ack---> 主机发送字节地址---> 主机检测从机是否回复了Ack --->  主机发出start ---> 主机发出片选字节(读) ---> 主机检测从机是否回复了Ack ---> 主机接收从机的单字节数据 ---> 主机向从机发出NoAck信号  --->  主机发出Stop

4、连续读出多个字节(24C04支持跨页连读)

主机发出start ---> 主机发出片选字节(写) ---> 主机检测从机是否回复了Ack---> 主机发送字节地址---> 主机检测从机是否回复了Ack --->  主机发出start ---> 主机发出片选字节(读) ---> 主机检测从机是否回复了Ack -> 循环{ 主机读取从机发出的一个字节 ---> 主机向从机回复Ack信号}  ---> 主机读取从机发出的一个字节 ---> 主机向从机回复NoAck信号 ---> 主机发出Stop。

 

 

你可能感兴趣的:(stm32/单片机)