关闭

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

标签: cdelay编程
1157人阅读 评论(0) 收藏 举报
/*------------------------------------------------------------------------------
〖说明〗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的数据。
-----------------------------------------------------------------------------------------------------------------*/

#i nclude "reg51.h"
#i nclude "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);
}



  •  
  • 0
    0
    查看评论

    PPI协议详解 ppi通讯协议 ppi通信协议 vb与ppi协议通讯

    转自:http://blog.csdn.net/vbvcde/article/details/7660497 我们提供 PPI协议的官方文档,协议更新时间为2005年,下面是我们根据文档解析的PPI读取变量返回数据,网上的文献大部分都是讲解如何发送的,对于接收提的很少,其中接收有很多控制位...
    • qq_26093511
    • qq_26093511
    • 2016-12-26 14:48
    • 1202

    几个用过的PPI命令

    注意事项: 1  必须要设置为偶校验(EVEN) 2  双方呼叫联系,发送之前先发一次,要不然总是只返回e5,不返回数据(也可能是中间时间过长,毕竟是手动测试的) 呼叫指令:双方呼叫联系,发送之前先发一次,要不然总是只返回e5,不返回数据 发送:10&#...
    • youhaipeng
    • youhaipeng
    • 2012-05-03 21:09
    • 1301

    PPI协议详解 ppi通讯协议 ppi通信协议 vb与ppi协议通讯

    PPI协议详解 ppi通讯协议  ppi通信协议  vb与ppi协议通讯 PPI协议详解 ppi通讯协议  ppi通信协议  vb与ppi协议通讯 我们提供 PPI协议的官方文档,协议更新时间为2005年,下面是我们根据文档解析的PPI读取...
    • vbvcde
    • vbvcde
    • 2012-06-13 18:32
    • 8531

    Karma-jasmine前端测试工具的配置(windows环境下)

    博客转自:http://www.cnblogs.com/wushangjue/
    • z372574152
    • z372574152
    • 2017-08-20 10:11
    • 157

    向HDFS上传文件时报错16/07/23 01:13:30 WARN hdfs.DFSClient: DataStreamer Exception: org.apache.hadoop.ipc.Rem

    16/07/23 01:13:30 WARN hdfs.DFSClient: DataStreamer Exception: org.apache.hadoop.ipc.RemoteException: java.io.IOException: File /test.txt could only b...
    • ywf008
    • ywf008
    • 2016-07-23 16:19
    • 1347

    java时间转换,2016-06-16T15:02:32转换为2016-06-16 15:02:32

    最近开发过程中,后台返回的时间戳是这样的:        "created_time": "2016-06-16T15:02:32"  中间有个T,在以前的开发过程中是返回一个11位的时间戳,也就是秒,这...
    • ai_yong_jie
    • ai_yong_jie
    • 2016-06-16 16:17
    • 1289

    一个ModBus RTU程序(支持01、02、03、05、06、15、16功能码)

    有两点需要注意的:1、modbus rtu标准协议规定:每帧数据间隔至少为3.5个字符时间。 2、接收发送数据最好改为中断模式,不然通信速度不够。 #include "RS485.h" #include "CRC.h" /////////////////...
    • liboxiu
    • liboxiu
    • 2018-01-11 09:46
    • 197

    再跟大家分享一下AT24C01~AT24C256的读写程序

    /* 在buf1中填入需要写入的内容,buf2的大小可根据需要定义。addr可根据使用的芯片选择,可从任何位置读写,只要在该芯片的范围内。enumer=ATxxx,根据使用的芯片赋值。各函数中的形式参数不需改变。本程序只要在调用的程序中定义实际参数即可,下述各子程序不必改动。*/#include #...
    • gxay2000
    • gxay2000
    • 2010-02-23 10:48
    • 2837

    51单片机之IIC&EEPROM的驱动程序

    51单片机之IIC&EEPROM的驱动程序
    • baidu_35534327
    • baidu_35534327
    • 2016-09-22 20:32
    • 771

    stm32 片上flash用作EEPROM(掉电保存)(绝对可用)

    #if !defined  (_FLASH_H) #define _FLASH_H #define FLASH_ADR 0x08010000  //要写入数据的地址 #define u8 INT8U #define u16 INT16U #defin...
    • sunyiming537
    • sunyiming537
    • 2012-11-15 23:22
    • 2907
      个人资料
      • 访问:1596463次
      • 积分:25481
      • 等级:
      • 排名:第289名
      • 原创:638篇
      • 转载:550篇
      • 译文:2篇
      • 评论:257条