一、I2C總線使用方法
I2C總線包括SCL,SDA 兩根信號線埠居,其中SCL是時鐘線芝硬,SDA是數(shù)據(jù)線。
對于I2C總線的操作帝璧,主要有以下幾個命令:
開始命令:
I2C總線開始的操作過程是通過SCL為高的時候SDA有個下降沿的過程先誉;停止命令:
I2C停止的的操作過程是通過SCL為高的時候SDA有個上升沿的過程;讀寫數(shù)據(jù)
I2C讀寫每一位數(shù)據(jù)都是在SCL為高的時候完成的的烁,讀寫每一位數(shù)據(jù)的時候SCL都有一個高脈沖的過程褐耳,也就是說,在SCL為高的時候我們讀寫SDA的值渴庆,這意味著在SCL拉高之前铃芦,SDA必須為一穩(wěn)定的值,不然讀寫就不準確襟雷;寫完從器件之后等待從器件的應答:
在主器件完成對從器件的寫操作時候(每次會有一個字節(jié)的數(shù)據(jù))刃滓,主器件會等待從器件發(fā)送指示信號,這個指示信號是說從器件已經(jīng)接受到了主器件的數(shù)據(jù)耸弄,這個回應ACK是個低電平脈沖咧虎。并且這是由從器件的硬件來完成的,不需要主器件來軟件操作叙赚,只需要等待老客;主器件讀完數(shù)據(jù)后向從器件發(fā)送應答信號:
這其實包括兩種情況,一種是主器件讀完后還要繼續(xù)讀就要發(fā)送一個繼續(xù)讀的信號(其實就是發(fā)送0)震叮,另一種就是不再繼續(xù)讀了胧砰,就要發(fā)送停止讀信號(其實就是發(fā)送1)。
二苇瓣、示例代碼
51C語言
#define uchar unsigned char
#define uint unsigned int
void delay()
{
uint i;
for(i=0;i<300;i++);
for(i=0;i<300;i++);
}
//開始
void I2C_START()
{
SDA = 1;
SCL = 1;
delay();
SDA = 0;
delay();
}
//停止
void I2C_STOP()
{
SDA = 0;
SCL = 1;
delay();
SDA = 1;
delay();
}
//寫完等待從器件應答
bit write_ACK(void)
{
uchar i;
SCL = 1;
delay();
i = SDA;
SCL = 0;
delay();
if(i==1) return 0;
else return 1;
}
//讀完發(fā)送停止讀的信號
void NACK()
{
uchar j;
SDA = 1;
delay();
SCL = 1;
delay();
while((SDA==0)&&(j<250)) j++;
SCL = 0;
delay();
}
//寫字節(jié)
void I2C_writebyte(uchar dat_w)
{
uint i;
uchar tmp;
tmp = dat_w;
SCL = 0;
delay();
for(i=0;i<8;i++)
{
if((tmp<<i)&0x80)
SDA = 1;
else SDA = 0;
delay();
SCL = 1;
delay();
SCL = 0;
delay();
}
SDA = 1;
delay();
}
//讀字節(jié)
uchar I2C_readbyte()
{
uchar i;
uchar dat_r,k;
SCL = 0;
delay();
SDA = 1;
delay();
for(i=0;i<8;i++)
{
SCL = 0;
delay();
SCL = 1;
delay();
k = SDA;
dat_r = (dat_r<<1)|k;
SCL = 0;
delay();
}
return dat_r;
}
//寫地址及數(shù)據(jù)
void I2C_write_add(uchar slave_add, uchar byte_add, uchar dat_w)
{
I2C_START();
I2C_writebyte(slave_add);
write_ACK();
I2C_writebyte(byte_add);
write_ACK();
I2C_writebyte(dat_w);
write_ACK();
I2C_STOP();
}
//讀地址的數(shù)據(jù)
uchar I2C_read_add(uchar slave_add, uchar byte_add)
{
uchar dat_r;
I2C_START();
I2C_writebyte(slave_add);
write_ACK();
I2C_writebyte(byte_add);
write_ACK();
I2C_START();
I2C_writebyte((slave_add+1));
write_ACK();
dat_r = I2C_readbyte();
NACK();
I2C_STOP();
return dat_r;
}
void main()
{
SDA = 1;
SCL = 1;
I2C_write_add(0xa0,0x23,0x51);
P1 = I2C_read_add(0xa0,0x23);
while(1);
}
三尉间、參考資料
- champion_xu I2C總線讀寫
http://www.360doc.com/content/12/0914/09/9400799_236028313.shtml