您的位置:首页 > 其它

AT24C01/02/04/08/16/32系列EEPROM驱动程序

2009-11-04 13:19 267 查看
/*------------------------------------------------------------------------------

〖说明〗24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。

现缺页写、页读,和CRC校验程序。以下程序经过50台验证,批量的效果有待考察。

为了安全起见,程序中很多NOP是冗余的,希望读者能进一步精简,但必须经过验证。

Atmel 24C01 比较特殊,为简约型,为其单独编程.

51晶振为11.0592MHz

〖文件〗RW24CXX.c 2001/09/18

--------------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------------------------------------------

调用方式:void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata) ﹫2001/09/18

函数说明:对于IIC芯片24CXX,在指定地址address写入一个字节ddata

调用方式:unsigned char ReadIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address) ﹫2001/09/18

函数说明:读取IIC芯片24CXX,指定地址address的数据。

-----------------------------------------------------------------------------------------------------------------*/

#include "reg51.h"

#include "intrins.h"

sbit SCL= P2^7;

sbit SDA= P2^6;

enum EEPROMTYPE {IIC24C01,IIC24C01A,IIC24C02,IIC24C04,IIC24C08,IIC24C16,IIC24C32,IIC24C64,IIC24C128,IIC24C256};

enum EEPROMTYPE eepromtype;

delay()

{

unsigned int i=1200;

while(i--);

}

/*----------------------------------------------------------------------------

调用方式:write_8bit(unsigned char ch) ﹫2001/03/23

函数说明:内函数,私有,用户不直接调用。

-------------------------------------------------------------------------------*/

void write_8bit(unsigned char ch)

{

unsigned char i=8;

SCL=0;

_nop_();_nop_();_nop_();_nop_();_nop_();

while (i--)

{

SDA=(bit)(ch&0x80);

_nop_();_nop_();_nop_();_nop_();_nop_();

ch<<=1;

SCL=1;

_nop_();_nop_();_nop_();_nop_();_nop_();

SCL=0;

_nop_();_nop_();_nop_();_nop_();_nop_();

}

_nop_();_nop_();_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();_nop_();_nop_();

}

/*------------------------------------------------------------------------------

调用方式:void ACK(void) ﹫2001/03/23

函数说明:内函数,私有,用户不直接调用。

-------------------------------------------------------------------------------*/

void ACK(void)

{

unsigned char time_1;

SDA=1;

SCL=0;

_nop_();_nop_();_nop_();_nop_();_nop_();

SCL=1;

time_1=5;

while(SDA) {if (!time_1) break;} //ACK

SCL=0;

_nop_();_nop_();_nop_();_nop_();_nop_();

}

void WriteIIC_24C01(unsigned char address,unsigned char ddata)

{SCL=1;

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA

SDA=0;

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA

SCL=0; //START

write_8bit( (address<<1) & 0xfe); //写页地址和操作方式,对于24C32-24C256,page不起作用

ACK();

write_8bit(ddata); //发送数据

ACK();

SDA=0;

_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

SDA=1; //STOP

delay();

}

/*---------------------------------------------------------------------------------------------------------------

调用方式:void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata) ﹫2001/09/18

函数说明:对于IIC芯片24CXX,在指定地址address写入一个字节ddata

-----------------------------------------------------------------------------------------------------------------*/

void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata)

{ unsigned char page,address_in_page;

if(eepromtype==IIC24C01) //如果是24c01

{

WriteIIC_24C01(address,ddata);

return;

}

page=(unsigned char)(address>>8) & 0x07;

page=page<<1;

address_in_page=(unsigned char)(address);

SCL=1;

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA

SDA=0;

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA

SCL=0; //START

write_8bit(0xa0 | page); //写页地址和操作方式,对于24C32-24C256,page不起作用

ACK();

if(eepromtype>IIC24C16) //如果是24C01-24C16,地址为一字节;24C32-24C256,地址为二字节

{

write_8bit(address>>8);

ACK();

}

write_8bit(address_in_page);

ACK();

write_8bit(ddata);

ACK();

SDA=0;

_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

SDA=1; //STOP

delay();

}

unsigned char ReadIIC_24C01(unsigned char address)

{

unsigned char ddata=0;

unsigned char i=8;

SCL=1;

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA

SDA=0;

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA

SCL=0; //START

write_8bit( (address<<1) | 0x01); //写页地址和操作方式

ACK();

while (i--)

{

SDA=1;

ddata<<=1;

SCL=0;

_nop_();_nop_();_nop_();_nop_();_nop_();

SCL=1;

if (SDA) ddata|=0x01;

}

SCL=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

SDA=1; //STOP

delay();

return ddata;

}

/*----------------------------------------------------------------------------------------------------

调用方式:unsigned char ReadIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address) ﹫2001/09/18

函数说明:读取IIC芯片24CXX,指定地址address的数据。

------------------------------------------------------------------------------------------------------*/

unsigned char ReadIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address)

{ unsigned char page,address_in_page;

unsigned char ddata=0;

unsigned char i=8;

if(eepromtype==IIC24C01)

{

return( ReadIIC_24C01(address) );

}

page=(unsigned char)(address>>8) & 0x07;

page=page<<1;

address_in_page=(unsigned char)(address);

SDA=0;_nop_();SCL=0; //START

write_8bit(0xa0 | page); //写页地址和操作方式,对于24C32-24C256,page不起作用

ACK();

if(eepromtype>IIC24C16) //如果是24C32-24C256,地址为二字节,先送高位,后送低位

{

write_8bit(address>>8);

ACK();

}

//如果是24C01-24C16,地址为一字节;

write_8bit(address_in_page);

ACK();//以上是一个“哑”写操作,相当于设置当前地址

SCL=1;

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Tsu:STA

SDA=0;

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA

SCL=0; //START

write_8bit(0xa1); //写从地址,置为读模式

ACK();

while (i--)

{

SDA=1;

ddata<<=1;

SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;

if (SDA) ddata|=0x01;

}

SCL=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

SDA=1; //STOP

delay();

return ddata;

}

/*分析:

该芯片采用传统的IIC口的规约形式,是一个标准的经典IIC封装。

注:使用该程序时注意改变芯片各个接口的修改。注意屏蔽主函数。

*/

main()

{

unsigned int i;

unsigned char kk,j[32];

delay();

kk=ReadIIC_24C01( 12 );

WriteIIC_24C01(12,0x67);

kk=ReadIIC_24C01(12);

for(i=0;i<32;i++) j[i]=ReadIIC_24CXX(IIC24C01,i);

for(i=0;i<32;i++) j[i]=i*2;

for(i=0;i<32;i++) WriteIIC_24CXX(IIC24C01,i,0x55);

for(i=0;i<32;i++) j[i]=0;

for(i=0;i<32;i++) j[i]=ReadIIC_24CXX(IIC24C02,i);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: