查看: 926|回复: 0
打印 上一主题 下一主题

STM32 使用定时器中断防止硬件IIC卡死

[复制链接]
跳转到指定楼层
沙发
发表于 2016-5-28 18:16:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
由于需要调试一个IIC从器件,期间插拔线或者接触不好经常出现死机,后来发现是卡在IIC通讯上面。
硬件IIC的库函数很多地方是while(。。。),没有长时间无返回就退出机制,因此很容易挂掉。
新思路是:在IIC  while(。。。)等待里面再加一个变量iic_time,使用定时器去改变此变量值
在while(。。。)里面除了判断状态参数外还要判断时间,这里设了5ms,只要到了5ms,不管接没接收到状态数据都退出while。
这样可以保证不会死机。
程序可参考如下:
void TIM3_start(void)
{
  iic_time=1;
  TIM_DeInit(TIM3);
  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  TIM_TimeBaseInitStructure.TIM_Period=5000;//定时5ms
  TIM_TimeBaseInitStructure.TIM_Prescaler=71;//1M时钟
  TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
  TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3,& TIM_TimeBaseInitStructure);
  TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标示位
  TIM_ITConfig(TIM3,TIM_IT_Update, ENABLE );//使能中断
  TIM_Cmd(TIM3, ENABLE);//开始计数
}
void TIM3_stop(void)
{
  iic_time=1;
  TIM_Cmd(TIM3, DISABLE);//停止计数
  TIM_ITConfig(TIM3,TIM_IT_Update, DISABLE );//停止转换
  TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标示位
}
void TIM3_IRQHandler(void)
{
  if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    iic_time=0;
  }
}
void I2C2_WriteByte(u8 id,u8 write_address, u8 datal)//写一个字节
    {
        TIM3_start();
        while((I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY))&(iic_time==1));
        TIM3_stop();
        I2C_AcknowledgeConfig(I2C1, ENABLE);
        I2C_GenerateSTART(I2C2,ENABLE);
        TIM3_start();
        while((!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))&(iic_time==1));  //等待ACK
        TIM3_stop();
        I2C_Send7bitAddress(I2C2,id,I2C_Direction_Transmitter);//发送设备地址
        TIM3_start();
       while((!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))&(iic_time==1));//等待ACK
        TIM3_stop();
        I2C_SendData(I2C2, write_address);//寄存器地址
        TIM3_start();
       while((!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&(iic_time==1));//等待ACK
        TIM3_stop();
        I2C_SendData(I2C2, datal);//发送数据  
        TIM3_start();
        while((!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))&(iic_time==1));//发送完成
         TIM3_stop();
        I2C_GenerateSTOP(I2C2, ENABLE);//产生结束信号
    }
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表