原创 24lc16c读写程序

2007-8-21 19:09 3027 4 4 分类: 通信

#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条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /2 下一条