?? [原創(chuàng)]at24c02 c語(yǔ)言驅(qū)動(dòng)程序.c
字號(hào):
/*[原創(chuàng)]AT24c02 C語(yǔ)言驅(qū)動(dòng)程序At24c02 的C語(yǔ)言驅(qū)動(dòng)程序,使用ACC的位讀取、寫入,達(dá)到最快的速度。
實(shí)現(xiàn)了頁(yè)寫(自動(dòng)換頁(yè)),連續(xù)讀、讀寫單字節(jié)。*/
//作者:張子墨
//QQ:88240655
//zzm19850214@hotmail.com
//I2C總線24系列EEPROM讀寫程序
//要首先定義SCL與SDA
//使用12MH或更高晶振,適當(dāng)增加延時(shí)
#include <at89s53.h>
#define DelayTime 20 //延遲時(shí)間,頻率越高適當(dāng)增加
#define scl P1_1 //針腳定義
#define sda P1_0
#define uchar unsigned char
#define uint unsigned int
bit ACK;
sbit a0 = ACC^0; //定義ACC位,使用ACC讀寫速度最快
sbit a1 = ACC^1;
sbit a2 = ACC^2;
sbit a3 = ACC^3;
sbit a4 = ACC^4;
sbit a5 = ACC^5;
sbit a6 = ACC^6;
sbit a7 = ACC^7;
void I2CStart (void) //總線開(kāi)始函數(shù)
{
sda=1;
scl=1;
Delay(DelayTime); //起始條件建立時(shí)間大于4.7us
sda=0;
Delay(DelayTime); //起始條件鎖定時(shí)大于4us
scl=0;
Delay(DelayTime); //鉗住總線,準(zhǔn)備發(fā)數(shù)據(jù)
}
void I2CStop (void) //總線停止函數(shù)
{
sda=0; //發(fā)送結(jié)束條件的時(shí)鐘信號(hào)
scl=1;
Delay(DelayTime); //結(jié)束總線時(shí)間大于4us
sda=1; //結(jié)束總線
Delay(DelayTime); //保證一個(gè)終止信號(hào)和起始信號(hào)的空閑時(shí)間大于4.7us
}
bit CheckACK (void) //檢查應(yīng)答函數(shù)
{
sda=1;
scl=1;
Delay(DelayTime/2);
ACK=sda;
Delay(DelayTime/2);
scl=0;
if (ACK==1) return 0; //沒(méi)有應(yīng)答返回0
return 1; //有應(yīng)答返回1
}
void SendACK (void) /* SEND ACK 發(fā)送應(yīng)答信號(hào)*/
{
sda=0;
scl=1;
Delay(DelayTime);
scl=0;
}
void SendNACK (void) //發(fā)送非應(yīng)答信號(hào)
{
sda=1;
scl=1;
Delay(DelayTime);
scl=0;
}
void WriteI2C (uchar dd) //寫入一個(gè)字節(jié)
{
ACC = dd;
sda=a7;scl=1;scl=0;
sda=a6;scl=1;scl=0;
sda=a5;scl=1;scl=0;
sda=a4;scl=1;scl=0;
sda=a3;scl=1;scl=0;
sda=a2;scl=1;scl=0;
sda=a1;scl=1;scl=0;
sda=a0;scl=1;scl=0;
sda = 1;
scl = 1;
}
uchar ReadI2C (void) //讀取一個(gè)字節(jié)
{
sda = 1;
scl=1;a7=sda;scl=0;
scl=1;a6=sda;scl=0;
scl=1;a5=sda;scl=0;
scl=1;a4=sda;scl=0;
scl=1;a3=sda;scl=0;
scl=1;a2=sda;scl=0;
scl=1;a1=sda;scl=0;
scl=1;a0=sda;scl=0;
return(ACC);
}
/*讀寫功能用戶函數(shù)*/
void WriteOneByte (uchar addr,char thedata) //寫入一個(gè)字節(jié)到指定地址
{
I2CStart(); //開(kāi)始總線
WriteI2C(0xa0); //發(fā)送控制數(shù)據(jù)
ACK = CheckACK(); //檢查應(yīng)答信息
WriteI2C(addr); //寫入地址
ACK = CheckACK();
WriteI2C(thedata); //寫入數(shù)據(jù)
ACK = CheckACK();
I2CStop(); //停止總線
}
void WriteOnePage (uchar addr,char *thedata) //寫入一頁(yè)16個(gè)字節(jié)到指定開(kāi)始地址,可以自動(dòng)翻頁(yè)
{
uchar i,j; //計(jì)數(shù)器
i=16-(addr&0x0F); //計(jì)算應(yīng)寫入第一頁(yè)的數(shù)據(jù)量 ??????
I2CStart(); //開(kāi)始總線
WriteI2C(0xa0); //發(fā)送控制數(shù)據(jù)
ACK = CheckACK(); //檢查應(yīng)答信息
WriteI2C(addr); //寫入地址
ACK = CheckACK();
for(j=0;j<i;j++) //循環(huán)寫入第一頁(yè)的數(shù)據(jù)
{
WriteI2C(*thedata); //寫入數(shù)據(jù)
ACK = CheckACK();
thedata++; //數(shù)據(jù)指針加1
}
I2CStop(); //停止總線
if(i!=16) //如果第一頁(yè)不夠,開(kāi)始寫入第二頁(yè)
{
I2CStart(); //開(kāi)始總線
WriteI2C(0xa0); //發(fā)送控制數(shù)據(jù)
ACK = CheckACK(); //檢查應(yīng)答信息
WriteI2C(addr+i); //寫入地址
ACK = CheckACK();
for(j=i;j<17;j++) //循環(huán)寫入第二頁(yè)數(shù)據(jù)
{
WriteI2C(*thedata); //寫入數(shù)據(jù)
ACK = CheckACK();
thedata++;
}
I2CStop();
}
}
char ReadOneByte (uchar addr) //讀取指定地址一個(gè)字節(jié)
{
char mydata; //準(zhǔn)備寫入的數(shù)據(jù)
I2CStart();
WriteI2C(0xa0); //寫入控制數(shù)據(jù)
ACK = CheckACK();
WriteI2C(addr); //寫入地址
ACK = CheckACK();
I2CStart(); //重新開(kāi)始總線
WriteI2C(0xa1); //寫入讀取控制碼
ACK = CheckACK();
mydata=ReadI2C(); //讀取數(shù)據(jù)
I2CStop(); //停止總線
return mydata;
}
void ReadNByte (uchar addr,char *thedata,uchar n) //連續(xù)讀取N個(gè)字節(jié)
{
uchar i;
I2CStart();
WriteI2C(0xa0);
ACK=CheckACK();
WriteI2C(addr);
ACK=CheckACK();
I2CStart();
WriteI2C(0xa1);
ACK=CheckACK();
for(i=0;i<n-1;i++) //循環(huán)讀取前N-1個(gè)數(shù)據(jù)
{
*thedata=ReadI2C(); //讀取數(shù)據(jù)
SendACK(); //發(fā)送應(yīng)答,表示繼續(xù)讀取
thedata++; //數(shù)據(jù)指針加1
}
*thedata=ReadI2C(); //讀取最后一個(gè)數(shù)據(jù)
SendNACK(); //發(fā)送非應(yīng)答,結(jié)束讀取
I2CStop(); //停止總線
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -