Last updated on
51单片机红外解码程序
单片机型号:AT89S52 红外接收模块:HX1838 红外编码模块:HT6222 程序作者:szy0syz
本程序将HT62222发送的波形用HX13838接收,再使用单片机软解码并将结果显示在8个数码段上。 显示内容包括:用户编码8bit*2,按键编码bit*2 算法:通过延迟检测宽窄正脉冲,直接跳过负脉冲,和网上流传那个即卡上升沿又卡下降沿的算法精简了许多。 关于如何设置延迟请用示波器检测波形。 程序代码如下:
////////////////////////////////////////////
//程序名:HT62222红外发送,51单片机软解码
//作者:szy0syz
//时间:2010.7.18
/////////////////////////////////////////////
////////////////////////////////////////////
//定义数组ir_rec[],分别装解码后得到的数据
//ir_rec[0]~ir_rec[7] 低8位地址码
//ir_rec[8]~ir_rec[16] 高8位地址码
//ir_rec[17]~ir_rec[24] 8位数据码
//ir_rec[24]~ir_rec[31] 8位数据码的反码
/////////////////////////////////////////////
#include
sbit IRIN = P3^2; //红外接收器数据线
#define uchar unsigned char
#define uint unsigned int
unsigned char const dofly[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码值01234567
unsigned char code seg[]={0,1,2,3,4,5,6,7};//分别对应相应的数码管点亮,即位码
unsigned int ir_rec[32]={0};
/*--------------------------------------------------------------------
子程序名称:50us 延时
--------------------------------------------------------------------*/
void delay_50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--)
;
}
void delay(unsigned int cnt)
{
while(--cnt);
}
///////////////
//初始化
////////////
void IR_init(void)
{
EA=1;
EX0=1; //允许总中断中断,使能 INT0 外部中断
IT0=1; //触发方式为脉冲负边沿触发
//IRIN=1; //I/O口初始化
}
//////////
//解码过程
//////////////
void IR_CODE(void) interrupt 0 //在外部中断子程序中解码
{
uchar j,k,n=0;
EX0 = 0; //关闭外部中断1
delay_50us(273); //延时273*0.05=13.65ms>9+4.5 ,直接跳过两个前导码
//注意:这里的值最好接近13.5,否则会对地址码检测产生严重的干扰
//否则检测成功率只有50%左右
if(IRIN==1) //检测是否是干扰
{ //确认IR信号出现
EX0 =1; //是干扰就重新开启INT0中断
return;
}
//while(!IRIN) ; //等IRIN变为高电平,开始解码
for (j=0;j<4;j++) //收集4组数据
{
for (k=0;k<8;k++) //每组数据有8位
{
while(!IRIN) delay_50us(1); //等待高电平
delay_50us(16); //延时0.8ms,减少误差尽量跳到边缘即可
if(IRIN==1)
{
ir_rec[n]=1;
delay_50us(20); //延时1ms
}
else ir_rec[n]=0;
n++;
}
}
EX0=1;
}
void main(void)
{
int i;
IR_init( ); //初始化外部中断0
for(i=0;i<32;i++) ir_rec[i]=0; //初始化接受数组
i=0;
while(1)
{
P0=dofly[ir_rec[i+16]]; //取显示数据,段码
P2=seg[i]; //取位码
delay(100); //扫描间隙延时,时间太长会闪烁
i++; //太短会造成重影,这里使用长时间方便了解显示原理
if(i>=8) i=0; //检测8位扫描完全?
}
}