在不同的红外解码方式中,我发现以下这种解码方法实用容易理解,代码 如下
#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);
}