#include<reg51.h>
//根据自己的接线来改
sbit IRIN = P3^2; //红外接收器数据线
sbit led = P3^7; //指示灯
////////////////////////////////////////////
//定义数组IRCOM,分别装解码后得到的数据
//IRCOM[0] 低8位地址码
//IRCOM[1] 高8位地址码
//IRCOM[2] 8位数据码
//IRCOM[3] 8位数据码的反码
/////////////////////////////////////////////
#define uchar unsigned char
#define uint unsigned int
uchar IRCOM[4]=0;
bit flag=0;
/********************/
void delay014ms(unsigned char x); //x*0.14MS
void IR_init(void);
void delay014ms(unsigned char x) //x*0.14MS STC10F04延时约0.15MS
{
unsigned char i;
while(x--)
{
for (i = 0; i<125; i++) //13
{;}
}
}
///////////////
//初始化
////////////
void IR_init(void)
{
EA=1;
EX0=1; //允许总中断中断,使能 INT0 外部中断
IT0=1; //触发方式为脉冲负边沿触发
IRIN=1; //I/O口初始化
}
//////////
//解码过程
//////////////
void IR_CODE(void) interrupt 0 //在外部中断子程序中解码
{
unsigned char j,k,N=0;
EX0 = 0;
delay014ms(15);
if (IRIN==1)
{ EX0 =1;
return;
} //确认IR信号出现
while (!IRIN) //等IR变为高电平,跳过9ms的前导低电平信号。
{delay014ms(1);}
for (j=0;j<4;j++) //收集四组数据
{
for (k=0;k<8;k++) //每组数据有8位
{
while (IRIN) //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
{delay014ms(1);}
while (!IRIN) //等 IR 变为高电平
{delay014ms(1);}
while (IRIN) //计算IR高电平时长
{
delay014ms(1);
N++;
if (N>=30)
{ EX0=1;
return;} //0.14ms计数过长自动离开。
} //高电平计数完毕
IRCOM[j]=IRCOM[j] >> 1; //数据最高位补"0"
if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //数据最高位补"1"
N=0;
}
}
if (IRCOM[2]!=~IRCOM[3]) //不等的话表示解码失败
{
IRCOM[4]=0;
EX0=1;
return;
}
flag = !flag;//pro();//解码成功后运行的程序
//如果解码成功,flag就取一次,在主程序中,就根据flag的值来闪灯,
EX0=1;
return;
}
//主程序
void main(void)
{
IR_init( ); //初始化外部中断0
flag = 0;
while(1)
{
led=flag; //正确接收后的led闪灯的现像。
//if(flag)
// {
// led =!led;
// delay014ms(1);
// }
// else led=1;
}
}
为什么用STC12LE5A60S2就是不能解码呢???????????????大神求救呀
别用delay延时、while等待电平变化……去解码,修改麻烦也容易卡机,
NEC解码很简单,用外部中断(下降沿) + 定时器 检测信号周期,状态机方式解码,
想省资源的话一个定时器就行,先用定时器外部计数扩展成外部中断,有信号触发中断后再计数解码
一周热门 更多>