I2C總線AT24C02讀寫程序
pre>//****************************************************
/*
程序的功能:將數(shù)據(jù)寫入AT24C02中,然后再從其中讀取
回來賦給P2口,讓流水燈顯示。
所涉及芯片:AT24C02
*/
//****************************************************
#includelt;reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit scl=P0^3;//時鐘線接在P0^3口
sbit sda=P0^4;//數(shù)據(jù)線接在P0^4口
void delay()//極短時間的延時
{
; ; ;
}
void delay1()//較長時間的延時
{
uchar i,j;
uchar k=10;
for(i=k;i>0;i--)
for(j=110;j>0;j--);
}
void chushihua()//對總線進行初始化
{
sda=1;
scl=1;
}
//=======================================
void start()//起始函數(shù)
{
sda=1;
delay();
scl=1; //時鐘線為高電平期間,數(shù)據(jù)線由高到低的一個跳變表示起始
delay();
sda=0;
delay();
}
//=========================================
void stop()//終止函數(shù)
{
sda=0;
delay();
scl=1;//時鐘線為高電平期間,數(shù)據(jù)線由低到高的一個跳變表示終止
delay();
sda=1;
delay();
}
//==========================================
void ack()//應答函數(shù)
{
uchar i;
scl=1;
if((sda==1)(ilt;250))i++;//如果數(shù)據(jù)線一直為高電平,則一段時間后則默認為應答(即時鐘線由高到底的一個跳變)
scl=0;
delay();
}
//===========================================
void noack()//非應答函數(shù) ,在數(shù)據(jù)線為高電平期間,時鐘線一個完整的脈沖表示非應答
{
sda=1;
delay();
scl=0;
delay();
scl=1;
delay();
scl=0;
delay();
}
//====================================
void write_byte(uchar date)//寫字節(jié)函數(shù)
{
uint i;
scl=0;//時鐘線為低電平期間,允許數(shù)據(jù)的變化
for(i=0;ilt;8;i++)
{
if(date0x80)//如果寫進的數(shù)據(jù)與0x80進行與運算為“1”(即為真),則數(shù)據(jù)線為高電平
{
sda=1;
}
else //否則為低電平
{
sda=0;
}
date=datelt;lt;1;//對8位數(shù)據(jù)進行移位操作
scl=1;//時鐘線為高電平(即數(shù)據(jù)穩(wěn)定),把數(shù)據(jù)讀走
delay();
scl=0; //把時鐘線拉回低電平
delay();
}
sda=1; //釋放數(shù)據(jù)線
delay();
}
//========================================
uchar read_byte()//讀字節(jié)函數(shù)
{
uchar i;
uchar date=0x00;
scl=0;
delay();
sda=1;//將總線釋放
delay();
for(i=0;ilt;8;i++)
{
scl=1;//時鐘線為高電平(即數(shù)據(jù)穩(wěn)定),把數(shù)據(jù)讀走
delay();
date=datelt;lt;1;
if(sda)
{
date++;
}
scl=0;
delay();
}
return date;
}
void xie(uchar add,uchar date)
{
start();
write_byte(0xa0);//指令碼0xa0為寫操作
ack();
write_byte(add);
ack();
write_byte(date);
ack();
stop();
}
uchar du(uchar t)
{
uchar k;
start();
write_byte(0xa0);
ack();
write_byte(t);
ack();
start();
write_byte(0xa1);//指令碼0xa1為讀操作
ack();
k=read_byte();
noack();
stop();
return k;//返回K的值
}
void main()
{
chushihua();
xie(10,0x44);//在0~256個地址中隨意選一地址10,并在該地址寫入一字節(jié)0x44
delay1();//此處必須要一個延時函數(shù)
P2=du(10);//將在地址10讀回的數(shù)據(jù)賦給P2口(即讓流水燈顯示)
while(1);//讓程序停在此處
}
/pre>
評論