tag 标签: 超时

相关博文
  • 热度 23
    2013-1-11 19:37
    5594 次阅读|
    0 个评论
    如今,I2C接口用的很多,使用两根线,即使加上地线一共才三根线,传输简单便捷;对于很多传感器和E2PROM都使用这种传输协议。 对于不采用中断功能的I2C数据传输,超时处理时必须;假如没有超时处理,一旦传输出错或者I2C器件损坏,整个程序都停在那儿了。 个人觉着,要解决超时的问题,首先我们要分清使用的是模拟的I2C还是硬件I2C?我们只是从MCU主模式来考虑问题,对于硬件I2C,我们可以用一个定时器设置超时指针,定时器必须采用中断的方式,因为只有中断,才能跳过无休止的等待。这样在I2C即使工作在查询模式,也能进行超时处理,而且不影响程序正常时的效率。   首先看一下,如何写一个字节 /****************************************** I2C总线写一个字节 返回0:写成功 返回非0:写失败 *******************************************/ unsigned char i2c_Write(unsigned char Wdata,unsigned char RomAddress)  {   Start();//I2C启动   Wait();   if(TestAck()!=START) return 1;//ACK   Write8Bit(wr_device_add);//写I2C从器件地址和写方式   Wait();   if(TestAck()!=MT_SLA_ACK) return 1;//ACK   Write8Bit(RomAddress);//写24C02的ROM地址   Wait();   if(TestAck()!=MT_DATA_ACK) return 1;//ACK   Write8Bit(Wdata);//写数据到24C02的ROM   Wait();   if(TestAck()!=MT_DATA_ACK) return 1;//ACK   Stop();//I2C停止  // delay_ms(10);//延时等EEPROM写完   return 0; }   我们要做的超时处理,就是在wait()中 加入超时处理,超时标志假设为time_out_sym,初始值为0,在进入wait()时,打开超时计数窗口,有定时器中断处理,在发生超时后对time_out_sym置1,否则对所有相关标志复位。 那么这个函数就相当于 void wait(void) {  while(!((TWCR(1 }   如此一来就可以进行简单的超时处理了!这个思路,实际上起源于某MCU官网上的一个关于I2C的例程,个人觉得这样处理很不错,所以写下来和大家分享!实际上我们仔细想想,对于模拟的I2C接口,超时处理也是可以采用这种方式的,只不过处理起来比硬件的相对麻烦一些罢了。 下面是硬件IIC超时处理: //在AT24CXX指定地址写入一个数据 //WriteAddr  :写入数据的目的地址     //DataToWrite:要写入的数据 void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite) {             IIC_Start();   if(EE_TYPEAT24C16) { IIC_Send_Byte(0XA0);    //发送写命令 IIC_Wait_Ack(); IIC_Send_Byte(WriteAddr8);//发送高地址 }else IIC_Send_Byte(0XA0+((WriteAddr/256)1));   //发送器件地址0XA0,写数据 IIC_Wait_Ack();        IIC_Send_Byte(WriteAddr%256);   //发送低地址 IIC_Wait_Ack();      IIC_Send_Byte(DataToWrite);     //发送字节    IIC_Wait_Ack();              IIC_Stop();//产生一个停止条件  delay_ms(10); }   标志处理也是采用中断方式,加在IIC_wait_Ack()上 //等待应答信号到来 //返回值:1,接收应答失败 //        0,接收应答成功 u8 IIC_Wait_Ack(void) { u8 ucErrTime=0; SDA_IN();      //SDA设置为输入   IIC_SDA=1;delay_us(1);    IIC_SCL=1;delay_us(1); while(READ_SDA|t ime_out_sym ) { ucErrTime++; if(ucErrTime250) { IIC_Stop(); return 1; } } IIC_SCL=0;//时钟输出0    return 0;   }  )|time_out_sym))) )|time_out_sym)));
相关资源