最近看到好多人都在寻找有关单片机对24c01/02系列存储器操作的程序,在这里我把以前我用过的源代码公开出来,这样大家可以直接使用,不必为调试程序而浪费大家的项目进度的时间了。使用该程序的人,希望您能在留言里支持一下,谢谢!--------小盒子 于07.05.30 大连
/*
**************************************************************************************************************
* Copyright (c) 2005 - 2010 Corp. Small.Box ,All rights reserved.
*
* FILENAME
* eeprom_24Cxx.c
*
* VERSION
* V1.00
*
* HISTORY
* 2005/04/16 13:27 Ver 1.0 Created by Small.Box
*
* REMARK
*
*
**************************************************************************************************************
*/
#include "reg52.h"
#include "intrins.h"
#include "../inc/opt.h"
#include "../inc/eeprom_24Cxx.h"
//AT24C02 EEPROM 相关的引脚参数
sbit SCL = P1^1;
sbit SDA = P1^2;
sbit WP = P1^3;
//自定义读写出错次数
#define ERRORCOUNT 10
/*
*******************************************************************************
* IICStart
*
*Description: 启动总线
*
*Arguments : 无
*
*Returns : 无
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
void IICStart(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
SDA=1;
}
/*
*******************************************************************************
* IICStop
*
*Description: 停止IIC总线
*
*Arguments : 无
*
*Returns : 无
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
void IICStop(void)
{
SCL=0;
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*
*******************************************************************************
* IICRecAck
*
*Description: 检查应答位
*
*Arguments : 无
*
*Returns :
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
bit IICRecAck(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
CY=SDA; //因为返回值总是放在CY中的
SCL=0;
return(CY);
}
/*
*******************************************************************************
* IICAck
*
*Description: 对IIC总线产生应答
*
*Arguments : 无
*
*Returns : 无
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
void IICAck(void)
{
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
SDA=1;
}
/*
*******************************************************************************
* IICNoAck
*
*Description: 不对IIC总线产生应答
*
*Arguments : 无
*
*Returns : 无
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
void IICNoAck(void)
{
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*
*******************************************************************************
* IICSendByte
*
*Description: 向IIC总线写数据
*
*Arguments : sendbyte 写入的数据
*
*Returns : 无
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
void IICSendByte(INT8U sendbyte)
{
INT8U data j;
j=8;
for(;j>0;j--){
SCL=0;
sendbyte<<=1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7;
SDA=CY;
SCL=1;
}
SCL=0;
}
/*
*******************************************************************************
* IICReceiveByte
*
*Description: 从IIC总线上读数据子程序
*
*Arguments : 无
*
*Returns : 读出来的数据
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
INT8U IICReceiveByte(void)
{
INT8U receivebyte,j;
j=8;
SCL=0;
while(j--){
SCL=1;
receivebyte=(receivebyte<<1)|SDA;
SCL=0;
}
return(receivebyte);
}
/*
*******************************************************************************
* Delay
*
*Description: 延时程序
*
*Arguments : DelayCount 延时系数
*
*Returns : 无
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
void Delay(INT8U DelayCount)
{
ClearWatchDog();
while(DelayCount--);
}
/*
*******************************************************************************
* RW24XX
*
*Description: 24C02读写函数
*
*Arguments : DataBuff 为读写数据输入/输出缓冲区的首址
* ByteQuantity 为要读写数据的字节数量
* Address 为EEPROM的片内地址
* ControlByte 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W)
* 其中R/W=1,表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;
* ERRORCOUNT 为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1
*
*Returns : 若返回1表示此次操作失效,
* 若返回0表示操作成功;
*
*Note : V1.0 by Small.Box at 2005.04.16
*
*******************************************************************************
*/
bit RW24XX(INT8U *DataBuff, INT8U ByteQuantity, INT8U Address, INT8U ControlByte)
{
INT8U j,i=ERRORCOUNT;
bit errorflag=1;
INT16U t;
EA=0;
WP=0;
for(t=0;t<10;t++);
while(i--){
ClearWatchDog();
IICStart(); //起始位
IICSendByte(ControlByte&0xfe); //写器件地址
if(IICRecAck())
continue;
IICSendByte(Address); //写写入/读出地址
if(IICRecAck())
continue;
if(!(ControlByte&0x01)){ // R/W=0则写入
j=ByteQuantity;
errorflag=0; //清除错误标记位
while(j--){
IICSendByte(*DataBuff++);
if(!IICRecAck())
continue;
errorflag=1;
break;
}
if(errorflag==1)
continue;
break;
}
else{ //R/W=1则读出
IICStart();
IICSendByte(ControlByte);
if(IICRecAck())
continue;
while(--ByteQuantity){
*DataBuff++=IICReceiveByte();
IICAck();
}
*DataBuff=IICReceiveByte(); //读最后一个字节数据
IICNoAck();
errorflag=0;
break;
}
}
IICStop();
if(!(ControlByte&0x01)){ //如为写入则延时等待写入完成
Delay(255);
Delay(255);
Delay(255);
Delay(255);
}
WP=1;
EA=1;
return(errorflag);
}
/*
*******************************************************************************
* WriteEEPromBlock
*
*Description: 向EEPROM中写入数据块
*
*Arguments :
*
*Returns :
*
*Note : V1.0 Created by Small.Box at 2005.04.19
*
*******************************************************************************
*/
INT8U WriteEEPromBlock(INT8U *buf, INT8U len, INT8U addr)
{
INT8U wflag;
wflag = RW24XX(buf, len, addr, WRITE24XX);
if(wflag == TRUE) {
return TRUE;
} else {
return FALSE;
}
}
/*
*******************************************************************************
* ReadEEPromBlock
*
*Description: 读取EEPROM中数据
*
*Arguments :
*
*Returns :
*
*Note : V1.0 Created by Small.Box at 2005.04.19
*
*******************************************************************************
*/
INT8U ReadEEPromBlock(INT8U *buf, INT8U len, INT8U addr)
{
INT8U rflag;
rflag = RW24XX(buf, len, addr, READ24XX);
if(rflag == TRUE) {
return TRUE;
} else {
return FALSE;
}
}
/*$PAGE*/
/*
**************************************************************************************************************
* Copyright (c) 2005 - 2010 Corp. Small.Box ,All rights reserved.
*
* FILENAME
* eeprom_24Cxx.h
*
* VERSION
* V1.00
*
* HISTORY
* 2005/04/16 13:27 Ver 1.0 Created by Small.Box
*
* REMARK
*
*
**************************************************************************************************************
*/
#ifndef __PARKSYS_EEPROM_24CXX_H
#define __PARKSYS_EEPROM_24CXX_H
#define WRITE24XX 0
#define READ24XX 1
#define WRITECNT 10000
bit RW24XX(INT8U *DataBuff,INT8U ByteQuantity,INT8U Address,INT8U ControlByte);
INT8U WriteEEPromBlock(INT8U *buf, INT8U len, INT8U addr);
INT8U ReadEEPromBlock(INT8U *buf, INT8U len, INT8U addr);
#endif