目录

  • 一、红外遥控概述
  • 二、红外编码规则
  • 三、硬件实现
  • 四、软件部分
    • 1、软件实现原理
    • 2、红外解码程序说明
    • 3、高低位逆转算法说明
    • 4、key_switch遥控按键指令识别函数说明
  • 五、总结

一、红外遥控概述

红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机和手机系统中。
我们的MS1824/MS1825/MS1851等产品普遍默认都是使用物理按键控制相关功能,现用MS8006开发红外遥控功能替代物理按键,由于目前红外普遍采用采用NEC编码即载波为38Khz的PWM(脉冲宽度调制)的方式实现遥控发送接收的。所以MS8006的红外按键代码也是按照PWM方式进行解码的。

二、红外编码规则

编码规则分为五个部分,按编码顺序分别是引导码、用户码、数据码、数据反码、重复简码构成,本程序中引导码为4.5ms或9ms低电平+4.5ms高电平,引导码之后就是16位用户码,用户码和数据码以及数据反码的格式是一致的,即0.57ms低电平+0.56ms高电平代表数据“0”位,0.57ms低电平+1.67ms高电平代表数据“1”位,重复简码即是当某个按键持续按下时只有第一组是全码,后面就是简码代替了,根据实际需要本程序中没有设计检测重复简码的部分,所以在红外发射端有无重复码都不会影响接收端对全码的识别。
下图为编码波形实例

例如遥控器数据的编码如下:
发射端用户码为(由左至右):00110101 01001101
数据码1:10000000 对应反码:01111111
数据码2:01000000 对应反码:10111111
数据码3:11000000 对应反码:00111111
数据码4:00100000 对应反码:11011111
数据码5:10100000 对应反码:01011111
数据码6:01100000 对应反码:10011111
数据码7:01010000 对应反码:10100000
提示:上述示例编码是从引导码后从左边至右边按照顺序写入0或1,而0和1的编码规则在前面已经详细描述。

三、硬件实现

由于只对原有电路加上一个红外接收管(1838B)即可,所以并没有硬件和原理图的改变,只需另外引出一个中断引脚接至接收管即可,这里用MS8006的GPIO D4做为红外接收线脚,并在软件中设置为外部中断输入。

四、软件部分

1、软件实现原理

利用现在普遍采用的红外接收头1838B作为红外信号采集并将其OUT引脚接至MS8006的中断引脚,因为一旦有正确信号进来需要立即执行,否则会错过引导码或其他问题导致遥控不灵敏等现象,MS8006所有GPIO引脚均可设置为外部中断源,外部中断设置为下降沿触发,然后启动计时器计时本次下降沿到下一下降沿触发的时间再结合编码规则部分的说明完成对遥控发射端的信号解码,定时器用MS8006的TIM10 basetime通用定时器。

2、红外解码程序说明

特别注意:以下程序中IR_data容易混乱,有一种方法可以更好的理解它,它是实际的定时器计时时间,是真实存在的一个可变的变量,程序中很多判断它的时间大于或小于某个数值,把这个数值只是看作一个数值并且和IR_data变量无关的确定后不可变的固定的数值即可,比如高电平时间是2.24ms,那么可以判断IR_data大于2ms即可认为是高电平,因为IR_data此时真正数值是2.24,是大于2的,所以可以判断为真。判断低电平时由于低电平时间比高电平短的,所以在1.14ms左右就重新进入中断了,是等不到2ms的,所以可以只要是小于2.4ms就先默认此位是低电平,当能检测到大于2ms时才判为高电平,大于的数值可根据需要选择,但一定要选大于1.14小于2.24的值,这里选得是2,为了兼容和减少误码率,前后都预留了点时间

VOID GPIOD_IRQHandler(VOID)    //红外接收头OUT脚接在port D4并//将此引脚设置为外部中断,ms8006 GPIOD中断号为3
{                         static UINT8 Flag_end=0;static UINT8 IR_num = 0;     UINT8 i;                            //变量定义HAL_GPIO_EXTI_IRQHandler(IR_PORT,IR_PIN);  //清除外部中断标志   TIM10->CR |= BASETIM_CR_INTEN;TIM10->CR |= BASETIM_CR_TR;NVIC_EnableIRQ(TIM10_IRQn);       //使能定时器10,开始计时__disable_irq();                   //关闭总中断if(IR_time <= 4)               //滤除前端杂波,定时器定时50us,所{                               //以滤除50x4=200us的杂波IR_data=0;IR_num=0;IR_time=0;}  if(IR_time > 170 && IR_time < 300) //引导码的识别,引导码的低电//平时间+高电平时间,为了更好的兼容性所以设置大于50x170=8.5ms小//于15ms,通常引导码有两种,一种是4.5ms低电平+4.5ms高电平,另一种//是4.5ms低电平+9ms高电平,此种算法可兼容两种方式{Flag_ir_start = 1;    //此时引导码正确,所以开始解码数据的标志位置1IR_num = 0;       //用于计数,一般引导码后会有32个二进制数//值组成用户码和数据码以及数据反码,此变量用于统计读取数据的个数IR_data=0;     //此变量用于存放读取到的数据,变量类型为非符32位}else if(IR_time >= 410)   //当引导码大于20.5ms时则判断失败,不再//读取数据,还有一点好处是这句话可以取消对重复简码的识别,提高兼容性{Flag_ir_start = 0;    // 引导码读取失败,则不读取数据,标志位置0IR_num = 0;IR_data=0;}    if((Flag_ir_start==1)&&(IR_time<=48))  /*标志位置1且两下降沿间隔小于2.4ms时说明数据正确,根据编码规则只要大于或等于2.24ms即可, 此举为了提高兼容性和减少误码率(由于环境影响,实际可能在2.24ms上下波动)*/{IR_data<<=1;         //将上次的数据先左移一位,低位再默认置0if(IR_time>=40)      //这里是大于2ms时就判断为高电平,因为按//照规则低电平应该为1.14ms左右就进入下一个下降沿了所以是达不到//2ms的,即能达到2ms的都是高电平了,而且实际上高电平时间为//2.24ms肯定大于2ms的{       IR_data |= (0x01<<0);//如果是高电平就将默认置0的低位再置1}IR_num++;             //共有32个位,这里自加计数if(IR_num > 31)       //当IR_num大于31时,其实此时就是32了,//就结束一组遥控码的读取并开始解码{Flag_end = 1;    //结束标志,防止每次进中断时都能进入//解码函数,必须读取完一组遥控码之后才能解码Flag_ir_start=0;     //此时开始读取标志置0,即当有新的引//导码时才会读取新的一组遥控码IR_time = 0;        //计时变量清0}} if(Flag_end)                //结束读码进入解码算法{TIM10->CR &= 0xDF;TIM10->CR &= 0x7F;NVIC_DisableIRQ(TIM10_IRQn);     //先将定时器关掉,直至下次//读码时再次定时器打开重新计//时,避免不用定时器还在计时//容易造成计时混乱等错误Inf_Rec_Buffer[0] = (UINT8)((IR_data>>0)&0xff);Inf_Rec_Buffer[1] = (UINT8)((IR_data>>8)&0xff);Inf_Rec_Buffer[2] = (UINT8)((IR_data>>16)&0xff);Inf_Rec_Buffer[3] = (UINT8)((IR_data>>24)&0xff);//以上四句是将读取到的32位数据分成4组8位数据//分别存放在四个数组中便于对数据的识别和后面的使用for(i=0;i<4;i++)Inf_Rec_Buffer[i] = (UINT8)(~(reverse8(Inf_Rec_Buffer[i])));//根据需要分别将4组数据的高低位全部颠倒然后再取反
#if 1LOG1("Buffer[0]=",Inf_Rec_Buffer[0]);LOG1("Buffer[1]=",Inf_Rec_Buffer[1]);LOG1("Buffer[2]=",Inf_Rec_Buffer[2]);LOG1("Buffer[3]=",Inf_Rec_Buffer[3]);
#endif                 //这里是用串口打印出解码成功后的数值,因为后面//使用的就是此时对应的数值if(Inf_Rec_Buffer[0] == (UINT8)(~Inf_Rec_Buffer[1]))                      //如果数据码和数据反码取反后的数值是相等说明读//码和解码是正确的,可进行赋值等使用{g_u8_Inf_Rec = Inf_Rec_Buffer[0];    //用低8位即图一中//的数据反码作为遥控控制指令key_switch(); //后面会介绍此函数,数据反码作为指令控制相应功能}Flag_end = 0;       //将结束读码的标志置0,以便于读取下一组遥控码IR_data=0;        //此时本组遥控数据已经读完,置0继续存放下一组IR_num=0;          //计数变量也置0,为读取下一组做准备}__enable_irq();            //两次下降沿之间的数据分析完成,将中断//再打开准备下一个下降沿IR_time = 0;   //将时间变量清0,也是为下一个两个下降沿之间的时间计时做准备
}

3、高低位逆转算法说明

短短几句话,算法也比较简单,可自行理解,原理大概就是先将8位数据分成2个4位同时调换中间两位,然后两边两位,最后将高4位和低4位反过来即可完成颠倒,比如c = 0B01011101(0X5D),那么return出来就是0B10111010(0XBA)
UINT8 reverse8( UINT8 c )
{
c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
return c;
}

4、key_switch遥控按键指令识别函数说明

这个函数主要是将解码后的遥控数据用于实际中,可以当成按键来使用,按键是识别按键对应pin脚的值,这里只不过是以8位的数据来作为识别的而已,由于需求不一样,下面只列举两个按键值作为说明,特别注意的是用的是留个按键,当某个值对应一个PIN_KEYn会被置为0给当作按键的识别,其实就是在模拟机械按键,但此时应将其他的PIN值置1,因为这里不能像真的机械按键那样会弹起自动置1,需要软件手动设置的,还有最后有一个对0xff的判断,这个是当没有遥控器按下的时候读取到的遥控码全是0经过上文的反码后为0xff,这时的所有PIN_KEYn均为1,模拟没有机械按键按下的状态

VOID key_switch(VOID)
{UINT8 g_u8_Inf_status = 0;if(g_u8_Inf_Rec != g_u8_Inf_status)
{g_u8_Inf_status = g_u8_Inf_Rec;switch(g_u8_Inf_status){case 0x01:PIN_KEY1 = 0;PIN_KEY2 = 1;PIN_KEY3 = 1;PIN_KEY4 = 1;PIN_KEY5 = 1;PIN_KEY6 = 1;break;case 0x02:PIN_KEY2 = 0;PIN_KEY1 = 1;PIN_KEY3 = 1;PIN_KEY4 = 1;PIN_KEY5 = 1;PIN_KEY6 = 1;break;case 0xff:PIN_KEY1 = 1;PIN_KEY2 = 1;PIN_KEY3 = 1;PIN_KEY4 = 1;PIN_KEY5 = 1;PIN_KEY6 = 1;break;default:break;}}
}

关于物理按键长按和短按的说明可参考我另一篇文章单片机按键长按短按检测MS8006示例代码说明

五、总结

现在越来越多的手机设备也可以作为红外发射器,而且能够匹配更多的家用电器等支持红外遥控的设备,无线遥控用途很广泛。
关于MS8006信息请找孙工13866788906

MS8006单片机开发IR红外遥控解码原理与程序实现(NEC)相关推荐

  1. 红外遥控解码原理及代码实现

    本篇介绍红外解码的原理和程序的写法. 下面来看一下,红外线是如何编码的.![这里写图片描述](https://img-blog.csdn.net/20150926130659823) 下面来具体说一下 ...

  2. 万能遥控程序c语言,51单片机万能红外遥控解码程序

    51hei单片机论坛里流传的遥控解码程序现在都弱爆了根本解不了现在的遥控自己写个万能红外遥控解码 本程序中需要用的头文件下载:http://www.51hei.com/mcu/2564.html // ...

  3. 基于51单片机+红外遥控解码+LCD1602显示

    红外遥控解码(NEC) 基本介绍 什么是红外线? 红外线系统的组成 发射管和接收管 红外遥控发射(载波频率) 重要介绍 NEC协议 数据格式(必看) 位定义(必看) 编写程序思路(2种) 方式一 方式 ...

  4. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

  5. 学习型红外遥控器设计(3) 红外遥控解码学习

    学习型红外遥控器设计(0) 摘要   (1) 绪论  (2) 方案设计   (3) 遥控解码   (4) 编码还原  (5) 硬件实现   (6) 总结展望 如方案设计所述,制作红外接收解码装置,该装 ...

  6. 51单片机tea5767收音机 红外遥控 自动搜台 存台 DIY

    转自:https://www.cnblogs.com/ningci/p/5464679.html 日向宁次 博客园 首页 新闻 新随笔 联系 管理 订阅 随笔- 55  文章- 0  评论- 1  5 ...

  7. HT6221红外遥控解码设计

    项目名称 HT6221红外遥控解码设计 具体要求 接收红外按键的数据在ISSP上观察 设计说明 下图为红外遥控器及按键图.红外接收头有三个引脚,电源.地和信号输出. HT6221芯片的红外遥控发送数据 ...

  8. 基于51单片机 的红外遥控解码设计

    红外线遥控在生活中有着广泛的应用,比如空调,电视,音响,机顶盒等.红外线遥控实际上就是一种通信方法,利用LED发射红外线,接收器接收到数据,进行处理后就可以得到发送端的信号.利用一个简单的红外线发光二 ...

  9. 单片机接收到红外对管的数据怎么用c语言程序传给led显示器,单片机实现遥控器-红外数据传输--红外编解码原理...

    一. 红外通信原理 红外遥控有发送和接收两个组成部分.发送端采用单片机将待发送的二进制信号编码调制为一系列的脉冲串信号,通过红外发射管发射红外信号.红外接收完成对红外信号的接收.放大.检波.整形,并解 ...

最新文章

  1. 不需要任何依赖的图片加载错误处理的工具类load-image.js
  2. webStorm Linux Ubuntu 中文搜狗输入问题
  3. 隐藏与显现_原神:芭芭拉的隐藏彩蛋你知道吗?对着游戏npc用技能就可显现
  4. ta-lib依赖安装问题
  5. C++ Primer Plus 读书笔记(第8、9章)
  6. 互联网巨头的“搜索”暗战
  7. testng 监听器_TestNG侦听器
  8. MOX:开创区块链通证参与电影融资的新篇章
  9. hibernate之HQL属性查询
  10. Bugzilla 的安装
  11. iphone5刷机教程
  12. Pixi官方文档译文(2)
  13. edge microsoff 连不上网_网站还原错误怎么办
  14. html一行字不同颜色6,html语言的字体设置
  15. 报错 undefined symbol: _ZN6caffe26detail36_typeMetaDataInstance_preallocated_7E
  16. 共享滑板背后:谷歌、Uber、软银暗斗大出行
  17. 鼠标悬浮旋转三角图标
  18. 光影软件测试自学,使用set a light 3D STUDIO来学习如何布光②
  19. Trip.com W1D5
  20. 汽车驾驶 直角转弯训练 技巧

热门文章

  1. 进度条上的小圆点怎么做_4个方面轻松搞定进度条
  2. 国内外编译原理课程实践教学现状分析
  3. python程序设计基础知识
  4. 华工计算机研究生课程表,11级华工研究生课程表.doc
  5. ANSYS Maxwell导出图片的方法
  6. 新建网站提升曝光率设置集合(边使用边更新)(包括:SEO优化,Robots设置,CDN加速,防盗链)
  7. 建模--知名软件介绍
  8. 怎样将文档生成链接或二维码
  9. librtmp windows编译
  10. 二极管在电路设计中的应用