NEC协议是众多红外遥控协议的其中一种,下面以蓝桥杯的单片机开发板实现红外解码。

相关芯片与元器件介绍

在这里插入图片描述
此图为跳线帽的解法,在做红外通信时应接3,5;4,6。
在这里插入图片描述

此图左为红外发射装置和HX1838集成芯片,放大与接受于一体,可实现对红外线的解调。
此图右为一简单的红外发射装置,发出的红外线信号易受干扰,且无法实现与HX1838的通信,若要实现红外发射,必须加上高频载波(38KHz),可以用555定时器产生高频载波。(通信原理相关知识,我只了解皮毛……)

在这里插入图片描述

NEC协议的格式

首先来看NEC协议的典型脉冲链:
主要分为:
引导码----用户码(区分不同遥控器)----用户码反码----键码(键值)----键码反码
框图:
在这里插入图片描述

具体形式:
在这里插入图片描述
注意:由于在HX1838芯片解码时,输出管脚接受到的编码是红外线的编码的反码。
在这里插入图片描述

而具体的引导码形式和逻辑位的形式如下图所示:
在这里插入图片描述
按照上图,就可以写代码了!

代码实现及流程图

首先搬运流程图(来自https://blog.csdn.net/jiabao817/article/details/80568610)
在这里插入图片描述

注意读取一次数据的过程全部在一次外部中断中进行,P1.1口在接收到引导码的低位时拉低(与外部中断用杜邦线接上),便进入了外部中断,然后进行一系列的读数据操作。读高电平的时间和读低电平的时间分别用两个函数去实现,类似于超声波测距的方法,这里还需注意遇到异常情况要跳出中断。

//读取高电平时间
uint GetHighTime()
{
	TH1=0;
	TL1=0;
	TR1=1;
	while(IR_input)
	{
		if(TH1>=0x40)
			break;
	}
	TR1=0;
	
	return (TH1*256+TL1);
}

//读取低电平时间
uint GetLowTime()
{
	TH1=0;
	TL1=0;
	TR1=1;
	while(!IR_input)
	{
		if(TH1>=0x40)
			break;
	}
	TR1=0;
	
	return (TH1*256+TL1);
}

//外部中断的服务函数
void Int1_Service() interrupt 1
{
	uint time;
	uchar i,j;
	uchar byte=0;
	
	time=GetLowTime();
	if((time<7833)||(time>8755))
	{
		IE1=0;					//清除外部中断,防止其再进入
		return;
	}
	
	time=GetHighTime();
	if((time<3686)||(time>4608))
	{
		IE1=0;
		return;
	}
	
	//连续读取四个字节的数据
	for(i=0;i<4;i++)
	{
		for(j=0;j<8;j++)
		{
			time=GetLowTime();
			if((time<313)||(time>718))
			{
				IE1=0;
				return;
			}
			
			time=GetHighTime();
			if((time>313)&&(time<718))
			{
				byte=byte>>1;
			}
			else if((time>1345)&&(time<1751))
			{
				byte>>=1;
				byte|=0x80;
			}
			else
			{
				IE1=0;
				return;
			}
		}
		Buf[i]=byte;
		byte=0;
	}
	
}

(还有两个礼拜就要比赛了,然而我才刚开始准备……
最近事情是真的多,国赛题目都不一定能做完,蓝桥杯真的要随缘了……
这日子过得是真的迷茫,有苦却没法说……)

References:

https://blog.csdn.net/weixin_43444989/article/details/89302008
https://wenku.baidu.com/view/62e1bd7a02768e9951e738f3.html
https://blog.csdn.net/yannanxiu/article/details/26171705
https://www.cnblogs.com/openusb/archive/2010/01/07/1641357.html