24C01驱动 |
[ 2012-5-18 13:48:00 | By: 吴师傅 ]
|
8
推荐
一.概述 24系列I2C串行总线EEPROM芯片应用非常广泛,在51单片机控制系统中如影随形。24系列EEPROM可重复擦写100万次,数据可以掉电保存100年不变,有1K位、2K位、4K位、8K位等存储容量的系列产品,24C01就是其中的1K位容量的产品。 I2C串行总线是Philips公司推出的一种双向二线制通信总线,由一条数据线和一条时钟线组成,主要应用于芯片之间的通信。支持I2C总线接口的芯片非常多,所以学习单片机一定要掌握I2C总线协议。51单片机本身并不带I2C总线接口,要想访问I2C接口芯片,只有通过软件模拟实现。51单片机IO口操作简单,软件模拟I2C总线轻而易取。 二.电路设计 在WSF-51DB开发板上,利用AT89S52单片机的P0.3、P0.4、P0.5来驱动AT24C01,P0口的上拉排阻为4.7K欧姆。需要注意的是AT24C01的SDA管脚是漏极开路,所以一定要在这个管脚上接一个上拉电阻,阻值在2K-10K欧姆范围内选择,传输速率越高,阻值应当越小。
三.软件设计 /***************************************************************** *程序名称:24C01驱动 *程序功能:写人8个数据,再读出来,放在P2口显示。 *开发工具:WSF-51DB开发板 * MCU型号:AT89S52-24PU *时钟频率:12MHZ *程序作者:吴师傅 *版权说明:吴师傅版权所有。转载请注明来源和作者。 *****************************************************************/ #i nclude unsigned char code dat[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//写入24C01的数据 sbit wp=P0^3;//写保护 sbit scl=P0^4;//时钟线 sbit sda=P0^5;//数据线
//延时15us函数: void Delayus() { unsigned char i; for(i=5;i>0;i--); }
//延时1ms函数: void Delayms(unsigned int t) { unsigned int x,y; for(x=t;x>0;x--) for(y=120;y>0;y--); }
//起始信号函数: void Start(void) { sda=1;//时序要就很严格 scl=1; Delayus(); sda=0; scl=0; } //停止信号函数: void Stop(void) { scl=0;//时序要就很严格 sda=0; Delayus(); scl=1; sda=1; } //应答信号函数: void ACK(void) { sda=1;//先释放总线 scl=1;//启动应答时钟(第九个脉冲) Delayus();//器件发出应答信号(sda被拉低) scl=0; Delayus();//等待应答脉冲变高后结束应答 }
//写字节函数: void Write24c01Byte(unsigned char wbyte) { unsigned char i; for(i=0;i<8;i++) { sda=(wbyte&0x80)?1:0;//从高到低逐位写数据, Delayus(); scl=1; Delayus(); scl=0; Delayus(); wbyte<<=1; } }
//读数据函数: unsigned char Read24c01Byte(void) { unsigned char i,rbyte; for(i=0;i<8;i++) { rbyte<<=1; scl=1; Delayus(); if(sda==1) rbyte|=0x01;//逐位读取数据 else rbyte&=(~0x01); scl=0; Delayus(); } return rbyte; } //字节模式写数据函数: void Write24c01ByteData(unsigned char waddr, unsigned char wdata) { Start(); Write24c01Byte(0xa0);//器件地址1010000+写(0) ACK(); Write24c01Byte(waddr);//写地址 ACK(); Write24c01Byte(wdata);//写数据 ACK(); Stop(); Delayms(1);//写延时,最大5毫秒 } //页模式写数据函数: void Write24c01PageData(unsigned char saddr,unsigned char *pd,unsigned char num) //saddr---页起始地址;pd---指针;nun---字节个数,不能大于一页的字节数 { unsigned char i; Start(); Write24c01Byte(0xa0);//器件地址1010000+写(0) ACK(); Write24c01Byte(saddr);//写页起始地址,24C01一页8个字节,共16页 ACK(); for(i=0;i { Write24c01Byte(*pd++);//写数据 ACK(); } Stop(); }
//读数据函数: unsigned char Read24c01Data(unsigned char raddr) { unsigned char rdat; Start(); Write24c01Byte(0xa0);//器件地址+写(0) ACK(); Write24c01Byte(raddr);//写数据存放地址 ACK(); Start(); Write24c01Byte(0xa1);//器件地址1010000+读(1) ACK(); rdat=Read24c01Byte(); Stop(); return rdat; }
//主函数: int main(void) { unsigned char i; wp=0;//写使能 //for(i=0;i<8;i++) // Write24c01ByteData(i,datacode[i]);//字节模式从0地址开始写入8个数据 Write24c01PageData(0,dat,8);//页模式从0地址开始写入8个数据 while(1) { for(i=0;i<8;i++) { P2=Read24c01Data(i);//从0地址开始读出数据,点亮P2口的8个LED Delayms(500); }
} return 0; } |