微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 一个红外线发射+解码程序+仿真文件

一个红外线发射+解码程序+仿真文件

时间:11-29 来源:互联网 点击:
可定义任意I/O作接收脚,支持长/短按,自适应主频6MHz~40


//****************************************////     简介:本程序适用于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__//#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;           //清定时器0TMOD |= 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;  }     //解码有效,接下来判断:短按?长按?#elseif(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 "INCSTC89C52RC.H"#include "INCMY_SET.H"#include "INCIR_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();         }

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top