51单片机LCD1602显示红外线值

红外线引脚示意图
在这里插入图片描述
红外线传输数据格式
在这里插入图片描述
数据格式包括了引导码、用户码、数据码和数据码反码,编码总占32位。数据反码是数据码反相后的编码,编码时可用于对数据的纠错。注意:第二段的用户码也可以在遥控应用电路中被设置成第一段用户码的反码。

传输数据位定义
在这里插入图片描述
用户码或数据码中的每一个位可以是位 ‘1’ ,也可以是位 ‘0’。区分 ‘0’和 ‘1’是利用脉冲的时间间隔来区分,这种编码方式称为脉冲位置调制方式,英文简写PPM

在这里插入代码片#include<reg51.h>
#define LCD1602_DATAPINS P0
#define uchar unsigned char
#define uint unsigned int

sbit IRIN=P3^2;

sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;


unsigned char code CDIS1[13]={" Red Control "};
unsigned char code CDIS2[13]={" IR-CODE:--H "};
unsigned char IrValue[6];
unsigned char Time;

void IrInit();
void DelayMs(unsigned int );
void LcdWriteCom(uchar com);
void LcdWriteData(uchar dat);
void LcdInit();

void main()
{
	unsigned char i;
	IrInit();	
	LcdInit();
	LcdWriteCom(0x80);
	for(i=0;i<13;i++)
	{
		LcdWriteData(CDIS1[i]);	
	}
	LcdWriteCom(0x80+0x40);
	for(i=0;i<13;i++)
	{
		LcdWriteData(CDIS2[i]);	
	}
	while(1)
	{
		IrValue[4]=IrValue[2]>>4;	 	 	//高位
		IrValue[5]=IrValue[2]&0x0f;		//低位	
		if(IrValue[4]>9)
		{
			LcdWriteCom(0xc0+0x09);			//设置显示位置
			LcdWriteData(0x37+IrValue[4]);	//将数值转换为该显示的ASCII码
		}
		else
		{
			LcdWriteCom(0xc0+0x09);
			LcdWriteData(IrValue[4]+0x30);	//将数值转换为该显示的ASCII码
		}	
		if(IrValue[5]>9)
		{
			LcdWriteCom(0xc0+0x0a);
			LcdWriteData(IrValue[5]+0x37);		//将数值转换为该显示的ASCII码
		}
		else
		{
			LcdWriteCom(0xc0+0x0a);
			LcdWriteData(IrValue[5]+0x30);		//将数值转换为该显示的ASCII码
		}	
	}
}									 

void DelayMs(unsigned int x)   //0.14ms误差 0us
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++)
 {}
 }
}

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=1000;				//1000*10us=10ms,超过说明接收到错误的信号
		/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
		侯,程序死在这里*/	
		while((IRIN==0)&&(err>0))	//等待前面9ms的低电平过去  		
		{			
			DelayMs(1);
			err--;
		} 
		if(IRIN==1)			//如果正确等到9ms低电平
		{
			err=500;
			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低电平过去
//					while (!IRIN)
					{
						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表示第几组数据,没有这个总是显示80
					if(Time>=8)			//如果高电平出现大于565us,那么是1
					{
						IrValue[k]|=0x80;
					}
					Time=0;		//用完时间要重新赋值							
				}
			}
		}
		if(IrValue[2]!=~IrValue[3])
		{
			return;
		}
	}			
}

void LcdWriteCom(uchar com)	  //写入命令
{
	LCD1602_E = 0;     //使能
	LCD1602_RS = 0;	   //选择发送命令
	LCD1602_RW = 0;	   //选择写入
	
	LCD1602_DATAPINS = com;     //放入命令
	DelayMs(1);		//等待数据稳定

	LCD1602_E = 1;	          //写入时序
	DelayMs(5);	  //保持时间
	LCD1602_E = 0;
}

void LcdWriteData(uchar dat)			//写入数据
{
	LCD1602_E = 0;	//使能清零
	LCD1602_RS = 1;	//选择输入数据
	LCD1602_RW = 0;	//选择写入

	LCD1602_DATAPINS = dat; //写入数据
	DelayMs(1);

	LCD1602_E = 1;   //写入时序
	DelayMs(5);   //保持时间
	LCD1602_E = 0;
}

void LcdInit()						  //LCD初始化子程序
{
 	LcdWriteCom(0x38);  //开显示
	LcdWriteCom(0x0c);  //开显示不显示光标
	LcdWriteCom(0x06);  //写一个指针加1
	LcdWriteCom(0x01);  //清屏
	LcdWriteCom(0x80);  //设置数据指针起点
}

LCD显示部分可以参考我一篇文章
51单片机DS1302时钟LCD1602显示

以上是我在学习过程中的一点总结,用的是普中的51单片机·。

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值