可界说恣意I/O作接纳脚,支撑长/短按,自适应主频6MHz~40
//*********************【 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; //清守时器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; }}}