首页 > 其他 > 详细

红外接收解码分析

时间:2020-08-16 13:28:37      阅读:82      评论:0      收藏:0      [点我收藏+]

典型红外接收波形引导码+用户码-用户码反码+指令码-指令码反码,在指令发送完成后,按键还未松开,会每隔100ms发送一个低脉冲和一个高脉冲。

技术分享图片

单片机实现红外检测的基本原理,简单的说就是记录高低电平时间,确实是引导码、0码、1码,接收32bit数据码即可。

实现:

1.定时器中断,固定时间检测接收脚位电平,得到数据。

2.外部中断的方式,加定时器记时方式。


//定时器0中断
//0.25ms进入一次
void Tim0Int() interrupt 1
{
     TR0 = 0;
    
     timStep ++;
     timCountMin ++;    //计数器计数
     timCountMax ++;
     timBzCount ++;
     tkDewaterCn ++;
     baseTimCn = 0;
    
     //检测到无下降沿多少秒,将下面那一段屏蔽掉
     if(redRev)
     {
         countHigh ++;            //state        countStep = 2;
         if(countHigh > 440)        //120ms清零
         {
            
             recCompltFlg = 0;
             sysUserCode = 0;
             sysCtrolCode = 0;
         }
         if(countHigh > 30)
         {
             pilotCodeFlg = 0;
             DataCount = 0;
         }
         revLowFlg = 0;
     }
     else
     {
         if(revLowFlg == 0)           
         {
             if(pilotCodeFlg == 0)        //检测引导码
             {
                 if(countLow >= 20)
                 {
                     if(countHigh >= 16)   
                     {
                         if(countLow <= 37)
                         {
                             if(countHigh <= 19)
                             {
                                 pilotCodeFlg = 1;        //确认为引导码
                             }
                         }
                     }
                 }
             }
             else        //检测数据码
             {
                 DataCount++;
                 if((countHigh <= 2)&&(countHigh >= 1)&&(countLow <= 3)&&(countLow >= 2))
                 {
                     //确认为零码
                     Databit = 0;
                 }
                 else    if((countHigh >= 5)&&(countLow >= 2)&&(countLow <= 3)&&(countHigh <= 7))
                 {
                     //确认为1码
                     Databit = 1;
                 }
                 else
                 {
                     //错误码
                     DataCount = 0;
                     pilotCodeFlg = 0;
                 }
                
                 if(DataCount != 0)
                 {
                     if(DataCount < 17)
                     {
                         if(Databit)        //默认先接LSB
                         {
                             userCode >>= 1;
                             userCode |= 0x8000;
                         }
                         else
                         {
                             userCode >>= 1;
                         }
                     }
                     else
                     {
                         if(Databit)        //默认先接LSB
                         {
                             ctrolCode >>= 1;
                             ctrolCode |= 0x8000;
                         }
                         else
                         {
                             ctrolCode >>= 1;
                         }
                        
                         if(DataCount == 32)
                         {
                             //确认接收数据结束
                             DataCount = 0;
                             pilotCodeFlg = 0;
                             //结束的处理,看看怎么弄
                             recCompltFlg = 1;                        //查询后清零
                             sysUserCode = userCode;
                             sysCtrolCode = ctrolCode;
                         }
                     }
                 }
             }
             //重置计数参数       
             countLow = 0;
             countHigh = 0;
             countLow ++;
             revLowFlg = 1;
         }
         else
         {
             countLow ++;             //state         countStep = 1;
         }
     }
     TL0 = 0x60;            //定时器0低5位初值
     TH0 = 0xf0;            //定时器0高8位初值
                                     //硬件自动清除中断标志
     TF0 = 0;
     TR0 = 1;
     //P17 ^= 1;
   

//红外解码    INT04下降沿唤醒
                 if(recCompltFlg)
                 {
                     if(sysUserCode == USERCODE)
                     {
                         switch(sysCtrolCode)
                         {
                             case WATERCODE         :    touchKeyVal = 0x02;   
                                                                     recCompltFlg = 0;
                                                                     sysUserCode = 0;
                                                                     sysCtrolCode = 0;
                                                                     break;
                             case LIGHTCODE         :    touchKeyVal = 0x06;   
                                                                     recCompltFlg = 0;
                                                                     sysUserCode = 0;
                                                                     sysCtrolCode = 0;
                                                                     break;
                             case SWCODE             :    touchKeyVal    = 0x01;
                                                                     recCompltFlg = 0;
                                                                     sysUserCode = 0;
                                                                     sysCtrolCode = 0;
                                                                     break;
                             case WINDCODE         : touchKeyVal = 0x04;
                                                                     recCompltFlg = 0;
                                                                     sysUserCode = 0;
                                                                     sysCtrolCode = 0;
                                                                     break;
                             case TIMMINGCODE     : touchKeyVal = 0x05;   
                                                                     recCompltFlg = 0;
                                                                     sysUserCode = 0;
                                                                     sysCtrolCode = 0;
                                                                     break;
                             case DEWATERCODE    :    touchKeyVal = 0X03;
                                                                     if(timFlgOn)
                                                                     {
                                                                         recCompltFlg = 0;
                                                                         sysUserCode = 0;
                                                                         sysCtrolCode = 0;
                                                                     }
                                                                     break;
                             default :                           
                                                                     recCompltFlg = 0;
                                                                     sysUserCode = 0;
                                                                     sysCtrolCode = 0;
                                                                         break;
                         }
                     }
    
                     //recCompltFlg = 0;
                     //sysUserCode = 0;
                     //sysCtrolCode = 0;
                 }   

提醒可以利用每100MS每次的高低脉冲实现按键长按的检测。

技术分享图片

项目合作、吹牛、扯淡、交朋友,请联系18665321219



红外接收解码分析

原文:https://www.cnblogs.com/logicexpression/p/13512165.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!