找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1079|回复: 1
收起左侧

51单片机NEC解码头文件irnec.h源程序

[复制链接]
ID:1012522 发表于 2022-3-23 16:11 | 显示全部楼层 |阅读模式
  1. //*********************【 NEC解码头文件 】*******************
  2. //
  3. //     简介:本程序适用于NCE解码:(9ms+4.5ms)引导码+32位编码。
  4. //           兼容STC所有型号(包括 1T 和 12T 系列),可以定义任意I/O作红外接收脚,
  5. //                         自适应解码主频:6MHz ~ 40MHz。
  6. //
  7. // 使用条件:占用系统定时器0,开启定时器0中断(如使用其它定时器请自改IR_Init();初始化函数)
  8. //
  9. // 使用说明:填相关宏定义:USER_H、USER_L、Check_EN、CPU_Fosc、IR,
  10. //           上电初始化函数IR_Init(),
  11. //           在定时器0中断中调用IR_NEC()解码函数,
  12. //           解码有效时,IR_BT=2即短按,IR_BT=3即长按,由用户清0,
  13. //           解码存放:用户码高8位NEC[0],用户码低8位NEC[1],操作码NEC[2],操作码反码NEC[3]。
  14. //
  15. //【供用户调用的函数】
  16. //    IR_Init();                         //接收初始化,开启定时器0中断400us
  17. //    IR_NEC();                             //红外线解码(解NEC编码)
  18. //         
  19. //***************************************************************/

  20. #define  USER_H     0x01         //用户码高8位
  21. #define  USER_L     0xFB         //用户码低8位
  22. #define  Check_EN   0            //是否要校验16位用户码:不校验填0,校验则填1      
  23. #define  CPU_Fosc   12000000L    //输入主频,自适应解码(单位:Hz,范围:6MHz ~ 40MHz)
  24. #define  CA_S       8            //长按时间设置,单位:108mS(即 108mS整数倍,10倍以上为宜)

  25. sbit IR = P3^2;                  //红外线接口(任意引脚)

  26. #define  Step       400          //红外采样步长:400us
  27. #define  TH_H      ((65536-Step*(CPU_Fosc/300)/40000)/256)  //定时器高8位基准赋值
  28. #define  TH_L      ((65536-Step*(CPU_Fosc/300)/40000)%256)  //定时器低8位基准赋值

  29. unsigned char IR_BT;     //解码效果返回:0无效,1有效,2短按,3长按
  30. unsigned char NEC[4];    //解码存放:16位用户码、操作码正反码
  31. unsigned char cntCA;     //长按计数
  32. unsigned int  cntStep;   //步数计
  33. bit                          IRa,IRb;   //接收脚电位状态保存
  34. bit                          IRsync;    //同步标志
  35. unsigned char BitN;      //位码装载数

  36. /*┈┈┈┈┈┈┈┈┈┈ 基准 ┈┈┈┈┈┈┈┈┈┈┈*/
  37. #define    Boot_Limit    ((9000+4500 +1000)/Step)   //引导码周期上限   
  38. #define    Boot_Lower    ((9000+4500 -1000)/Step)   //引导码周期下限   
  39. #define    Bit1_Limit    ((2250 +800)/Step)         //“1”周期上限
  40. #define    Bit0_Limit    ((1125 +400)/Step)         //“0”周期上限
  41. /*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  42. 函数:红外线NEC周期采样解码法(定时中断,下降沿查询周期时间)
  43. 全局变量:IR_BT = 0无效
  44.                   1有效,待继续判断长、短按(如不需要判断长、短按,则直接使用)
  45.                   2短按
  46.                   3长按
  47. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
  48. void IR_NEC()
  49. {         
  50.    TL0 = TH_L;   //重赋值
  51.    TH0 = TH_H;      

  52.    cntStep++;    //步数累加
  53.    if(IR_BT==1)if(cntStep>300)IR_BT=2; //解码有效后,如果无长按,120ms(400us×300)后默认短按

  54.    IRb = IRa;    //保存上次电位状态
  55.    IRa = IR;     //保存当前电位状态
  56.       
  57.    if(IRb && !IRa)    //是否下降沿(上次高,当前低)
  58.    {
  59.       if(cntStep > Boot_Limit)   //超过同步时间?
  60.       {      
  61.           if(IR_BT==1)if(++cntCA>CA_S)IR_BT=3; //解码有效后,继续按住遥控>CA_S即长按
  62.           IRsync=0;                            //同步位清0
  63.       }
  64.       else if(cntStep > Boot_Lower){ IRsync=1; BitN=32; }   //同步位置1,装载位码数32                          
  65.       else if(IRsync)            //如果已同步
  66.       {
  67.          if(cntStep > Bit1_Limit)IRsync=0;                  
  68.          else
  69.          {      
  70.             NEC[3] >>= 1;                              
  71.             if(cntStep > Bit0_Limit)NEC[3] |= 0x80;    //“0”与“1”
  72.             if(--BitN == 0)                              
  73.             {
  74.                IRsync = 0;    //同步位清0

  75.                #if (Check_EN == 1)                                       
  76.                if((NEC[0]==USER_H)&&(NEC[1]==USER_L)&&(NEC[2]==~NEC[3]))    //校验16位用户码、操作码正反码
  77.                {  IR_BT=1; cntCA=0;  }     //解码有效,接下来判断:短按?长按?
  78.                #else
  79.                if(NEC[2]==~NEC[3]){ IR_BT=1; cntCA=0; }  //只校验操作码正反码
  80.                #endif                                       
  81.             }
  82.             else if((BitN & 0x07)== 0)    //NEC[3]每装满8位,移动保存一次(即 BitN%8 == 0)
  83.             {   NEC[0]=NEC[1]; NEC[1]=NEC[2]; NEC[2]=NEC[3];   }
  84.          }
  85.       }
  86.       cntStep = 0;   //步数计清0
  87.    }
  88. }
复制代码

头文件使用方法详见:http://www.51hei.com/bbs/dpj-218217-1.html
回复

使用道具 举报

ID:624476 发表于 2022-3-25 14:02 | 显示全部楼层
楼主你这代码中没有判断长按松开。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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