×
嵌入式 > 嵌入式开发 > 详情

关于I2C的总结

发布时间:2020-08-21 发布时间:
|
这两天在看I2C,为了加深印象,把我遇到的一些问题写出来吧。

1——————

最先遇到的问题是AT24C02的操作时序,AT24C02内部有一个指针,指向储存空间的某一个字节,另外AT24C系列支持页操作,对于AT24C02一个页是8字节,也就是说地址的高5位是页地址,在同一次写入中,页地址不变,低3位地址一次增加,当增加到7之后再加1就变成0了,而由于页地址不变,相当于指针回到了页首,如果继续写那前面的内容会被覆盖。写数据的时序,先是I2C的开始信号,发送设备地址,之后写入希望写入的数据地址,然后依次写入数据。当然,可以只写一个字节的数据。

对于读取,是不存在页的概念的,时序是先发送启动信号,然后发送设备地址(注意,是写设备的时候的地址,也就是说最低位是1),接着发送数据地址,完了之后重新发送一次启动信号,接着就可以读取了,读取完一个字节的数据后要发送一个ACK,对于最后一个字节的数据要发送一个NACK来告诉AT24C数据已经接收完毕,之后发送结束信号断开连接即可。也可以只接收一个数据,这时候一个ACK都没有,第一次接收好直接发送一个NACK。

24C02的内部有连续的子地址空间,对这些空间进行n个字节的连续读/写时,都具有地址自动加1功能。只要设定好要读/写的器件内起始子地址及字节数,就能完成整个操作。
注意:对于24C02连续写的字节数不应超过页容量8,一次连续写所形成的总线传送结束后(主机发出停止信号后),24C02执行内部擦写过程,大约需要10ms左右,24C02不再应答主器件的任何请求。
24C02内有一个8位的地址计数器,连续读操作时,24C02每次输出一个数据字节后,地址计数器自动加1,当地址计数器加到255,并输出一个字节数据后,地址计数器将翻转到0,并继续输出数据字节,这样整个存储区域可以在一个读操作内全部读完。

#define SLAW 0xA0
uchar delay(uchar j)
{ uchar k,l;
for(l=0;l<=j;l++)
for(k=0;k<=250;k++);
return 0;
}
void main()
{
uchar sbuf[5]={0x00,0x12,0x55,0x30,0x12};
uchar rbuf[5];
I2C_SendStr(SLAW,0x10,tbuf,0x5);

delay(100);
I2C_RcvStr(SLAW,0x10,rbuf,0x5);

while(1);
}
}

2——————

在次我只发表对I2C确认信号的看法,至于它的一整套时序就不多罗嗦了。

1)MASTER向SLAVE发送数据:
MASTER没向SLAVE端发送8位数据后,就会将SDA置1,等待SLAVE端的确认;SLAVE端如果正确接受到数据,就会自动将SDA置0。我们程序员所能做的只能是检测确认信号,即每发送完8位数据后就检测一次SDA的状态,如果是0,则让程序继续往下执行,如果是1则强迫MASTER将刚才的8位数据再发送一遍;当然,如果SDA一直是1,也就是SLAVE一直未能正确接受到数据,我们也不能一直让MASTER反复发送,要做TIMEOUT处理,以防系统死机!

2) MASTER从SLAVE读取数据:
MASTER从SLAVE端读取数据,情况与发送数据有所区别,在读到最后8位数据时,要将SDA置1,也就是做UNACK动作,让系统知道读取数据到此结束;这个置1动作由程序员来做,而不是MASTER本身,因为数据读到哪里结束,只有我们程序员知道!

3) 说明:MASTER 指主控制端,在一般系统中就是我们常说的单片机了;SLAVE是指具备I2C协议的专用IC,比如ATMEL的24系列(24C16、14C32等)和PHILPS的SAA711X系列(VIDEO DECODER)。



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
RIOS实验室联手Imagination.共同助力RISC-V生态发展