以下程序本人仅在 6MHZ晶振,AT89CXX 测试通过..至于其它晶振下未经测试,也不知道行不行.如果不行,请自行调整延时量.主要在于了解IIC总线的操作,这样不管是AT24C0X还是其它的IIC总线的芯片都可以很好的去应用.
#include <AT89X51.H> sbit SDA=P2^5;//SDA sbit SCL=P2^4;//SCL sbit WP=P2^3;//WP /*---------------------------------------------- 6MHZ晶振,AT89CXX ----------------------------------------------*/ void delay20ms(void) { //延时20ms int t=1240; unsigned char i=11; for(;i!=0;i--) for(;t!=0;t--); } //-------------------- void MDDelay(void) { unsigned char i=0; for(;i<=10;i++); } /*------------------------ 开始信号 --------------------------*/ void Start(){ SDA=1;//数据线高电平 SCL=1;//时钟高电平 MDDelay(); SDA=0;//数据下跳作为开始信号 SCL=0;//时钟高电平 MDDelay(); } /*----------------------- 停止信号 -----------------------*/ void Stop(){ SDA=0;//数据线高电平 SCL=1;//时钟高电平 MDDelay(); SDA=1;//数据线高电平 MDDelay(); }
/*----------------------- 发送应答 -----------------------*/ void Ack() { SDA=0; SCL=1; MDDelay(); SCL=0; } /*----------------------- 发送不应答 -----------------------*/ void NoAck() { SDA=1; SCL=1; MDDelay(); SCL=0; } /*------------------------------------------------------- 写一个byte -------------------------------------------------------------*/ void WriteByte(unsigned char BufByte) { unsigned char i; for(i=1;i<=8;i++){ SCL=1; MDDelay(); SDA=(bit)(BufByte&0x80);//从高位开始写入,输出一位数据 SCL=0; MDDelay(); BufByte<<=1;//左移一位 } SCL=0; } /*-------------------------------------------------- 写(page wirte) 24C04 --------------------------------------------------*/ void Write24c04(unsigned char *ArrayData,unsigned char RomAddress,unsigned char ArrayLen) { Start();//发送开始信号 WriteByte(0xA0);//"写"命令+片选地下信号(只有一个a2,a1,a0==0) Ack(); WriteByte(RomAddress);//准备写入EEPROM地址信息 Ack(); for(;ArrayLen!=0;ArrayLen--) { WriteByte(*ArrayData); Ack(); ArrayData++;//指针下移取下一个ArrayData数组的地址 } Stop();//发送停止信号 } /*---------------------------------- 读一个byte -------------------------------------*/ unsigned char Read8Bit() { unsigned char i,rbyte=0; SDA=1; for(i=1;i<=8;i++) { SCL=1; SCL=0; rbyte<<=1; if(SDA) rbyte|=0x01; } return(rbyte); }
/*-------------------------------------------------- 读24C004 (Randowm read 方式) --------------------------------------------------*/ void Read24c04(unsigned char *ReadData,unsigned char RomAddress,unsigned char bytes) { unsigned char i; for(i=0;i<bytes;i++){
Start();//发送开始信号 WriteByte(0xA0);//"写"命令+片选地下信号 Ack(); WriteByte(RomAddress+i);//写入片地址信息 Ack(); //-------------- Start();//重复发送开始信号,注:这里和写不同 WriteByte(0xA1);//(读)+片选地值(000) Ack(); //--------- *(ReadData+i)=Read8Bit();//将读来的数据保存至ReadBuf数组中 NoAck(); Stop(); } } /*-------------------------- 初始化port ---------------------------*/ void Rest() { WP=0;//置低电平,清除写保护 SDA=0;//数据总线置低电平 SCL=0;//时钟置低电平 } void main() { unsigned char myd[9]={'1','2','3','4','5','6','7','8','\0'}; unsigned char myRead[9]; Rest(); Write24c04(&myd,0x00,9); delay20ms(); delay20ms(); Read24c04(&myRead,0x00,9); delay20ms(); delay20ms(); }

|