机器人车技术开发分享网
单片机红外遥控器解码例程源码新说
  • 首页 > 单片机ARM系列
  • 作者:小v
  • 2015年8月14日 9:47 星期五
  • 浏览:2565
  • 字号:
  • 评论:3
  • 这是第三次更改这个红外遥控解码的例程了。之前的第一版是直接用51单片机的外部中断然后在里边加延时采集高低电平的长短来判断引导码和位 1 0 的,这个当初不知是从哪看的,这种方式太误导人了,如果想用这种思路移植到stm32上,还是趁早打住吧,stm32这种高级处理器难道只用来红外遥控解码吗?不,肯定会有更高级的任务去等待他处理,外部中断加延时可以提高遥控的响应速度,但实际上这种方式很占资源,当cpu在处理其他紧急任务的时候,突然来个按键,打断进程,并且一置占用进程,经测试过,遥控一个键码有50-90ms,这对单片机来说可是不小的时间啊。所以,可以结合外部中断+定时器两种方式来解码。

    外部中断开启上升和下降沿同时触发。这样的话,我们在两次触发后,计算出高或低的点评时间看是否准确,就可以了。

    可以采用状态机也就是状态变换的思路来解码。引导码和用户码,分成两部分来解。高电平和低电平分成两部分来解码。

    又因为位1 和位0 之间区别在于 高电平的时间不同,也就是 位 0  _||   1

      _|——两者的

    低电平的时间都是一样的,而后边的高电平长的为短的为0 ,有这个特点就特别好解决了。可参考之前的文章, http://www.xiaovdiy.cn/?post=138

    源代码奉上

             if(EXTI_GetITStatus(EXTI_Line12)!= RESET)

             {

              if(RDATA()==0)//说明是下降沿到来

              {

               

            TIM_Cmd(TIM4, ENABLE);

                     if(lead_flg==0)//说明是第一次接收引导码

                     {

                                TIM_SetCounter(TIM4,0);//TIM4->CNT=0;    1

                lead_flg=1;

                       }

                       else if(lead_flg==2)

                       {

                     ir_cnt= TIM_GetCounter(TIM4);    

                TIM_SetCounter(TIM4,0);

                                lead_flg=3;

                                if((ir_cnt<70)||(ir_cnt>90))//测试表明为79 80

                                {

                                  lead_flg=0; //超出范围  退出

                  return 0;

                  

                                }

                       }

                       else if(lead_flg==3)//获得高电平时间

                       {

                                ir_cnt= TIM_GetCounter(TIM4);    

                                TIM_SetCounter(TIM4,0);

                                //接收3个字节 24位码

                    high_cnt++;//加到24   8次为1个字节

                         if(high_cnt<=8)

                                         {

                                                   user_code[0]>>=1;

                                         }

                    if(high_cnt<=16)

                                         {

                                                   user_code[1]>>=1;

                                                   }

                    if(high_cnt<=24)

                                         {

                                                   user_code[2]>>=1;

                                         }

                         if((ir_cnt>35)&&(ir_cnt<45))//我们认为是 bit '1'

                                         {

                             if(high_cnt<=8)

                                                   {

                                                            user_code[0]|=0x80;

     

                                                   }

                        if(high_cnt<=16)

                                                   {

                                                            user_code[1]|=0x80;

                                                   }

                        if(high_cnt<=24)

                                                   {

                                                            user_code[2]|=0x80;}

                                             }

                               if(high_cnt>24)//说明接受完毕

                                         {

                                                   lead_flg = 0;

                                                   high_cnt = 0;

                                                   REM_FLG = 1;//采集完毕 清除标志位

     

                                                   TIM_Cmd( TIM4,DISABLE);

                                         }

                              

     

                       }

     

              }

              else if(RDATA()!=0)//说明是第一次接收引导码的高电平

              {

           if(lead_flg==0)

           {

           return 0;

           }

           else    if(lead_flg==1)//我们只接受一次低电平即可   2

                {

                                ir_cnt= TIM_GetCounter(TIM4);

                                TIM_SetCounter(TIM4,0);

                                         lead_flg=2;

                                if((ir_cnt<70)||(ir_cnt>90))

                                {

                                  lead_flg=0;//不是我们要的 退出

                  return 0;

                   

                                }

     

                       }

                       else if(lead_flg==3)//非引导码进入中断   上升沿触发的

                       {  

                           ir_cnt= TIM_GetCounter(TIM4);

                                TIM_SetCounter(TIM4,0);

                                        

                                if((ir_cnt<8)||(ir_cnt>20))//测试数据为 ir_cnt =9 10 稳定值

                                {

                                  lead_flg=0;

                  return 0;//不是我们要的  退出

                   

                                }

                               

     

                       }

              }

     

             }

      您阅读这篇文章共花了:  
    二维码加载中...
    本文作者:小v      文章标题: 单片机红外遥控器解码例程源码新说
    本文地址:http://blog.cvosrobot.com/?post=150
    版权声明:若无注明,本文皆为“机器人车技术开发分享网”原创,转载请保留文章出处。

    还有这篇 http://www.xiaovdiy.cn/?post=138
    @小v:http://www.xiaovdiy.cn/admin/write_log.php?action=edit&gid=160
    关于stm32的相关文章http://www.xiaovdiy.cn/?post=145
    返回顶部| 首页| 手气不错| 捐赠支持| 自定义链接| 自定义链接| 自定义链接| 手机版本|后花园

    Copyright © 2014-2017 机器人车技术开发分享网   京ICP备14059411 Copyright 2014-2019 小v工作室 版权所有 All Rights Reserved

    sitemap