NEC红外线解码协议

非常精简的NEC红外解码程序,适合程序存储空间低的单片机(C语言)

注意:之所以程序精简,是因为解码NEC协议时只计算协议中的高电平时间,不去计算低电平时间。对应的,可能会出现未知干扰波造成解码失败。

解码之前,我们先来熟悉一下NEC协议:

1、NEC协议载波:38khz
2、NEC编码格式为:引导码+8bit用户码+8bit用户反码+8bit数据码+8bit数据反码+重复码
3、NEC协议格式:
在这里插入图片描述
上图是一个完整的波形,其中每隔110ms发送一个重复码。
4、对应单片机解码需要用到的:
在这里插入图片描述
知道这些我们就可以开始解码了。(如有错误,请高手指出 ^_^ ^_^)

/* 寄存器定义 */
uint8_t  IRHigh;                                          /* 计数IR脚高电平时间              */
uint8_t  IRReceiveCnt;                                    /* IR接收数据计数                  */
uint16_t UserCodeVal;                                     /* 用户码                          */
uint16_t DataCodeVal;                                     /* 数据码                          */
uint32_t DecodeVal;                              /* 32位数据 用户码+用户反码+数据码+数据反码 */
/* 位定义 */
#define IR_OK      	             UserFlag.0               /* 解码完成时置一                  */
#define IR_START_SIGNAL          UserFlag.1               /* 红外解码引导码 检测到引导码置一 */
#define IR_PIN_START             UserFlag.2               /* IO电平状态标志                  */
/* 宏定义 */
#define USER_CODE                0x10ED                     /* 用户码 校验数据               */

/*******************************************************************************************
*                                   简易的NEC红外解码程序
* 1.此函数只是粗略的检测NEC协议中的高电平时间
* 2.此函数通过判断IO口状态+定时器扫描的方式完成的
* 3.此函数非常精简 用应广XY_IDE编译出来的文件只占79个程序空间 非常适合程序空间小的单片机
* 4.此函数解码是依据MSB优先传输,正好和NEC相反(LSB优先传输),特此注明
* 5.此函数没有对解码出来的数据进行校验 (数据码+数据反码=0xff 用户码+用户反码=0xff )
****声明:此函数仅作为参考程序 如需商业使用 还请自行验证
****验证平台:应广XY150C单片机+标准NEC协议遥控器
********************************************************************************************/     
void IRDecode(void){                                   /* 此函数 100us扫描一次             */
   if(!IR_OK){                                        /* 解码完成为1                      */
   	if(IR_PIN_START){
   		if(!IR){               IR_PIN_START = 0; } /* 判断引脚电平状态 下降沿          */
   		if(IRHigh<49){         IRHigh++;         } /* 计时IR脚高电平时间	           */
   	}
   	else{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
   		if(IR){                
   			IR_PIN_START = 1;                      /* 判断引脚电平状态 上升沿          */
   			
   			if(IR_START_SIGNAL){                   /* 检测到引导码 可以开始解码        */
   				if(IRHigh>=13 && IRHigh<=19){	   /* 数据1      1.7ms高电平           */				
   					IRReceiveCnt++;                /* 接收的信号次数计数               */
   					DecodeVal<<=1;                      
   					DecodeVal++;                   /* 将数据存入 接收数据寄存器中      */
   				}
   				else if(IRHigh>=4 && IRHigh<=8){   /* 数据 0    0.56ms高电平           */							
   					IRReceiveCnt++;                /* 接收的信号次数计数               */
   					DecodeVal<<=1;                 /* 将数据存入 接收数据寄存器中      */
   				}
   				else{
   					IR_START_SIGNAL = 0;           /* 错误信号  复位解码状态           */
   					IRReceiveCnt    = 0;
   				}
   				
   				if(IRReceiveCnt==32){      /* 32个信号为一个周期 16位用户码+16位数据码 */
   					UserCodeVal = DecodeVal>>16;  /* 取用户码                          */
   					DataCodeVal = DecodeVal;      /* 取数据码                          */
   					
   					if(UserCodeVal == USER_CODE){ /* 校验用户码                        */      
   						IR_OK = 1;                /* 解码完成                          */
   						
   					}	
   					
   					IR_START_SIGNAL = 0;
   					IRReceiveCnt    = 0;
   				}		
   			}
   			
   			if(IRHigh>=44){		                   /* 高电平信号4.4ms-4.8ms 为引导码  */
   				IRReceiveCnt    = 0;
   				IR_START_SIGNAL = 1;
   				if(IRHigh==49){IR_START_SIGNAL = 0;}/* 错误信号   复位解码状态        */
   			}
   			
   			IRHigh = 0;                             /* 清除高电平时间计数             */
   		}			
   	}				
   }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值