📄 irda.c
字号:
/********************************************************************
* *
* 程序名:红外线遥控解码程序(芯片 HT6221) 单发中断法 *
* *
* 设 计 人:牛余朋 *
* *
* 日 期:2005年11月24日 *
* *
* 版本:1.0 *
*********************************************************************/
#include <REGX51.H>
unsigned char keynumber=0xff;//定义按键值变量
void Delay(void);
void Irda(void);
void beep(void);
dispaly(unsigned char keynum);
void delay1ms(unsigned int count);
/*分别存放红外线译码后的数据*/
unsigned char data e1 _at_ 0x1A; /*存放低8位地址码*/
unsigned char data w1 _at_ 0x1B; /*存放高8位地址码*/
unsigned char data e2 _at_ 0x1C; /*存放8位数据码*/
unsigned char data w2 _at_ 0x1D; /*存放8位数据反码*/
//sbit IrInput=P3^2; //红外线输入引脚,可自定义
unsigned char LEDdata[]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60};//0-9段码
/*代表遥控器上的1--28按键红外码值*/
unsigned char Irda_data[]={0x5f,0x50,0x5d,0x44,0x41,0x0a,0x42,0x46,0x47,0x49,
0x05,0x06,0x07,0x09,0x45,0x03,0x5c,0x1e,0x5e,0x02,
0x58,0x1a,0x5b,0x01,0x1b,0x59,0x5a,0x18};//1--28
/*********************主程序***************************/
void main(void)
{
unsigned char i;
IT0 = 1; //INT0下降沿有效
EX0 = 1; //开INT0中断;
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
EA = 1; //允许CPU中断
while(1)
{
if(keynumber!=0xff)
{
for(i=0;i<10;i++)
dispaly(keynumber);
keynumber=0XFF;
}
}
}
/*******************红外线解码子程序*******************/
void Irda(void)
{
#pragma asm
SB:
MOV R4,#8 ;8毫秒为高电平错误
SBA:
MOV R5,#250
SBB:
JB P3.2,SXB1
DJNZ R5,SBB
DJNZ R4,SBA
MOV R4,#2
JMP SBC
SXB1:
MOV R5,#5
SXB2: ;去掉20US的尖峰干扰信号
JNB P3.2,SBB
DJNZ R5,SXB2
RET
SBC:
MOV R5,#250
SB1:
JB P3.2,SB2 ;2MS内不为高电平错误(监测9MS的低电平引导码)
DJNZ R5,SB1
DJNZ R4,SBC
RET
SB2: ;去掉20US的尖峰干扰信号
MOV R5,#5
SB2_A:
JNB P3.2,SB1
DJNZ R5,SB2_A
MOV R4,#3
SB2_1:
MOV R5,#250
SB3: ;监测4.5MS高电平,如3MS内出现低电平错误
JNB P3.2,SXC
DJNZ R5,SB3
DJNZ R4,SB2_1
MOV R4,#2
JMP SB3_1
SXC: ;去掉20US的尖峰干扰信号
MOV R5,#5
SXC1:
JB P3.2,SB3
DJNZ R5,SXC1
RET
SB3_1: ;监测4.5MS高电平,如5MS内不为低电平错误
MOV R5,#250
SB3_2:
JNB P3.2,SB4
DJNZ R5,SB3_2
DJNZ R4,SB3_1
RET
SB4: ;去掉20US的尖峰干扰信号
MOV R5,#5
SB4_1:
JB P3.2,SB3_2
DJNZ R5,SB4_1
MOV R1,#1AH ;设定1AH为起始RAM区
MOV R2,#4
PP: MOV R3,#8
JJJJ:
MOV R5,#250
JJJJ2: ;1MS内不为低电平错误
JB P3.2,JJJJ3
DJNZ R5,JJJJ2
RET
JJJJ3:
LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态
MOV C,P3.2 ;将P3.7引脚此时的电平状态0或1存入C中
JNC UUU ;如果为0就跳转到UUU
MOV R5,#250
JJJJ4:
JNB P3.2,UUU
NOP
DJNZ R5,JJJJ4
RET
UUU: MOV A,@R1 ;将R1中地址的给A
RRC A ;将C中的值0或1移入A中的最低位
MOV @R1,A ;将A中的数暂时存放在R1中
DJNZ R3,JJJJ ;接收地址码的高8位
INC R1 ;对R1中的值加1,换成下一个RAM
DJNZ R2,PP ;接收完16位地址码和8位数据码和8位数据反码,存放在1AH/1BH/1CH/1DH的RAM中
YS1: MOV R4,#20 ;延时子程序1,精确延时882微秒
D1: MOV R5,#20
DJNZ R5,$
DJNZ R4,D1
RET
YS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒
D2: MOV R5,#235
DJNZ R5,$
DJNZ R4,D2
RET
YS3: MOV R4,#2 ;延时程序3,精确延时1000微秒
D3:MOV R5,#248
DJNZ R5,$
DJNZ R4,D3
RET
#pragma endasm
}
/*****************外部中断0服务程序*********************/
void int0_int(void) interrupt 0
{
unsigned char i;
EX0 = 0;
Irda();
if((e1==~w1)&&(e2==~w2)) //判断系统码与系统反码、用户码与用户反码是否相同
{
P1=e2;
for(i=0;i<28;i++)
{
if(e2==Irda_data[i])
{
keynumber=i;
beep( );
}
}
}
e1=e2=w1=w2=0; //防止下一次误判断
EX0 = 1;
}
void beep(void)
{
P3_3=0;
delay1ms(1);
P3_3=1;
}
/*************************延时1毫秒子程序*****************************/
void delay1ms(unsigned int count)//晶振12M,延时ms
{
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++)
;
}
dispaly(unsigned char keynum)
{
//unsigned char i;
// for(i=0;i<5;i++)
// {
P0=LEDdata[(keynum+1)%10];
P2=0xfb;
delay1ms(5);
P0=LEDdata[(keynum+1)/10];
P2=0xfd;
delay1ms(5);
P2=0xff;
// }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -