?? i2c.c
?? C文件
I2C總線型芯片操作
向芯片寫(xiě)數(shù)
讀回所寫(xiě)數(shù)據(jù)
在流水燈上表現(xiàn)所讀
較難
較有用
經(jīng)常
?? C
字號(hào):
??
//嚴(yán)格的時(shí)序
#include<reg52.h>
#include<intrins.h>//_nop_()函數(shù)所在庫(kù)
#define uchar unsigned char
#define uint unsigned int//簡(jiǎn)寫(xiě)宏定義
sbit sda=P2^0;//數(shù)據(jù)總線
sbit scl=P2^1;//時(shí)鐘總線
void delay()//延時(shí)函數(shù)〉4.7US
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
void delay1(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=2;b>0;b--);
}
void init_I2C()//初始I2C總線,都釋放為高,SCL 為高電平時(shí),SDA數(shù)據(jù)要穩(wěn)定
{
sda=1;
scl=1;
}
void start_I2C()//開(kāi)始信號(hào),在SCL為高電平時(shí)SDA出現(xiàn)下跳變?yōu)殚_(kāi)始;
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop_I2C()//停止信號(hào),在SCL為高電平時(shí)SDA出現(xiàn)上跳變?yōu)橥V梗?{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void write_byte(uchar dat)//寫(xiě)一個(gè)字節(jié)到24C02
{
uchar i;//數(shù)據(jù)是串行的,高位在前
for(i=0;i<8;i++)
{
scl=0;
delay();
dat=dat<<1;//移出的位到PSW的CY位
sda=CY;
scl=1;
delay();//在數(shù)據(jù)送出后置高SCL并延時(shí)保證SDA穩(wěn)定
scl=0;
delay();
}
sda=1;//寫(xiě)完數(shù)據(jù)后習(xí)慣性釋放數(shù)據(jù)線以等待回應(yīng)
}
uchar read_I2C()//讀一個(gè)字節(jié)注意將位移為完整字節(jié)的技巧
{
uchar i,renum;
for(i=0;i<8;i++)
{
scl=0;
delay();
sda=1;
delay();
scl=1;
delay();
renum=(renum<<1)|sda;//¥
scl=0;
delay();
sda=0;
delay();
}
return renum;
sda=1;//釋放數(shù)據(jù)線
}
void ack_I2C()//應(yīng)答信號(hào),在SCL為高時(shí)24C02收到SDL上的低電平信號(hào)
{ //若未收到則在一定時(shí)間之后默認(rèn)已收到
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;//SDA從0到1,或一定時(shí)間后都可使之跳出循環(huán)
scl=0;
delay();
}
void write_I2C(uchar add,uchar sta)//按照時(shí)序向24C04寫(xiě)數(shù)據(jù)主要函數(shù)
{ //要嚴(yán)格按照時(shí)序,特別注意應(yīng)答信號(hào)必不可少
start_I2C();//開(kāi)始信號(hào)
write_byte(add);//存儲(chǔ)器地址
ack_I2C();//應(yīng)答
write_byte(2);//寫(xiě)存儲(chǔ)器中欲寫(xiě)的單元
ack_I2C();//應(yīng)答
write_byte(sta);//寫(xiě)數(shù)據(jù)
ack_I2C();//應(yīng)答
stop_I2C();//停止信號(hào)
}
uchar readmain()//按照時(shí)序讀24C04中數(shù)據(jù)主函數(shù),注意讀時(shí)也要寫(xiě)清讀的地址
{
uchar temp;//讀回?cái)?shù)據(jù)暫存
start_I2C();
write_byte(0xa0);//要讀的存儲(chǔ)器地址
ack_I2C();
write_byte(2);//讀存儲(chǔ)器中欲寫(xiě)的單元
ack_I2C();
start_I2C();
write_byte(0xa1);//數(shù)據(jù)流向選擇0xa1,1為讀
ack_I2C();
temp=read_I2C();
stop_I2C();
return temp;
}
void main()
{
while(1)
{
init_I2C();
write_I2C(0xa0,0xee);//數(shù)據(jù)流向選擇0xa0,0為寫(xiě),0Xee為欲寫(xiě)數(shù)
delay1(200);//讀寫(xiě);大的數(shù)據(jù)流向或單元改變要添置延時(shí),否則將會(huì)造成整個(gè)程序的失敗
P1=readmain();
while(1);
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -