找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4174|回复: 11
打印 上一主题 下一主题
收起左侧

也谈51单片机红外通信(附有四种红外解码源码)

  [复制链接]
跳转到指定楼层
楼主
本帖最后由 wzqwxx 于 2021-10-8 11:48 编辑

       今天谈的是NEC 协议的。关于此协议请上百度。
       放假在家集中学习了51单片机,“苦读”了一些书箱和视频教程。谈不上谈论什么,其实就向大家汇报这段时间的学习情况,欢迎交流,提出宝贵意见。
      本人是第一次在贵坛发贴,定有很多不到的地方,也请大家批评指正。
      今天就NEC 协议,仿照教材编写了三种红外解码方案,并都在开发板调试通过,完整源码会在附件提供。
      第一种方案是参照教程的源码(在此称第四方案)改写的,解码部分代码比第四方案精减了,而且不失第四方案性能,只用了几行代码,占用内存也少。而第四方案正好相反。这两种方案都是利用中断,对前后信号两个下降沿之间时间长短、判定二进制数据0/1位的。优点:利用了两个中断,分别是定时器0和外部中断0,程序执行很快,占用CPU时间很少。缺点:占用了两个中断,能正确解码NEC协议的遥控器信号,也能解码别的协议遥控器的信号,当然是乱码。
      第二种方案,与第四种方案解码方式不同,只利用一个外部中断0,对信号高低电平分别测量延续时长,来判定二进制数据0/1位的。优点:代码少,占用内存少,只利用了一个外部中断。能正确解码NEC协议的遥控器信号,禁止解码别的协议遥控器的信号,不会出现乱码。缺点:占用CPU时间多,整个解码期间不能产生别的中断。
      第三种方案,综合了一二两种方案,扬长避短,优势互补,自认为是很好的方案。相对第四方案,优点:代码少,占用内存少,程序执行较快,占用CPU时间较少,只利用了一个外部中断0,能正确解码NEC协议的遥控器信号,禁止解码别的协议遥控器的信号。缺点:解码头部要延时9+4.5=13.5ms时间,有点长,CPU不能做其它任务。
      下面将前三种方案核心代码贴出,欢迎大家评论交流,并指出错误和不足   。
/*-----------------------------------------------
* 【实验平台】: QX-单片机开发板
* 【外部晶振】: 11.0592mhz        
* 【主控芯片】: STC89C52
* 【编译环境】: Keil μVisio4         

  名称:遥控器红外解码数码管显示
  使用:按遥控器会在数码管上对应显示十六进制键值

                NEC 协议下的编码表示
                其中:引导码高电平约9000us 左右,低电平约4500us 左右;
                接收端:引导码低电平约9000us 左右,高电平约4500us 左右;
                用户码16 位,数据码16 位,共32位;
        发送端:        数据0 是用“高电平约560us +低电平约560us”表示。
                数据1 可用“高电平约560us+低电平约1680us”表示

        接收端反转:数据0 是用“低电平约560us +高电平约560us”表示。
                   数据1 可用“低电平约560us+高电平约1680us”表示


------------------------------------------------*/





单片机源程序如下:

  1. #include<reg52.h>            //包含头文件,头文件包含特殊功能寄存器的定义

  2. sbit IR=P3^2;                          //红外接口
  3. sbit beep = P2^3;//蜂鸣器接口
  4. #define DataPort P0         //定义数据端口 程序中遇到DataPort 则用P0 替换
  5. sbit LATCH1=P2^6;                //定义锁存使能端口 段锁存
  6. sbit LATCH2=P2^7;                //                 位锁存

  7. unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
  8.                         0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  9.                                                 //0-F的码表
  10. unsigned char  irtime;        //红外用全局变量   计数延时,识别比特位电平高低

  11. unsigned char IRcord[4];//存储键码

  12. void delay(unsigned int i)
  13. {
  14.         unsigned int m,n;
  15.         for(m=i;m>0;m--)
  16.                 for(n=114;n>0;n--);
  17. }

  18. void tim0_isr (void) interrupt 1 using 1  //STC89C52 11.0592M
  19. {
  20.   irtime++;  //用于计数2个下降沿之间的时间         每个溢出中断时长256*1.085us=277.7us
  21. }

  22. void EX0_ISR (void) interrupt 0 //外部中断0服务函数
  23. {
  24.         static unsigned char  i;             //接收红外信号处理
  25.           if( irtime <3 || irtime >54) goto end; //两个下降沿延时过短(少于833us)或过长不解码 滤除干扰波

  26.         if(irtime > 45 && irtime < 54)//跳过引导码 头码,9ms+4.5ms
  27.          {  
  28.                 irtime=0;
  29.                 i=0;
  30.         }                    
  31.         else{
  32.                         IRcord[i/8] >>= 1;          //i/8每处理8位换下一个元素,总的处理4个字节共32位的数据
  33.                          if(irtime > 6) IRcord[i/8] |= 0x80;           //位0电平时长计数上限4,位1高电平计数上限8
  34.                     irtime = 0;                                                           //这里取6为0/1 的识别分界
  35.                     i++;
  36.                         if(i > 31){ i=0;  beep = 0;        delay(100); beep = 1; }
  37.                 }                                                 //beep 鸣叫一声        解码成功
  38.         end: irtime=0;                                                                           
  39. }


  40. void TIM0init(void)//定时器0初始化
  41. {
  42.         TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  43.         TH0=0x00; //重载值
  44.         TL0=0x00; //初始化值
  45.         ET0=1;    //开中断
  46.         TR0=1;   
  47. }
  48. void EX0init(void)
  49. {
  50. IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  51. EX0 = 1;   //使能外部中断
  52. EA = 1;    //开总中断
  53. }
  54. void SMG_show(unsigned char num) //两位数码管显示十六进制键码
  55. {
  56.         P0=dofly_DuanMa[num/16];           
  57.         LATCH1=1;
  58.         LATCH1=0;

  59.         P0=0xdf;           //选中第一个数码管
  60.         LATCH2=1;
  61.         LATCH2=0;
  62.         delay(2);

  63.         P0=dofly_DuanMa[num%16];           
  64.         LATCH1=1;
  65.         LATCH1=0;

  66.         P0=0xbf;           //选中第二个数码管
  67.         LATCH2=1;
  68.         LATCH2=0;
  69.         delay(2);
  70. }
  71. void main(void)
  72. {
  73.         EX0init(); //初始化外部中断
  74.         TIM0init();//初始化定时器

  75.         while(1)//主循环
  76.         {
  77.                 SMG_show(IRcord[2]);//两位数码管显示十六进制键码
  78.         }
  79. }
  80.   
  81.   
复制代码
例程副本.rar (12.69 KB, 下载次数: 58)

遥控器红外解码数码管显示——第一方案.jpg (200.56 KB, 下载次数: 123)

遥控器红外解码数码管显示——第一方案.jpg

评分

参与人数 1黑币 +100 收起 理由
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏20 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:965487 发表于 2021-10-6 20:36 | 只看该作者
本帖最后由 wzqwxx 于 2021-10-6 20:40 编辑







例程副本.rar (12.69 KB, 下载次数: 36)

红外解码数码管显示 -第3方案.rar (350.1 KB, 下载次数: 60)

红外解码数码管显示 -第二方案.rar (359.96 KB, 下载次数: 54)

红外解码数码管显示——第1方案.rar (257.96 KB, 下载次数: 60)




回复

使用道具 举报

板凳
ID:262 发表于 2021-10-7 03:27 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

地板
ID:695749 发表于 2021-10-7 08:02 | 只看该作者
这种学习方式最实用,好资料,学习学习。
回复

使用道具 举报

5#
ID:965487 发表于 2021-10-7 11:19 | 只看该作者
谢谢版主给于100黑币奖励,感谢大家精神鼓励。

第一次在贵论坛发帖,版面有点乱,图片尺寸大了。现在才知道发源代码有插件的。下次会改进。
回复

使用道具 举报

6#
ID:82491 发表于 2022-1-24 09:03 | 只看该作者
你好请问红外相关的教程有哪些方便分享一下吗?最近额想学习一下红外相关的。
回复

使用道具 举报

7#
ID:965189 发表于 2022-1-24 12:22 | 只看该作者
没详细看,有没有连续码的识别?
回复

使用道具 举报

8#
ID:71233 发表于 2022-1-25 12:38 | 只看该作者
精神可嘉,但遗憾的是附件需要多次下载。
回复

使用道具 举报

9#
ID:378617 发表于 2022-9-6 01:20 | 只看该作者

好用吗?????????????
回复

使用道具 举报

10#
ID:966606 发表于 2022-9-6 10:16 | 只看该作者
这种学习方式最实用,好资料,学习学习。
回复

使用道具 举报

11#
ID:137736 发表于 2022-9-7 10:24 | 只看该作者

很好的例程,谢谢
回复

使用道具 举报

12#
ID:325735 发表于 2023-3-7 17:23 | 只看该作者
能解码空调不
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表