基于STM32的红外遥控器解码逻辑和代码分析

 

v在调试红外解码的时候,遥控器.jpg
首先定了三个方案一个是利用定时器的pwm捕获方法,其次是外部中断加延时计数,第三个是io口轮询定时器计时。首先尝试的第一个,但在移植好程序后发现不能捕获进不了捕获中断,进过查看手册和资料发现钙通道为Tim3N,不具备捕获的功能,后来果断改为方案2,顺利实施。
 
图片1.png
 
v使用外部中断的好处就是响应时间快,不会造成多次按下当时没反应,过后连串反应的问题。抗干扰,中断处理函数内部加判断。增添超时退出,不会造成死循环。
下面进行一下遥控器的解码分析
下面两张图是搜集的解码资料

图片2.png图片3.jpg

 
v分析2张图片我们发现有个共同点,每个波形的起始位置都会有一个不同于后边波形长宽的波形,这是引导码。对于红外编解码都是有一个引导码来引导后边的数据的。
v还有一个共同之处就是  01 的定义是相通的,
v都是通过后边一位的长短来定义是0还是1
v说白了跟第一个没有关系,他是固定的。
v第一张图中如右边,0是由一个短波的高电平500us
v2000us的低电平组成的0 1是由500高电平+1500us低电平。
v第二张图中1  是由一个低电平+2.0ms的高电平组成
v                   0是由一个低电平+1ms的高电平组成  不管是0
v还是1 前边的低电平不变
v不同之处     不同的遥控器 定义波形的0 1  的维持时间不同
v但可以看出是 100us的整数倍
v那么程序中我们就开启一个100us的定时器或者延时100us累加1次的计数器也可以。
v第一次我们先使用了100us的延时,通过仿真,执行一个指令为1/72M  得出的估计时间。
v中断服务函数内先判断引导码,引导码时间根据不断调试得出一个比较稳定的值,便可以得出一个值了,但该值并不是实际的时间。

图片4.png图片5.png

还有一种方式使用stm32的  tim_getcounter()计算,这种方法最好,中断里边加延时不建议使用,只是测试一下而已。

/*************************************************************
名称: Timer4_CFG()
功能: 初始化timer4
输出参数:
作者:v
******************************************************************/

 void Timer4_CFG()
{

TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;


RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO , ENABLE);
 
GPIO_InitStructure.GPIO_Pin = IR_LED_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(IR_LED_PORT, &GPIO_InitStructure);


TIM_TimeBaseStructure.TIM_Prescaler = 3599; //72MHz/(3599+1)=10 000  HZ  50uS
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //
TIM_TimeBaseStructure.TIM_Period = 200;       // ARR基准值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);


TIM_ARRPreloadConfig(TIM4,DISABLE);

TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_ITConfig(TIM4,TIM_IT_Trigger,ENABLE);
TIM_Cmd(TIM4, DISABLE);

}

 

 

/*************************************************************
名称: Remote_Scan()
功能:
输出参数:
作者:v
******************************************************************/
static u8  Remote_Scan()
{
    u16 TIMt=0;
    u16  waitquit;//超时退出
  u8 i,ia;
          if(RDATA()!=0)//先判断是否为0  排除干扰
          return  0;
            TIM_SetCounter(TIM4,0);//TIM4->CNT=0;
            TIM_Cmd(TIM4, ENABLE);
                waitquit=60000;
                do{
                  waitquit--;
                  }
          while((!RDATA())&&(waitquit));//检查高电平的时间4ms
                 TIM_Cmd(TIM4, DISABLE);
   TIMt=TIM_GetCounter(TIM4);
                 if((TIMt<70)||(TIMt>120))
                  return 0;
                  TIM_SetCounter(TIM4,0); 
                  TIM_Cmd(TIM4, ENABLE);
                  waitquit=60000;
                     do{
                        waitquit--;
                       }
   while((RDATA())&&( waitquit));//接收高电平
   TIMt=TIM_GetCounter(TIM4);
                        TIM_Cmd(TIM4, DISABLE);
          if((TIMt>120)||(TIMt<60))//同样 8MS
          return 0;
 
    
 ////////////引导码接收完毕///////开始接收客户码//////////////////////////////
    
 for(i=0;i<3;i++)//接收3个字节 24位码
 {
                      for(ia=0;ia<8;ia++)
                      {
                      TIM_Cmd(TIM4, ENABLE);
                      while(!RDATA());//等待高
                      TIM_SetCounter(TIM4,0);
                      waitquit=60000;//可根据实测调整
                      do{
                      waitquit--;
                      }
                      while((RDATA())&&( waitquit));//接收高电平
                      TIM_Cmd(TIM4, DISABLE);
                      TIMt=TIM_GetCounter(TIM4); 
 ////////////////////////////高电平结束/////////////////////////
                      user_code[i]>>=1;
                      if((TIMt>45))
                      return 0;
                      if((TIMt>35)&&(TIMt<45))//经过实测 在1400us以上为1 小于一般为 9 为0
                      user_code[i]|=0x80;
                      }
   
 }

REM_FLG=1;
return 1;
}

 这两种方法解出来的码都是一样的,用多个也测试过,没有问题很稳定,。

 图片7.png

 

最新评论

  1. 发布于:2015-09-01 13:38 回复
    这篇文章的解码方式是有点问题 不能用于太复杂的功能设备中  改善后的看这里http://www.xiaovdiy.cn/?post=150#146

sitemap