⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 [原创]at24c02 c语言驱动程序.c

📁 本人收集和自己写的部分51系列例程,供各位参考
💻 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 + -