********************************************************************************
* 描述: *
* 遥控键值读取器*
* 数码管显示, P0口为数码管的数据口 *
* *
********************************************************************************
遥控键值解码-数码管显示*
********************************************************************************/
#include <reg51.h>
#include <intrins.h>
void IR_SHOW()
void delay(unsigned char x)//x*0.14MS
void delay1(unsigned char ms)
void beep()
sbit IRIN = P3^2
sbit BEEP = P3^7
sbit RELAY= P1^3
sbit GEWEI= P2^7
sbit SHIWEI= P2^6
unsigned char IRCOM[8]
unsigned char code table[16] =
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e}
main()
{
IE = 0x81 //允许总中断中断,使能 INT0 外部中断
TCON = 0x1 //触发方式为脉冲负边沿触发
delay(1)
IRIN=1
BEEP=1
RELAY=1
for()
{
IR_SHOW()
}
} //end main
void IR_IN() interrupt 0 using 0
{
unsigned char i,j,k,N=0
EA = 0
I1:
for (i=0i<4i++)
{
if (IRIN==0) break
if (i==3) {EA =1return}
}
delay(20)
if (IRIN==1) goto I1 //确认IR信号出现
while (!IRIN)//等 IR 变为高电平
{delay(1)}
for (j=0j<4j++)
{
for (k=0k<8k++)
{
while (IRIN)//等 IR 变为低电平
{delay(1)}
while (!IRIN) //等 IR 变为高电平
{delay(1)}
while (IRIN) //计算IR高电平时长
{
delay(1)
N++
if (N>=30) {EA=1return}
}
IRCOM[j]=IRCOM[j] >>1
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80}
N=0
}//end for k
}//end for j
if (IRCOM[2]!=~IRCOM[3]) {EA=1return}
IRCOM[5]=IRCOM[2] &0x0F
IRCOM[6]=IRCOM[2] &0xF0
IRCOM[6]=IRCOM[6] >>4
beep()
EA = 1
}
void IR_SHOW()
{
P0 = table[IRCOM[5]]
GEWEI = 0
SHIWEI = 1
delay1(4)
P0 = table[IRCOM[6]]
SHIWEI = 0
GEWEI = 1
delay1(4)
}
void beep()
{
unsigned char i
for (i=0i<100i++)
{
delay(5)
BEEP=!BEEP
}
BEEP=1
}
void delay(unsigned char x)//x*0.14MS
{
unsigned char i
while(x--)
{
for (i = 0i<13i++) {}
}
}
void delay1(unsigned char ms)
{
unsigned char i
while(ms--)
{
for(i = 0i<120i++)
{
_nop_()
_nop_()
_nop_()
_nop_()
}
}
}
下面是一个用C写的遥控器程序.能在数码管上显示键码.#include <reg52.h>
#define c(x) (x*110592/120000)
sbit Ir_Pin=P3^3
unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E} //共阳极数码显示码0-F.
unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7}
unsigned char Led_Buf[4]//显示缓冲区
char Led_Index //位选
unsigned char Ir_Buf[4]//用于保存解码结果
//==============================================================
//数码管扫描
timer0() interrupt 1 using 1
{
TL0=65536-1000
TH0=(65536-1000)/256//定时器0设定约1000us中断一次,用于数码管扫描
P0=0xff
P2=Led_Sel[Led_Index] //位选
P0=Led_Tab[Led_Buf[Led_Index]] //段选
if(++Led_Index>3) Led_Index=0 //四个扫描完了,到第一个数码管
}
//==============================================================
unsigned int Ir_Get_Low()
{
TL1=0
TH1=0
TR1=1
while(!Ir_Pin &&(TH1&0x80)==0)
TR1=0
return TH1*256+TL1
}
//=============================================================
unsigned int Ir_Get_High()
{
TL1=0
TH1=0
TR1=1
while(Ir_Pin &&(TH1&0x80)==0)
TR1=0
return TH1*256+TL1
}
//==============================================================
main()
{
unsigned int temp
char i,j
Led_Index=1
TMOD=0x11
TL0=65536-1000
TH0=(65536-1000)/256//定时器0设定约1000us中断一次,用于数码管扫描
EA=1
ET0=1
TR0=1
Led_Buf[0]=0
Led_Buf[1]=0
Led_Buf[2]=0
Led_Buf[3]=0//显示区设成0
do{
restart:
while(Ir_Pin)
temp=Ir_Get_Low()
if(temp<c(8500) || temp>c(9500)) continue//引导脉冲低电平9000
temp=Ir_Get_High()
if(temp<c(4000) || temp>c(5000)) continue//引导脉冲高电平4500
for(i=0i<4i++) //4个字节
for(j=0j<8j++) //每个字节8位
{
temp=Ir_Get_Low()
if(temp<c(200) || temp>c(800)) goto restart
temp=Ir_Get_High()
if(temp<c(200) || temp>c(2000)) goto restart
Ir_Buf[i]>>=1
if(temp>c(1120)) Ir_Buf[i]|=0x80
}
Led_Buf[0]=Ir_Buf[2]&0xf
Led_Buf[1]=(Ir_Buf[2]/16)&0xf
Led_Buf[2]=Ir_Buf[3]&0xf
Led_Buf[3]=(Ir_Buf[3]/16)&0xf//显示结果
}while(1)
}