红外遥控接收

在不同的红外解码方式中,我发现以下这种解码方法实用容易理解,代码 如下

#include <reg52.h>
#include "lcd_1602.h"
#define uchar unsigned char
#define uint unsigned int

sbit IR=P3^2;	  //红外接收器数据线接在外部中断0端口

uchar code  lcddis[16] = {"Remote Control "};
uchar code  lcddis1[16]={"0123456789ABCDEF"};//用来将数据对应转换成字符以便LCD显示
uchar disp[8];    //红外数据显示
uchar irdata[33]; //原始数据
uchar bitnum;	  //原始数据下标

uchar irtime;      //记录0/1时间		
uchar startflag;   //红外接收开始标志
uchar irreceiveok; //接收完成
uchar ircode[4];   //接收到的4组数据 
uchar irdecodeok;  //解码完成
 //-------------初始化定时器-----------------
void timer0_init(void)
{
	TMOD = 0x02;   //定时器0方式2
	//TH0 = 0;
	//TL0 = 0;
	ET0 = 1;
	EA = 1;
	TR0 = 1;	
}
//--------------初始化外部中断0--------------
void int0_init(void)
{
	EA=1;    //开总中断
	EX0=1;   //开外部中断
	IT0=1;   //下降沿触发,因为红外接收到的和发射反相
}
//----------------数据解码-------------------
void ir_decode(void)
{
	uchar k=1,i,j;
	uchar value;
	for(j=0;j<4;j++)
	{
		for(i=0;i<8;i++)
		{
			value=value>>1;  //低位在前,高位在后
			if(irdata[k]>6)  //时间长的为1
			{
				value=value | 0x80;
			}
			k++;
		}
		ircode[j]=value;
	}
	irdecodeok=1;
}
 //--------------分离数据---------------------
void decode_resolve(void)
{
	disp[0]=ircode[0]/16;
	disp[1]=ircode[0]%16;
	disp[2]=ircode[1]/16;
	disp[3]=ircode[1]%16;
	disp[4]=ircode[2]/16;
	disp[5]=ircode[2]%16;
	disp[6]=ircode[3]/16;
	disp[7]=ircode[3]%16;	
}
//--------------主函数-------------------------
void main()
{   
	uchar k;
	lcd_init();
	timer0_init();
	int0_init();
	while(1)
	{
		if(irreceiveok==1)	//如果全部接收完成开始解码
		{
			startflag=0;
			irreceiveok=0;
			ir_decode();
			if(irdecodeok==1)  //如果解码完成分解数据以便显示
			{
				irdecodeok=0;
				decode_resolve();
			}
		}
		/******LCD显示******/
		lcd_write_str(0,0,lcddis); 
		for(k=0;k<8;k++)
		{
			lcd_write_char(k,1,lcddis1[disp[k]]);
			delay_ms(3);
		}
		delay_ms(50);
	}
}
//-------------定时器0中断----------------------
void timer0() interrupt 1
{
	irtime++;        //255
} 
//-------------外部中断--------------------------
void IR_IN() interrupt 0 using 0
{
	if(startflag=1)	  
	{
		if(irtime>32) //检测到引导码	
		{
			bitnum=0;
		}
		irdata[bitnum]=irtime; //使用数组记录时间
		irtime=0;
		bitnum++;
		if(bitnum==33)
		{
			bitnum=0;
			irreceiveok=1;
		}	
	}
	else
	{
		startflag=1;  //跳过第一个下降沿
		irtime=0;
	}
}

LCD1602代码:

#include <reg52.h>
#include <intrins.h>
#include "lcd_1602.h"
#define uchar unsigned char
#define uint unsigned int 

sbit RS=P3^3;   //LCD定义            
sbit RW=P3^4;
sbit EN=P3^5;

#define LCD_PORT P0	   
#define RS_CLR RS = 0
#define RS_SET RS = 1
#define RW_CLR RW = 0
#define RW_SET RW = 1
#define EN_CLR EN = 0
#define EN_SET EN = 1

/*******************************************************************/
/**函数名:delay_ms(uint x)
/**功能:ms级别延时
/**入口参数:uint
/**出口参数:无
/*******************************************************************/
void delay_ms(uint x)
{
 	uint i,j;
 		for(i=x;i>0;i--)
  			for(j=120;j>0;j--);
}
/*******************************************************************/
/**函数名:delay_1us()
/**功能:1us延时
/**入口参数:无
/**出口参数:无
/*******************************************************************/
void delay_1us()//us级别延时
{_nop_();_nop_();_nop_();}

/*******************************************************************/
/**函数名:lcd_write_command(uchar command)
/**功能:LCD写命令
/**入口参数:uchar
/**出口参数:无
/*******************************************************************/
void lcd_write_command(uchar command)
{
	 RS_CLR;   //指令模式
	 RW_CLR;   //写操作
	 LCD_PORT = command; 
	 delay_ms(3);  //EN脉冲
	 EN_SET;     
	 delay_1us();
	 EN_CLR;
}
/*******************************************************************/
/**函数名:lcd_write_dat(uchar dat)
/**功能:LCD写数据
/**入口参数:uchar
/**出口参数:无
/*******************************************************************/
void lcd_write_dat(uchar dat)
{
	 RS_SET;   //数据模式
	 RW_CLR;   //写操作
	 LCD_PORT = dat;
	 delay_ms(3);  //EN脉冲
	 EN_SET;     
	 delay_1us();
	 EN_CLR;
} 
/*******************************************************************/
/**函数名:lcd_init()
/**功能:LCD初始化
/**入口参数:无 
/**出口参数:无
/*******************************************************************/
void lcd_init()
{
	 lcd_write_command(0x01);  //清屏
	 lcd_write_command(0x38);  //显示模式设置
	 lcd_write_command(0x0c);     //开显示,不显示光标,光标不闪烁
	 //lcd_write_command(0x0e);   //开显示,显示光标,光标不闪烁
	 //lcd_write_command(0x0d);   //开显示,不显示光标,光标闪烁
	 //lcd_write_command(0x0f);   //开显示,显示光标,光标闪烁
	 lcd_write_command(0x06);   //地址加一光标加一
	 //lcd_write_command(0x07); //写一字符,整屏左移
	 
}
/*******************************************************************/
/**函数名:lcd_set_xy(uchar x,uchar y)
/**功能:LCD字符显示初始地址设置
/**入口参数:uchar
/**出口参数:无
/*******************************************************************/
void lcd_set_xy(uchar x,uchar y)
{
 	uchar address;
	 if(y==0)
	 	address = 0x80+x;
	 else
	 	address = 0xc0+x;
	 lcd_write_command(address);
}
/*******************************************************************/
/**函数名:lcd_write_str(uchar x,uchar y,uchar *s)
/**功能:LCD字在第x行y列开始显示
/**入口参数:uchar
/**出口参数:无
/*******************************************************************/
void lcd_write_str(uchar x,uchar y,uchar *s)
{
	 lcd_set_xy(x,y);
	 while(*s)
	 {
	 	lcd_write_dat(*s);
	 	s++;
	 }
}
/*******************************************************************/
/**函数名:lcd_write_char(uchar x,uchar y,uchar dat)
/**功能:LCD在第X行Y列开始显示Wdat所对应的单个字符
/**入口参数:uchar
/**出口参数:无
/*******************************************************************/
void lcd_write_char(uchar x,uchar y,uchar dat)
{
	 lcd_set_xy(x,y);
	 lcd_write_dat(dat);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值