/*-------------------------------------------------------------------------- 铁电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 } |
文章评论(0条评论)
登录后参与讨论