找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机红外解码程序+仿真文件(支持长/短按,自适应主频6MHz ~ 40MHz)

  [复制链接]
跳转到指定楼层
#
ID:51129 发表于 2013-6-21 00:08 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
//*********************【 NEC解码头文件 】*******************
//
//     简介:本程序适用于NCE解码:(9ms+4.5ms)引导码+32位编码。
//           兼容STC所有型号(包括 1T 和 12T 系列),可以定义任意I/O作红外接收脚,
//                         自适应解码主频:6MHz ~ 40MHz。
//
// 使用条件:占用系统定时器0,开启定时器0中断(如使用其它定时器请自改IR_Init();初始化函数)
//
// 使用说明:填相关宏定义:USER_H、USER_L、Check_EN、CPU_Fosc、IR,
//           上电初始化函数IR_Init(),
//           在定时器0中断中调用IR_NEC()解码函数,
//           解码有效时,IR_BT=2即短按,IR_BT=3即长按,由用户清0,
//           解码存放:用户码高8位NEC[0],用户码低8位NEC[1],操作码NEC[2],操作码反码NEC[3]。
//
//【供用户调用的函数】
//    IR_Init();                         //接收初始化,开启定时器0中断400us
//    IR_NEC();                             //红外线解码(解NEC编码)
//          
//***************************************************************/
#ifndef __IR_NEC_H__
#define __IR_NEC_H__


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

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

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

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


/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:红外线解码初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_Init()
{
   TMOD &= 0xF0;           //清定时器0
   TMOD |= 0x01;           //定时器0:16位定时器
   TL0 = TH_L;           //每步时间
   TH0 = TH_H;
   ET0 = 1;
   EA  = 1;
   TR0 = 1;
}

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

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

   IRb = IRa;    //保存上次电位状态
   IRa = IR;     //保存当前电位状态
       
   if(IRb && !IRa)    //是否下降沿(上次高,当前低)
   {
      if(cntStep > Boot_Limit)   //超过同步时间?
      {       
          if(IR_BT==1)if(++cntCA>CA_S)IR_BT=3; //解码有效后,继续按住遥控>CA_S即长按
          IRsync=0;                            //同步位清0
      }
      else if(cntStep > Boot_Lower){ IRsync=1; BitN=32; }   //同步位置1,装载位码数32                          
      else if(IRsync)            //如果已同步
      {
         if(cntStep > Bit1_Limit)IRsync=0;                   
         else
         {       
            NEC[3] >>= 1;                               
            if(cntStep > Bit0_Limit)NEC[3] |= 0x80;    //“0”与“1”
            if(--BitN == 0)                               
            {
               IRsync = 0;    //同步位清0

               #if (Check_EN == 1)                                       
               if((NEC[0]==USER_H)&&(NEC[1]==USER_L)&&(NEC[2]==~NEC[3]))    //校验16位用户码、操作码正反码
               {  IR_BT=1; cntCA=0;  }     //解码有效,接下来判断:短按?长按?
               #else
               if(NEC[2]==~NEC[3]){ IR_BT=1; cntCA=0; }  //只校验操作码正反码
               #endif                                       
            }
            else if((BitN & 0x07)== 0)    //NEC[3]每装满8位,移动保存一次(即 BitN%8 == 0)
            {   NEC[0]=NEC[1]; NEC[1]=NEC[2]; NEC[2]=NEC[3];   }
         }
      }
      cntStep = 0;   //步数计清0
   }
}

//取消相关宏定义
#undef CPU_Fosc

#endif





主程序
#include "INC\STC89C52RC.H"
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H"        //调用NEC解码头文件

sfr   SE   = 0x80;             //数码管段选 P0:0x80   P1:0x90
sbit  WX1  = P2^0;                 //数码管位显
sbit  WX2  = P2^1;
sbit  WX3  = P2^2;
sbit  WX4  = P2^3;
sbit  WX5  = P2^4;
sbit  WX6  = P2^5;
sbit  WX7  = P2^6;
sbit  WX8  = P2^7;

uint8c tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0xFF};
uint8  Xn,X1,X2,X3,X4,X5,X6;

void KZ0();      //短按处理
void KZ1();      //长按处理


/***************** 主函数 ********************/
void main(void)
{
   IR_Init();                           //红外线解码初始化
                                                  
   while(1)
   {
      //遥控检测
      if((IR_BT==2)||(IR_BT==3))                          
      {
         if(IR_BT==2)KZ0();      //短按处理                  
         else        KZ1();      //长按处理       
         IR_BT =0;               //清有效标志

         X1 = NEC[0]/16;              //更新显示
         X2 = NEC[0]%16;
         X3 = NEC[1]/16;
         X4 = NEC[1]%16;
         X5 = NEC[2]/16;
         X6 = NEC[2]%16;
      }
          
   }

}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:遥控短按处理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ0()
{
   switch(NEC[2])             
   {
          case 0x12: P10 = !P10; break;
          case 0x05: break;
          case 0x1E: break;
          case 0x55: break;

          case 0x01: break;
          case 0x1B: break;
          case 0x03: break;
          case 0x6B: break;

          case 0x07: break;
          case 0x08: break;
          case 0x09: break;
          case 0x68: break;

          case 0x22: break;
          case 0xE6: break;
          case 0x33: break;
          case 0xE2: break;
          default:break;
   }
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:遥控长按处理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ1()
{
   switch(NEC[2])             
   {
          case 0x12: P14 = !P14; break;
          case 0x05: break;
          case 0x1E: break;
          case 0x55: break;

          case 0x01: break;
          case 0x1B: break;
          case 0x03: break;
          case 0x6B: break;

          case 0x07: break;
          case 0x08: break;
          case 0x09: break;
          case 0x68: break;

          case 0x22: break;
          case 0xE6: break;
          case 0x33: break;
          case 0xE2: break;
          default:break;
   }
}
/*********************数码管扫描*************************/
void XS(void)
{
  if(++Xn > 7)Xn=0;
  switch(Xn)             
  {
            case 0: WX8=1;  NOP;           //屏蔽上个位显
                    SE=tab[X1];           //送段码
                    WX1=0;           //开位显
                    break;
            case 1: WX1=1; NOP; SE=tab[X2]; WX2=0; break;
            case 2: WX2=1; NOP; SE=tab[X3]; WX3=0; break;       
         case 3: WX3=1; NOP; SE=tab[X4]; WX4=0; break;
         case 4: WX4=1; NOP; SE=tab[16]; WX5=0; break;
         case 5: WX5=1; NOP; SE=tab[16]; WX6=0; break;
         case 6: WX6=1; NOP; SE=tab[X5]; WX7=0; break;
         case 7: WX7=1; NOP; SE=tab[X6]; WX8=0; break;                 
         default:break;                        
  }
}

/********************** 定时器0中断函数************************/
void time0(void) interrupt 1
{
   IR_NEC();
   XS();        
} 
接收源程序+仿真: NEC(任意接收引脚,支持长短按).rar.rar (111.09 KB, 下载次数: 265)
遥控器源程序: 遥控器源程序.rar (94.19 KB, 下载次数: 210)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏9 分享淘帖 顶1 踩
回复

使用道具 举报

43#
ID:47634 发表于 2017-2-5 22:14 | 只看该作者
很好很好,感谢感谢
回复

使用道具 举报

42#
ID:144738 发表于 2016-10-30 21:32 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

41#
ID:55584 发表于 2016-10-24 09:01 | 只看该作者
谢谢楼主分享。
回复

使用道具 举报

40#
ID:64178 发表于 2016-10-17 18:52 | 只看该作者
谢谢 LZ分享,下载了,正好要用
回复

使用道具 举报

39#
ID:130591 发表于 2016-9-26 15:51 | 只看该作者
没有黑币,下不了
回复

使用道具 举报

38#
ID:105562 发表于 2016-4-14 21:43 | 只看该作者
多谢分享
回复

使用道具 举报

37#
ID:99618 发表于 2015-12-20 01:53 来自手机 | 只看该作者
hao终于能下了
回复

使用道具 举报

36#
ID:47760 发表于 2015-3-18 14:56 | 只看该作者
谢谢分享
回复

使用道具 举报

35#
ID:73002 发表于 2015-3-11 13:12 | 只看该作者
可以学习下。
回复

使用道具 举报

34#
ID:61343 发表于 2015-2-26 10:25 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

33#
ID:48413 发表于 2015-2-23 22:34 | 只看该作者
谢谢你
回复

使用道具 举报

32#
ID:73002 发表于 2015-2-20 15:34 | 只看该作者
谢谢楼主分享。
回复

使用道具 举报

31#
ID:29438 发表于 2015-2-3 13:26 | 只看该作者
找了很久,谢谢!
回复

使用道具 举报

30#
ID:72947 发表于 2015-1-31 19:35 来自手机 | 只看该作者
谢谢楼主分享!!!
回复

使用道具 举报

29#
ID:70330 发表于 2015-1-4 15:36 | 只看该作者
谢谢分享,就是图看不清
回复

使用道具 举报

28#
ID:71142 发表于 2015-1-1 21:37 | 只看该作者
你好,图看不清,能发个清晰的吗?谢谢!
回复

使用道具 举报

27#
ID:71359 发表于 2014-12-30 13:53 | 只看该作者
谢谢楼主
回复

使用道具 举报

26#
ID:56814 发表于 2014-9-14 17:14 | 只看该作者
谢谢分享
回复

使用道具 举报

25#
ID:51348 发表于 2014-9-14 02:02 | 只看该作者
很好  学习  谢谢
回复

使用道具 举报

24#
ID:66000 发表于 2014-9-13 10:03 | 只看该作者
谢谢分享
回复

使用道具 举报

23#
ID:47760 发表于 2014-9-13 09:24 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

22#
ID:62288 发表于 2014-5-26 12:30 | 只看该作者
好东东,谢谢分享。
回复

使用道具 举报

21#
ID:58188 发表于 2014-1-17 13:08 | 只看该作者
下来看看
回复

使用道具 举报

20#
ID:57670 发表于 2014-1-10 21:31 | 只看该作者
下载学习!!!!!!!
回复

使用道具 举报

19#
ID:58653 发表于 2014-1-9 07:28 来自手机 | 只看该作者
这个一定要顶
回复

使用道具 举报

18#
ID:58552 发表于 2014-1-5 11:22 | 只看该作者
好东西,谢谢楼主,正做这个呢
回复

使用道具 举报

17#
ID:56665 发表于 2013-12-2 09:53 | 只看该作者
下载了,谢谢。
回复

使用道具 举报

16#
ID:56665 发表于 2013-12-2 09:48 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

15#
ID:52286 发表于 2013-10-13 23:03 | 只看该作者
不错过来看看
回复

使用道具 举报

14#
ID:47175 发表于 2013-10-11 09:20 | 只看该作者
东西不错
回复

使用道具 举报

13#
ID:47175 发表于 2013-10-11 09:19 | 只看该作者
感谢楼主分享
回复

使用道具 举报

12#
ID:55601 发表于 2013-10-3 16:05 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

11#
ID:55354 发表于 2013-9-23 23:56 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

10#
ID:21740 发表于 2013-9-15 00:11 | 只看该作者
请问这个程序怎样实现遥控按键不自锁状态。谢谢分享!
回复

使用道具 举报

9#
ID:52966 发表于 2013-8-12 19:43 | 只看该作者
学无止境
回复

使用道具 举报

8#
ID:52397 发表于 2013-7-29 15:48 | 只看该作者
楼上的你就会说:不错的,好假货,大家一起学习下   说点别的好不好
回复

使用道具 举报

7#
ID:52177 发表于 2013-7-23 23:17 | 只看该作者
不错的,好假货,大家一起学习下
回复

使用道具 举报

6#
ID:16521 发表于 2013-7-9 23:08 | 只看该作者
怎么下载不了啊,是不是我的电脑网络问题呢
回复

使用道具 举报

5#
ID:16521 发表于 2013-7-9 23:07 | 只看该作者
谢谢楼主分享。
回复

使用道具 举报

地板
ID:51248 发表于 2013-7-9 10:26 | 只看该作者
谢谢楼主分享!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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