// 解码值在Im[2]中,当IrOK=1时解码有效。
/* 51单片机红外遥控解码程序 */
//用遥控器对准红外接收头,按下遥控器按键,在数码管前两位上就会显示对应按键的编码
#include <reg52.h>
#define uchar unsigned char
sbit dula=P2^6
sbit wela=P2^7
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}
uchar f
#define Imax 14000 //此处为晶振为11.0592时的取值,
#define Imin 8000 //如用其它频率的晶振时,
#define Inum1 1450 //要改变相应的取值。
#define Inum2 700
#define Inum3 3000
unsigned char Im[4]={0x00,0x00,0x00,0x00}
uchar show[2]={0,0}
unsigned long m,Tc
unsigned char IrOK
void delay(uchar i)
{
uchar j,k
for(j=ij>0j--)
for(k=125k>0k--)
}
void display()
{
dula=0
P0=table[show[0]]
dula=1
dula=0
wela=0
P0=0xfe
wela=1
wela=0
delay(5)
P0=table[show[1]]
dula=1
dula=0
P0=0xfd
wela=1
wela=0
delay(5)
} //外部中断解码程序
void intersvr1(void) interrupt 2 using 1
{
Tc=TH0*256+TL0 //提取中断时间间隔时长
TH0=0
TL0=0 //定时中断重新置零
if((Tc>Imin)&&(Tc<Imax))
{
m=0
f=1
return
} //找到启始码
if(f==1)
{
if(Tc>Inum1&&Tc<Inum3)
{
Im[m/8]=Im[m/8]>>1|0x80m++
}
if(Tc>Inum2&&Tc<Inum1)
{
Im[m/8]=Im[m/8]>>1m++//取码
}
if(m==32)
{
m=0
f=0
if(Im[2]==~Im[3])
{
IrOK=1
}
else IrOK=0 //取码完成后判断读码是否正确
}
//准备读下一码
}
}
/*演示主程序*/
void main(void)
{
unsigned int a
m=0
f=0
EA=1
IT1=1EX1=1
TMOD=0x11
TH0=0TL0=0
TR0=1//ET0=1
while(1)
{
if(IrOK==1)
{
show[1]=Im[2] &0x0F //取键码的低四位
show[0]=Im[2] >>4
IrOK=0
}
for(a=100a>0a--)
{
display()
}
}
}
解码程序这个就能实现
#include <REGX52.h>#define uchar unsigned char
uchar dataIRcode[4] //定义一个带冲4字节的数组用来存储代码
uchar CodeTemp //编码字节缓存变量
uchar i,j,k //延时用的循环变量
sbit IRsignal=P3^2 //HS0038接收头OUT端直接连P3.2(INT0)
/**************************延时0.9ms子程序**********************/
void Delay0_9ms(void)
{uchar j,k
for(j=18j>0j--)
for(k=20k>0k--)
}
/***************************延时1ms子程序**********************/
void Delay1ms(void)
{uchar i,j
for(i=2i>0i--)
for(j=230j>0j--)
}
/颤行纤***************************延时4.5ms子程序**********************/
void Delay4_5ms(void)
{uchar i,j
for(i=10i>0i--)
for(j=225j>0j--)
}
/**************************** 延时子程序 ************************/
void Delay(void)
{uchar i,j,k
for(i=200i>0i--)
for(j=200j>0j--)
for(k=3k>0k--)
}
/************************中断0解码服务子程序**********************/
void int0(void) interrupt 0 using 2
{
EA=0
for(k=0k<10k++)
{Delay0_9ms()
if (IRsignal==1) //如果0.9ms后IRsignal=1,说明不是引导码
{k=10break}
else if(k==9) //如果持续了10×0.9ms=9ms的低电平,说明是引导码
{while(IRsignal==0)
Delay4_5ms() //跳过持续4.5ms的高电平
for(i=0i<4i++) //分别读取4个字节
{for(j=1j<=8j++) //每个字节8个bit的判断
{ while(IRsignal==0) //等待上升沿
Delay0_9ms() //从上升沿那一时刻开始延时0.9ms,再判断IRsignal
if(IRsignal==1) //如果IRsignal是"1",则向右移入一位"1"
{Delay1ms()
CodeTemp=CodeTemp|0x80
if(j<8) CodeTemp=CodeTemp>>1
}
else
if(j<8)CodeTemp=CodeTemp>>1//如果IRsignal是"0",则向右移一位,自动补"茄仿0"
}
IRcode[i]=CodeTemp
CodeTemp=0
}
for(i=0i<4i++)//通过串口将代码发出
{
SBUF=IRcode[i]
while(!TI) //等待一个字节发送完毕
TI=0
}
Delay()
}
}
EA=1
}
/***********************串口初始化程序*********************/
void initUart(void)
{
TMOD|=0x20
SCON=0x50
PCON|=0x80
TH1=0xff//57600bps @ 11.0592MHz
TL1=0xff
TR1=1
}
/**************************主程序*************************/
void main()
{ initUart()
IT0=1 //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)
EX0=1 //外部中断INT0开, (1:开, 0:关)
EA=1 //开所有中断
CodeTemp=0 //初始化红外编码字节缓存变量
Delay()
while(1)
}
规格书上注明工作电压最低4.5v。当然3.3v也可能正常工作,但受周边环境干扰程度就越大。
可以试将接收头用图筒卡纸包围,观察干裂塌扰输出肆岁圆的信号是雀哪否仍然存在。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)