📄 [原创]at24c02 c语言驱动程序.c
字号:
/*[原创]AT24c02 C语言驱动程序At24c02 的C语言驱动程序,使用ACC的位读取、写入,达到最快的速度。
实现了页写(自动换页),连续读、读写单字节。*/
//作者:张子墨
//QQ:88240655
//zzm19850214@hotmail.com
//I2C总线24系列EEPROM读写程序
//要首先定义SCL与SDA
//使用12MH或更高晶振,适当增加延时
#include <at89s53.h>
#define DelayTime 20 //延迟时间,频率越高适当增加
#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) //总线开始函数
{
sda=1;
scl=1;
Delay(DelayTime); //起始条件建立时间大于4.7us
sda=0;
Delay(DelayTime); //起始条件锁定时大于4us
scl=0;
Delay(DelayTime); //钳住总线,准备发数据
}
void I2CStop (void) //总线停止函数
{
sda=0; //发送结束条件的时钟信号
scl=1;
Delay(DelayTime); //结束总线时间大于4us
sda=1; //结束总线
Delay(DelayTime); //保证一个终止信号和起始信号的空闲时间大于4.7us
}
bit CheckACK (void) //检查应答函数
{
sda=1;
scl=1;
Delay(DelayTime/2);
ACK=sda;
Delay(DelayTime/2);
scl=0;
if (ACK==1) return 0; //没有应答返回0
return 1; //有应答返回1
}
void SendACK (void) /* SEND ACK 发送应答信号*/
{
sda=0;
scl=1;
Delay(DelayTime);
scl=0;
}
void SendNACK (void) //发送非应答信号
{
sda=1;
scl=1;
Delay(DelayTime);
scl=0;
}
void WriteI2C (uchar dd) //写入一个字节
{
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) //读取一个字节
{
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);
}
/*读写功能用户函数*/
void WriteOneByte (uchar addr,char thedata) //写入一个字节到指定地址
{
I2CStart(); //开始总线
WriteI2C(0xa0); //发送控制数据
ACK = CheckACK(); //检查应答信息
WriteI2C(addr); //写入地址
ACK = CheckACK();
WriteI2C(thedata); //写入数据
ACK = CheckACK();
I2CStop(); //停止总线
}
void WriteOnePage (uchar addr,char *thedata) //写入一页16个字节到指定开始地址,可以自动翻页
{
uchar i,j; //计数器
i=16-(addr&0x0F); //计算应写入第一页的数据量 ??????
I2CStart(); //开始总线
WriteI2C(0xa0); //发送控制数据
ACK = CheckACK(); //检查应答信息
WriteI2C(addr); //写入地址
ACK = CheckACK();
for(j=0;j<i;j++) //循环写入第一页的数据
{
WriteI2C(*thedata); //写入数据
ACK = CheckACK();
thedata++; //数据指针加1
}
I2CStop(); //停止总线
if(i!=16) //如果第一页不够,开始写入第二页
{
I2CStart(); //开始总线
WriteI2C(0xa0); //发送控制数据
ACK = CheckACK(); //检查应答信息
WriteI2C(addr+i); //写入地址
ACK = CheckACK();
for(j=i;j<17;j++) //循环写入第二页数据
{
WriteI2C(*thedata); //写入数据
ACK = CheckACK();
thedata++;
}
I2CStop();
}
}
char ReadOneByte (uchar addr) //读取指定地址一个字节
{
char mydata; //准备写入的数据
I2CStart();
WriteI2C(0xa0); //写入控制数据
ACK = CheckACK();
WriteI2C(addr); //写入地址
ACK = CheckACK();
I2CStart(); //重新开始总线
WriteI2C(0xa1); //写入读取控制码
ACK = CheckACK();
mydata=ReadI2C(); //读取数据
I2CStop(); //停止总线
return mydata;
}
void ReadNByte (uchar addr,char *thedata,uchar n) //连续读取N个字节
{
uchar i;
I2CStart();
WriteI2C(0xa0);
ACK=CheckACK();
WriteI2C(addr);
ACK=CheckACK();
I2CStart();
WriteI2C(0xa1);
ACK=CheckACK();
for(i=0;i<n-1;i++) //循环读取前N-1个数据
{
*thedata=ReadI2C(); //读取数据
SendACK(); //发送应答,表示继续读取
thedata++; //数据指针加1
}
*thedata=ReadI2C(); //读取最后一个数据
SendNACK(); //发送非应答,结束读取
I2CStop(); //停止总线
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -