高效NEC遥控解码,任意IO(精简10行C语言)

2020-01-13 18:28发布

以前刚学MCU时做过红外遥控解码,参考别人的程序写了老半天,总共几十行,用外部中断方式,而且还很不好使。
后来在做一个遥控控制RGB灯变 {MOD}时,发现用外部中断方式解码在按键时RGB灯老闪(中断处理解码去了,PWM波程序被打断了,PWM用软件模拟的),
这时想可不可以不用中断来做呢,就在网上搜了搜,发现一个,就在这个基础上做了大量优化,最后的解码程序只有10行左右,且灵敏度也很好,给大家分享一下。

悄悄告诉你:这个代码相当好用!各种MCU移植都很方便
上源码:(只是核心部分)

sbit IR_IO = P1^6;          // IR管脚 任意IO

//定时器初始化为125uS中断一次
void IR_decode_init(void)
{
   TMOD |= 0x12;                     // T1定时方式2
//--------------设定中断时间------------------------
   TH0 = (-125);  TL0 = (-125); // 定时125us 12M晶振
    ET0 = 1;        TR0 = 1;        // 启动T1
    EA = 1;                              // 总中断允许
}
//解码的相关数据              
bit Irprot_LastState = 0;   // 端口状态位
uchar codeCnt = 0;          // 数据码位计数
uchar irTime;                   // 码时间,用于以125us时间计时
uchar IR_data[4];            // 接收数据缓存

//下面为解码的关键部分,大家自己去分析。主思路就是计算下降沿间隔,其余什么高电平多少时间,低电平多少时间都不关心,因此代码比较精简。
//125us执行中断程序一次
void Timer0(void) interrupt 1                                                            
{   
   irTime++;
   if(irTime==240) {irTime--;  codeCnt=0x3f;} // ir解码后码值存放时间, 240*125us = 30ms
   if(IR_IO)   Irprot_LastState=1; // 记录IO状态
   else if(Irprot_LastState)       // 有下降沿
   {
      Irprot_LastState = 0;        // 下降沿后IO状态记录为0
      if(irTime<24)                // 小于24*125us=3ms的间隔才进行处理
      {
         codeCnt++;  codeCnt &= 0x1f;
         IR_data[codeCnt>>3] <<= 1;
         if( irTime>15 )   IR_data[codeCnt>>3]++;  // 大于15*125us=1.875ms的间隔为数据1
      }
      irTime = 0;                  // 下降沿处理完成,将时间清0
   }
}

使用时只需查询codeCnt的值是否等于31(如果解码完成30ms后才去判断codeCnt==31,codeCnt将不会再是31,可以在程序中修改该标志的存活时间),是表示解码完成,解码数据放于IR_data[]数组中; 因为该解码的核心思想是检测两个下降沿相隔的时间,所以只要两个下降沿间隔符合,不管高低电平时间都会进行解码,所以如果要提高准确性,需把IR_data[]中的数据进行检验,
也就是看是否IR_data[2]==IR_data[3],如果是,99%是正确的.




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
98条回答
hamipeter
1楼-- · 2020-01-21 05:45
收藏先,留着备用.
lryxr2507
2楼-- · 2020-01-21 09:41
支持,支持,学习,学习!!!
dyzhenhuai
3楼-- · 2020-01-21 14:36
不错,学习学习
catywu
4楼-- · 2020-01-21 19:08
收藏先,学习中
ka1265
5楼-- · 2020-01-21 23:48
 精彩回答 2  元偷偷看……
cyq001
6楼-- · 2020-01-22 04:58
我来泼几瓢冷水,不过在泼水之前还是夸奖楼主几句:很认真!做得很精简!

但正是因为你做得很精简,所以……反而是有问题的。
这个问题的根本原因就在于……你将实际情况想象得太理想了。
你说灵敏度在99%以上,你跑到一个到处都是日光灯的环境试试?

1、对于红外遥控器来说,其实灵敏度和误码率,是一对矛盾的。
从你自己的描述和程序来看,你其实是牺牲了误码率的,也就是说,很可能外界的干扰(其它发红外线的东西或者类似的遥控器)会误操作你的接收设备的。在我看来,灵敏度很重要,其实误码率更重要。
2、这个程序,只适合移植到小项目中,如果项目稍微大一点,你分给遥控器的时间片还是太多了,系统开销会不够的。

一周热门 更多>