📄 eeprom.c
字号:
#include <head.h>
#include "EEPROM.H"
#include <function.h>
BOOL E_err;
/**************************************************************************
* 函数原型:void I_start(void);
* 功 能:提供I2C总线工作时序中的起始位。
**************************************************************************/
void I_start(void)
{
SCL=HIGH;
_nop_();
_nop_();
SDA=LOW;
_nop_();
_nop_();
SCL=LOW;
_nop_();
_nop_();
}
/**************************************************************************
* 函数原型:void I_stop(void);
* 功 能:提供I2C总线工作时序中的停止位。
**************************************************************************/
void I_stop(void)
{
SDA=LOW;
_nop_();
_nop_();
SCL=HIGH;
_nop_();
_nop_();
SDA=HIGH;
_nop_();
_nop_();
SCL=LOW;
_nop_();
_nop_();
}
/**************************************************************************
* 函数原型:void I_init(void);
* 功 能:I2C总线初始化。在main()函数中应首先调用本函数,然后再用
* I2C其它函数。
**************************************************************************/
void I_init(void)
{
WP=0;
SCL=LOW;
_nop_();
I_stop();
}
/**************************************************************************
* 函数原型:bit I_clock(void);
* 功 能:提供I2C总线的时钟信号,并返回在时钟电平为高期间SDA信号线上状
* 态。本函数可用于数据发送,也可用于数据接收。
**************************************************************************/
BOOL I_clock(void)
{
BOOL sample;
SCL=HIGH;
_nop_();
_nop_();
_nop_();
sample=SDA;
SCL=LOW;
_nop_();
_nop_();
_nop_();
return(sample);
}
/**************************************************************************
* 函数原型:bit I_send(Uchar I_data);
* 功 能:向I2C总线发送8位数据,并请求一个应答信号ACK。如果收到ACK应答,
* 则返回1(TRUE),否则返回0(FALSE)。
**************************************************************************/
BOOL I_send(Uchar I_data)
{
Uchar i;
/*发送8位数据*/
for(i=0;i<8;i++)
{
SDA=(BOOL)(I_data&0x80);
I_data=I_data<<1;
I_clock();
_nop_();
_nop_();
}
/*请求应答信号ACK*/
SDA=HIGH;
for(i=0;i<3;i++)
{
if(!I_clock())return 1;
delayms(1);
}
E_err=1;
return 0;
//return(~I_clock());
}
/**************************************************************************
* 函数原型:Uchar I_receive(void);
* 功 能:从I2C总线上接收8位数据信号,并将接收到的8位数据作为一个字节
* 返回,不回送应答信号ACK。主函数在调用本函数这前应保证SDA信
* 号线处于浮置状态。
**************************************************************************/
Uchar I_receive(void)
{
register Uchar I_data=0;
register Uchar i;
for(i=0;i<8;i++)
{
I_data*=2;
_nop_();
_nop_();
if(I_clock())I_data++;
}
return(I_data);
}
/**************************************************************************
* 函数原型:void E_address(Uchar Address);
* 功 能:向24C02写入器件地址和一个指定的字节地址。
**************************************************************************/
void E_address(Uchar Address)
{
I_start();
I_send(WRITE);
I_send(Address);
}
/**************************************************************************
* 函数原型:void E_writeex(Uchar Address,Uchar *E_data,Uchar datan);
* 功 能:将 24C02 以Address起始的空间读入e_data指向的空间
**************************************************************************/
void E_writeex(Uchar Address,Uchar *E_data,Uchar datan)
{
Uchar i;
for(i=0;i<datan;i++)
{
E_write(Address+i,*(E_data+i));
delayms(10);
}
}
/**************************************************************************
* 函数原型:void E_readex(Uchar Address,Uchar *E_data,Uchar datan);
* 功 能:将E_data所指向的内容写入 24C02 以Address起始的空间
**************************************************************************/
void E_readex(Uchar Address,Uchar *E_data,Uchar datan)
{
Uchar i;
for(i=0;i<datan;i++)
{
*(E_data+i)=E_read(Address+i);
}
}
/**************************************************************************
* 函数原型:void E_write(Uchar Address,Uchar E_data);
* 功 能:将E_data内容写入到24C02的Address单元以及与它相对应的两个备份单元
* 如果总共有六次写入失败,LCD显示E2P ERR的内容,此时专业人员应检查
* 出错原因,系统停止工作。
**************************************************************************/
void E_write(Uchar Address,Uchar E_data)
{
Uchar i;
for(i=0;i<3;i++)
{EA=0;
E_address(Address);
I_send(E_data);
I_stop();
EA=1;
delayms(10);
Address=Address+E2PROM_bias;
}
}
/**************************************************************************
* 函数原型:Uchar E_read(Uchar Address);
* 功 能:从24C02中读出地址为Address单元以及与它相对应的两个备份单元的内容,
* 如果三个都一样,那么返回值就是其中一个值;如果两个一样,另一个不 一样,
* 那么一样的值做为返回值;如果三个都不一样,那么认为中间的值做为返回值。
* 如果三个值有不一样的情况下,必须重新写入。以便三个值都一致。
* 如果读出三个数的失败的次数达到六次, LCD显示E2P ERR的内容,此时专业人员应检查
* 出错原因,系统停止工作。
**************************************************************************/
Uchar E_read(Uchar Address)
{
Uchar i;
Uchar accept[3];
for(i=0;i<3;i++)
{
EA=0;
E_address(Address);
I_start();
I_send(READ);
accept[i]=I_receive();
I_clock();
I_stop();
EA=1;
delayms(1);
Address=Address+E2PROM_bias;
}
if((accept[1]==accept[0])&&(accept[1]==accept[2]))return(accept[1]);
else if((accept[1]!=accept[0])&&(accept[1]!=accept[2]))
{E_err=1; return(accept[1]);}
else if(accept[0]==accept[2])accept[1]=accept[0];
E_write(Address,accept[1]);
return(accept[1]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -