原创 铁电I2C一体化安全读写程序

2006-12-30 01:22 5118 12 12 分类: MCU/ 嵌入式


铁电I2C一体化安全读写程序
mood0.gif hotpower 发表于 2005-6-17 23:45:33 侃单片机 ←返回版面 按此给该网友发送邮件 按此察看该网友的资料 按此把文章加入收藏夹



/*--------------------------------------------------------------------------
           铁电I2C一体化安全读写程序
                                          2004.6.18 作于西安大雁塔村大队部
--------------------------------------------------------------------------*/

//I2C收发一体化START执行检测函数
bit I2CStart(void)
{
  EA=0;//关中断
  WP = 0;//允许写
  ClrWdt();//喂狗
  SDA=1; SCL="1";//释放总线
  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  CY = SDA & SCL;//测试总线
//  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  SDA=0;//Start信号开始
  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  SCL=0;//注意SCL在除函数I2CStop()外其他模块都是进入或退出SCL=0
  return CY;//总线忙CY=0,总线空闲CY=1
}

//I2C收发一体化STOP执行检测函数
void I2CStop(void)
{
  SCL=0; SDA="0";//在SCL为低时准备Stop信号
  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  SCL=1;
  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  SDA=1; //STOP信号结束
  WP = 1;//写保护
  EA=1;//开中断
}

//I2C收发一体化ACK读写函数
bit I2CAck(unsigned char val)
{
unsigned char i;
  SDA = val & 1;//写入1位ACK数据
  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  SCL = 1;//拉高I2C时钟
  _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
  CY = SDA;//读回1位ACK数据
  if (val <= 1) {//需要从机应答信号
    for (i = 255; i > 0; i --) {
      if (!(CY = SDA)) break;//收到从机应答信号立即退出
    }
  }
  SCL = 0;//拉低I2C时钟
  return CY;//返回读回ACK数据
}

//I2C收发一体化读写函数
unsigned char I2CReadWrite(unsigned char val)
{
unsigned char i;
  ACC = val;//取写入数据
  for (i = 8; i > 0; i --) {//收发8位数据
    SCL = 0;//拉低I2C时钟
    _rlca_();//左移1位数据(取出1位写入数据)
     SDA = CY;//写入1位I2C数据
    _rrca_();//右移1位还原数据
//    _nop_();_nop_();_nop_();_nop_();_nop_();//延时4.7uS
//如果不追求高速,可在此加入一些总线冲突裁决程序
//即SDA=1时,读回若为0则为总线冲突
    SCL = 1;//拉高I2C时钟
    CY = SDA;//读回1位I2C数据
    _rlca_();//左移最后1位数据
  }
  SCL = 0;//拉低I2C时钟
  return ACC;//返回读回数据
}


//多字节读铁电数据
unsigned char ReadFM24C256(unsigned int readaddress,unsigned char count,unsigned char buff[])
{
unsigned char i, status = 0;//无错误返回状态为0
  if (!I2CStart()) status = 0xe1;//总线未释放
  else {
    I2CReadWrite(0xA0);//发送器件写地址
    if (I2CAck(1)) status = 0xe2;//未收到从机器件写地址应答信号
    else {
      I2CReadWrite(readaddress >> 8);//发送从机存储高位地址
      if (I2CAck(1)) status = 0xe3;//未收到从机存储高位地址应答信号
      else {
        I2CReadWrite(readaddress & 0xff);//发送从机存储低位位地址
        if (I2CAck(1)) status = 0xe4;//未收到从机存储低位位地址应答信号
        else {
          if (!I2CStart()) status = 0xe5;//发送重复位失败
          else {
            I2CReadWrite(0xA1);//发送器件读地址
            if (I2CAck(1)) status = 0xe6;//未收到从机器件读地址应答信号
            else {
              for (i = 0;i < count;i ++) {
                buff = I2CReadWrite(0xff);//读出从机存储数据(一体化读时需写0xFF)
                if (i != count - 1) I2CAck(2);//除最后一个字节外,其他都要MASTER发应答。
                else I2CAck(3);//最后一个字节不需MASTER发应答。
              }
            }
          }
        }
      }
    }
  }
  I2CStop();//结束通讯释放总线
  return status;//出错返回非0
}

//多字节写铁电数据
unsigned char WriteFM24C256(unsigned int readaddress,unsigned char count,unsigned char buff[])
{
unsigned char i, status = 0;//无错误返回状态为0
  if (!I2CStart()) status = 0xe1;//总线未释放
  else {
    I2CReadWrite(0xA0);//发送器件写地址
    if (I2CAck(1)) status = 0xe2;//未收到从机器件地址应答信号
    else {
      I2CReadWrite(readaddress >> 8);//发送从机存储高位地址
      if (I2CAck(1)) status = 0xe3;//未收到从机存储高位地址应答信号
      else {
        I2CReadWrite(readaddress & 0xff);//发送从机存储低位位地址
        if (I2CAck(1)) status = 0xe4;//未收到从机存储低位位地址应答信号
        else {
          for (i = 0;i < count;i ++) {
            I2CReadWrite(buff);//写入主机数据
            if (I2CAck(1)) {
              status = 0xe0;//数据写入失败
              break;
            }
          }
        }
      }
    }
  }
  I2CStop();//结束通讯释放总线
  return status;//出错返回非0
}

http://www.21icbbs.com/club/bbs/showEssence.asp?id=6494&page=1

文章评论0条评论)

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