首页 > 代码库 > 蓝桥杯板子红外线使用,NEC协议

蓝桥杯板子红外线使用,NEC协议

遥控器 是ht6121 接收器是TSOP1838

协议的讲解ppt里有点击打开链接

连线就是把N_B2连到P3^2

简单讲讲代码

 

#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit IRIN = P3^2;	
uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar dspbuf[]={10,10,10,10,10,10,10,10};
#define delay1us {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
uchar discom=0;

void IrInit();
void DelayMs(unsigned int );

void displaylcd()////////////////////实验室的开发板
{
    P2=(P2&0X1F)|0XE0;
	P0=0Xff;	   //消隐
	P2=(P2&0X1F);

	P2=(P2&0X1F)|0XC0;
    P0=(1<<discom);	   //位选   00000001
	P2=(P2&0X1F);

	P2=(P2&0X1F)|0XE0;
    P0=~tab[dspbuf[discom]]; 	   //段选 dspbuf[0]=1
	P2=(P2&0X1F);
	DelayMs(1);
	if(++discom==8)
	discom=0;
}



unsigned char IrValue[6];	  //用来存放读取到的红外值
unsigned char Time;

void main()
{
	IrInit();
	while(1)
	{
		IrValue[4]=IrValue[2]>>4;	 	 	//高位
		IrValue[5]=IrValue[2]&0x0f;		//低位
		dspbuf[0] = 0x00;
		dspbuf[1] =IrValue[4];
		dspbuf[2] =IrValue[5];
		dspbuf[3] = 0;	  //01110110
		dspbuf[4] = 0x00;
		dspbuf[5] = IrValue[4];
		dspbuf[6] = IrValue[5];
		dspbuf[7] = 0;
		
		displaylcd();
	}
}									 

void DelayMs(unsigned int a)   //0.14ms误差 0us
{
  uint i,j;
  for(j=0;j<a;j++)
  for(i=0;i<11;i++)
  {
	  delay1us  delay1us
	  delay1us  delay1us
	  delay1us  delay1us
	  delay1us  delay1us
	  
  }
}

void IrInit()
{
	IT0=1;//下降沿触发
	EX0=1;//打开中断0允许
	EA=1;	//打开总中断

	IRIN=1;//初始化端口
}

void ReadIr() interrupt 0
{
	unsigned char j,k;
	unsigned int err;
	Time=0;					 
	DelayMs(70);

	if(IRIN==0)		//确认是否真的接收到正确的信号
	{	 
		
		err=200;				//1000*10us=10ms,超过说明接收到错误的信号
		/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
		侯,程序死在这里*/	
		while((IRIN==0)&&(err>0))	//等待前面9ms的低电平过去  		
		{			
			DelayMs(1);
			err--;
		} 
		if(IRIN==1)			//如果正确等到9ms低电平
		{
			err=100;
			while((IRIN==1)&&(err>0))		 //等待4.5ms的起始高电平过去
			{
				DelayMs(1);
				err--;
			}
			for(k=0;k<4;k++)		//共有4组数据
			{				
				for(j=0;j<8;j++)	//接收一组数据
				{

					err=60;		
					while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
					{
						DelayMs(1);
						err--;
					}
					err=500;
					while((IRIN==1)&&(err>0))	 //计算高电平的时间长度。
					{
						DelayMs(1);//0.14ms
						Time++;
						err--;
						if(Time>30)
						{
							EX0=1;
							return;
						}
					}
					IrValue[k]>>=1;	 //k表示第几组数据
					if(Time>=12)			//如果高电平出现大于565us,那么是1
					{
						IrValue[k]|=0x80;
					}
					Time=0;		//用完时间要重新赋值							
				}
			}
		}
		if(IrValue[2]!=~IrValue[3])
		{
			return;
		}
	}			
}  

主要有几个地方注意一下,我原先疑问应该在进入中断时关掉它免得后面的下降沿继续出发,但是我后来查了一下,如下
一个外部中断的请求标志只有一位,这个标志在遇到RETI时撤出,所以在进入中断到RETI前这段时间,中断请求标志不会随你的有效触发条件而变化。  
简而言之,在中断程序执行时下降沿不会再出发外部中断
再者就是延时,这个芯片也不能用烧录软件直接生成延时,我知道的最靠谱的办法就是用_nop_() 但是还有for在,所以具体时间还是不太准,有空再测一下 先这样吧
还有就是刚刚看别人的代码发现一个容易错的 姑且也在这说一下,就是这里移位放到读到1或0之前,放到之后的话就会多移一位,不小心有可能会错                                                                                                                                 

 

蓝桥杯板子红外线使用,NEC协议