51单片机实现NEC红外通信协议的解码

NEC协议中1、0电平的表示
51单片机实现NEC红外通信协议的解码_第1张图片
数据格式:
数据格式包括了引导码、用户码、数据码和数据码反码,编码总占32位。数据反码是数据码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。
51单片机实现NEC红外通信协议的解码_第2张图片
代码实现:
头文件NEC.h

#ifndef NEC
#define	NEC

#include 

sbit INIR=P3^2;							//红外端口,同时是EX0中断口
void init();						//初始化函数
void delayus();						//延时函数
unsigned char time;					//计算电平长度
unsigned char rec[4];				//存放数据
#endif

主函数main.c

#include "NEC.h "
void main()
{
     
	init();
	while(1);
}
void delayus(unsigned char i)									//延时,单位约10us
{
     
	while(i--);
}

void init()
{
     
	EA=1;										//总中断
	EX0=1;									//外部中断0
	IT0=1;									//下降沿触发
	
	INIR=1;									//红外接收端口置1
}

void Read() interrupt 0
{
     
	unsigned char k,j;
	unsigned int err;
	time=0;
	delayus(700);    //延时7ms
	if(INIR==0)
	{
     
		err=1000;				 //设置err,规定某一时长循环结束,防止程序陷入死循环
		while((err>0)&&(INIR==0))							//检测起始码9ms低电平
		{
     
			delayus(1);
			err--;
		}
		if(INIR==1)
		{
     
			err=500;
			while((INIR==1)&&(err>0))						//检测起始码4.5ms高电平
			{
     
				delayus(1);
				err--;
			}
			for(k=0;k<4;k++)									//四段数据
			{
     
				for(j=0;j<8;j++)								//每段中的八位bit数据          
				{
     
					err=60;
					if((INIR==0)&&(err>0))						//检测0.56us低电平
					{
     
						delayus(1);
						err--;
					}
					err=300;
					if((INIR==1)&&(err>0))						//计算高电平时长
					{
     
						delayus(1);
						err--;
						time++;
						if(time>250)							//如果长度大于2.5ms
							return;							//信号错误,提前结束read()函数
					}
					rec[k]>>=1;                 //右移一位,留空以存放一位bit
					if(time>80)
						rec[k]|=0x80;							//最高位赋1
					
					time=0;											//time归零
				}
			}
		}
		if(rec[2]!=~rec[3])								//校验数据是否正确
			return;
	}
}
//rec[0],rec[1]:用户码 rec[2]:数据码 rec[3]:数据反码

考虑硬件实际运行过程中的误差,时间无法准确卡点,所以采取一个时间段来估计判断的方法

你可能感兴趣的:(51单片机,嵌入式,单片机)