// 解码值在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()
}
}
}
解码程序这个就能实现
那个N大灶困耐于30是尺败因为已经超出了0和1代表的时间长度。0和1所代表的高低电平时间不一样。当高电平时长超过n=8时,代表1否则代表0.这个是和你红外设置的0,1代表时间长度有关系,请隐春问你有时序图吗??那就一目了然了#include <reg51.h>#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit IRIN = P3^2 //遥控输入脚
sbit BEEP = P3^7 //蜂鸣器
sbit RELAY= P3^6 //继电器
uchar IR_buf[4]={0x00,0x00,0x00,0x00}//IR_buf[0]、IR_buf[1]为用户码低位、用户码高位接收缓冲区
// IR_buf[2]、IR_buf[3]为键数据码和键数据码反码接收缓冲区
uchar disp_buf[2]={0x10,0x10} //显示缓冲单元,初值为0x10(即16),指向显示码的第16个"-"
uchar code seg_data[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf}
//0~F和"-"符的显示码(字形码)
/********以下是0.14ms的x倍延时函数********/
void delay(uchar x) //延时x*0.14ms
{
uchar i
while(x--)
for (i = 0i<13i++)
}
/********以下是延饥培时函数********/
void Delay_ms(uint xms)
{
uint i,j
for(i=xmsi>0i--) //i=xms即延时约xms毫秒
for(j=110j>0j--)
}
/*********以下是蜂鸣器响一声函数********/
void beep()
{
BEEP=0 //蜂鸣器响
Delay_ms(100)
BEEP=1 //关闭蜂鸣器
Delay_ms(100)
}
/********以下是显示函数********/
void Display()
{
P0=(seg_data[disp_buf[0]])
P2=0x7f
Delay_ms(1)
P0=(seg_data[disp_buf[1]])
P2=0xbf
Delay_ms(1)
}
/前源********以下是主函数********/
main()
{
EA=1EX0=1//允许总中断中断,使能 INT0 外部中断
IT0 = 1 //触发方式为脉冲负边沿触发
IRIN=1 //遥控输入脚置1
BEEP=1RELAY=1 //关闭蜂鸣器和继电器
P0=0xffP2=0xff //P0和P2口置1
Display() //调显示函数
while(1)
{
if(IR_buf[2]==0x02) //02H键(键值码为02H)
RELAY=0 //继电器吸合
if(IR_buf[2]==0x01) // 01H键(键值码为01H)
RELAY=1 //继电器关闭
Display()
}
}
/********以下是外中断0函数********/
void IR_decode() interrupt 0
{
uchar j,k,count=0
EX0 = 0 //暂时关闭外中断0中断请求
delay(20) //延时20*0.14=2.8ms
if (IRIN==1) //等待 IRIN低电平出现
{
EX0 =1 //开外中断0
return //中断返回
}
while (!IRIN) delay(1) //等待IRIN变为高电平,跳过9ms的慧肢态低电平引导码
for (j=0j<4j++) //收集四组数据,即用户码低位、用户码高位、键值数据码和键值数码反码
{
for (k=0k<8k++) //每组数据有8位
{
while (IRIN)//等待IRIN变为低电平,跳过4.5ms的高电平引导码信号。
delay(1)
while (!IRIN) //等待IRIN变为高电平
delay(1)
while (IRIN) //对IRIN高电平时间进行计数
{
delay(1) //延时0.14ms
count++ //对0.14ms延时时间进行计数
if (count>=30)
{
EX0=1 //开外中断0
return //0.14ms计数过长则返回
}
}
IR_buf[j]=IR_buf[j] >>1 //若计数小于6,数据最高位补"0",说明收到的是"0"
if (count>=6) {IR_buf[j] = IR_buf[j] | 0x80} //若计数大于等于6,数据最高位补"1",说明收到的是"1"
count=0 //计数器清0
}
}
if (IR_buf[2]!=~IR_buf[3]) //将键数据反码取反后与键数据码码比较,若不等,表示接收数据错误,放弃
{
EX0=1
return
}
disp_buf[0]=IR_buf[2] &0x0f//取键码的低四位送显示缓冲
disp_buf[1]=IR_buf[2] >>4 //右移4次,高四位变为低四位送显示缓冲
Display() //调显示函数
beep() //蜂鸣器响一声
EX0 = 1 //开外中断0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)