| 
 
| 引导码为9ms+4.5ms,红外接收头任意连接单片机。 void time0(void) interrupt 1
 {
 IR_NEC();
 XS();
 }
 #define  USER_H     0x80                         //用户码高8位
 #define  USER_L     0x7F                         //用户码低8位
 #define  Check_EN   0                             //是否要校验16位用户码:不校验填0,校验则填1
 #define  CPU_Fosc   12000000             //输入主频,自适应解码(单位: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) +2000)/Step)          //引导码周期上限
 #define    Boot_Lower            (((9000+4500) -2000)/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,装载位码数
 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
 可以帮忙看看Boot_Limit,Boot_Lower,Bit1_Limit,Bit0_Limit是如何计算出来的?
 | 
 |