这两天在看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)。