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

NEC协议中1、0电平的表示

数据格式:
数据格式包括了引导码、用户码、数据码和数据码反码,编码总占32位。数据反码是数据码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。
在这里插入图片描述
代码实现:
头文件NEC.h

#ifndef NEC
#define	NEC

#include <reg52.h>

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]:数据反码

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值