#i nclude <E2ROM.h>
#i nclude <string.h>
extern struct Parameter code Par[];
extern int Current_Parameter_Value;
extern char Current_Parameter_Attrib;
//************************************************
void I2cWait(void) //延时,I2c大约30k/s
{
unsigned char i;
for(i=10;i>0;i--)
{
i="i";
}
}
//************************************************
void I2cStart(void) // 起始信号
{
SDA = 1;
SCL = 1; I2cWait(); //起始条件建立时间大于4.7us,延时*/
SDA = 0; I2cWait(); //发送起始信号
SCL = 0;
}
//************************************************
void I2cStop(void) //停止信号
{
SDA = 0;
SCL = 1; I2cWait();
SDA = 1; I2cWait();
SCL = 0;
}
//************************************************
void mast_ack(void) //主答函数
{ SDA="0";
SCL="1";I2cWait();
SCL="0";
SDA="1";
}
//************************************************
void mast_nack(void) //主不答函数
{
SDA="1";
SCL="1";I2cWait();
SCL="0";I2cWait();
SDA="0";
}
//************************************************
void ack(void) //应答函数
{ SDA="1";
SCL="1";I2cWait();
// while(SDA){;} //等,直到成功
if(SDA)
E2ROM_ERROR=1; //失败或出错
else
E2ROM_ERROR=0; //成功
SCL="0";I2cWait();
}
//************************************************
void I2cSendByte(unsigned char bytedata) //送一字节数据到slave,成功返回1,失败返回0
{ unsigned char i="8";
// SCL="0";I2cWait();
for(i=0;i<8;i++)
{
if(bytedata & 0x80)
SDA = 1;
else
{SDA = 0;
}
SCL = 1;I2cWait();
SCL = 0;
bytedata <<= 1;
}
I2cWait();
ack();
}
/************************************************************
* 从slave接收1字节数据
************************************************************
*/
unsigned char I2cReceiveByte(void) //接收1字节数据
{
unsigned char i;
unsigned char bytedata = 0;
for(i=0;i<8;i++)
{SDA = 1;
SCL = 1;I2cWait(); //置时钟线为高使数据线上数据有效
bytedata <<= 1;
if(SDA)
{
bytedata |= 0x01;
}
SCL = 0;I2cWait(); //置时钟线为低,准备接收数据位
}
//SCL = 0; I2cWait();
return bytedata;
}
/*
************************************************************
* 从E2ROM指定地址读取1字节数据
************************************************************
*/
unsigned char E2ROM_ByteRead(unsigned int address)
{
unsigned char bytedata;
unsigned char addh,addl;
EA="0"; //避免与中断冲突
addl="address"&0xff; //有关地址的计算参考手册Block部分
addh="address">>7;
addh="addh"&0x0e;
I2cStart();
I2cSendByte(E2ROM_WR); E2ROM_ERROR_CHECK;
I2cSendByte(addl); E2ROM_ERROR_CHECK;
I2cStart();
I2cSendByte(E2ROM_RD|addh); E2ROM_ERROR_CHECK;
bytedata="I2cReceiveByte"();
mast_nack();
I2cStop();
EA="1";
return bytedata;
}
/*
************************************************************
* 从E2ROM指定地址(为首地址)读取number字节数据,放在目的地址
************************************************************
*/
bit E2ROM_PageRead(unsigned int address,unsigned char *daddress,unsigned char number)
{
unsigned char j;
unsigned char addh,addl;
EA="0"; //关中断,避免中断的影响
addl="address"&0xff; //有关地址的计算参考手册Block部分
addh="address">>7;
addh="addh"&0x0e;
I2cStart();
I2cSendByte(E2ROM_WR); E2ROM_ERROR_CHECK;
I2cSendByte(addl); E2ROM_ERROR_CHECK;
// I2cSendByte(addh); E2ROM_ERROR_CHECK;
I2cStart();
I2cSendByte(E2ROM_RD|addh); //读
E2ROM_ERROR_CHECK;
for(j=number-1;j>0;j--) //接收数据
{ *daddress=I2cReceiveByte();
daddress++;
mast_ack();
}
*daddress=I2cReceiveByte();
mast_nack(); //停止接收
I2cStop();
EA="1";
return 1; //成功返回1
}
/*
************************************************************
* 向E2ROM指定地址写1字节数据
************************************************************
*/
bit E2ROM_ByteWrite(unsigned int address,unsigned char bytedata)
{
unsigned char addressh,addressl;
EA="0";
addressl = address&0xFF; //有关地址的计算参考手册Block部分
addressh = address>>7;
addressh = addressh&0x0e;
I2cStart();
I2cSendByte(E2ROM_WR|addressh); E2ROM_ERROR_CHECK;
I2cSendByte(addressl); E2ROM_ERROR_CHECK;
I2cSendByte(bytedata); E2ROM_ERROR_CHECK;
I2cStop(); I2cWait();
EA="1";
return 1; //成功返回1
}
/*
************************************************************
* 向E2ROM指定地址为首址,连续写n字节数据
* address:指定E2ROM 首地址
* saddress:数据源地址
* number:数据个数,对于24lc16该个数不能大于16,否则卷页
************************************************************
*/
bit E2ROM_PageWrite(unsigned int address,unsigned char *saddress,unsigned char number)
{
unsigned char i;
unsigned char addressh,addressl;
EA="0";
addressl = address&0xFF; //有关地址的计算参考手册Block部分
addressh = address>>7;
addressh =addressh*0x0e;
I2cStart();
I2cSendByte(E2ROM_WR|addressh); //指定页地址
E2ROM_ERROR_CHECK;
I2cSendByte(addressl); E2ROM_ERROR_CHECK;
for(i=number;i>0;i--)
{I2cSendByte(*saddress); E2ROM_ERROR_CHECK;
saddress++;
}
I2cWait();
I2cStop();
I2cWait();
EA="1";
return 1;
}
/*
************************************************************
* 向E2ROM写入参数值及属性
* 因所选器件24lc16B的特殊性,在进行写操作时不能连续写入超过16
* 字节的字符串,且如果在连续写入的地址中,如果包括16的整数倍
* 将卷页,例如将1,2,3写入15,16,17地址中,那么3将写到1地址中
* 如果以后升级将修改该函数
************************************************************
*/
void Write_Parameter(unsigned char which)
{unsigned int address,temp;
unsigned char Err_Count,str[3];
str[0]=Current_Parameter_Value>>8;
str[1]=Current_Parameter_Value&0xff;
str[2]=Current_Parameter_Attrib;
temp=which/5; //每页写5个参数,选择5是因为3*5=15<16
temp=temp<<4; //temp=temp*16
which=which%5; //
address=Par_Addrees+which*3+temp;
for(;;)
{E2ROM_PageWrite(address,str,3);
if((!E2ROM_ERROR)||Err_Count>10) //连续写10次出错,则退出
break;
Err_Count++;
}
I2cWait();
I2cWait();
// I2cWait();
}
/*
************************************************************
* 向E2ROM写入所有参数值及属性
* 如果以后升级将修改该函数
************************************************************
*/
void Write_All_Parameter(void)
{unsigned int address,temp;
unsigned char i,Err_Count,tempi,str[3];
for(i=0;i<Par_NUM;i++)
{
str[0]=Par.Default>>8;
str[1]=Par.Default&0xff;
str[2]=Par.Attrib;
temp="i/5"; //每页写5个参数,选择5是因为3*5=15<16
temp="temp"<<4; //temp=temp*16
tempi="i"%5;
address="Par"_Addrees+tempi*3+temp;
E2ROM_PageWrite(address,str,3);
if(E2ROM_ERROR) //如果写入错误,重写
{i--;
Err_Count++;
if(Err_Count>50) //连续50次没有正确读出,则退出
break;
}
Err_Count=0;
I2cWait();
I2cWait();
E2ROM_PageWrite(FLAG_ADDRESS,"OK",2); //将“OK”写入标志位置
I2cWait();
I2cWait();
}
for(i=0;i<50;i++) //等待写完成,不得<40
I2cWait();
}
/*
************************************************************
* E2ROM读入参数值及属性 *
* 如果以后升级将修改该函数 *
* 入口:which:那个参数 *
* 出口:Current_Parameter_Value, 全局变量,当前参数值 *
* Current_Parameter_Attrib,全局变量,当前参数属性 *
************************************************************
*/
void Read_Parameter(unsigned char which)
{unsigned int address,temp;
unsigned char str[3];
temp=which/5; //每页写5个参数,选择5是因为3*5=15<16
temp=temp<<4; //temp=temp*16
which=which%5; //
address=Par_Addrees+which*3+temp;
E2ROM_PageRead(address,str,3);
temp=str[0];
temp=temp<<8;
Current_Parameter_Value=temp+str[1]; //Current_Parameter_Value=str[0]|str[1];
Current_Parameter_Attrib=str[2];
I2cWait();
I2cWait();
// I2cWait();
}
/*
************************************************************
* 检查参数是否已经正确写入E2ROM子程序 *
************************************************************
*/
void Check_Parameter_Write_OK(void)
{unsigned char str[2];
E2ROM_PageRead(FLAG_ADDRESS,str,2);
if(strcmp(str,"OK")==0) //如果已经正确写入则退出
return;
Write_All_Parameter();
}
文章评论(0条评论)
登录后参与讨论