有一个问题,是关于红外线接收的,在外部中断函数里出错了,功能是按下遥控器的一个键,在数码管上显示相应数字,NEC协议,引导码是9ms高电平+4.5ms低电平,但在外部中断里判断接收到的引导码中的高电平持续时时间时出错了,结果就是数码管只是显示默认的值
L1灯总是被点亮,说明后面读取用户根本就没有进行,但我又找不到我的获取电平持续时间函数错在哪(晶振11.0592MHZ),求教
#include<reg52.h>
#include<intrins.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long int
#define DataPort P0
uint8 code DuanMa[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴数码管段选码表,无小数点
sbit IR_RECEIVE=P3^2;
sbit dula=P2^6;
sbit wela=P2^7;
sbit L0=P1^0;
sbit L1=P1^1;
sbit L2=P1^2;
sbit L3=P1^3;
sbit L4=P1^4;
sbit L5=P1^5;
sbit L6=P1^6;
sbit L7=P1^7;
bit irflag=0;
uint8 ircode[4];
uint8 T0RH=0;
uint8 T0RL=0;
uint8 i,j;
uint16 time;
uint8 byt;
void InitInfrared();//红外线初始化
uint8 GetHighTime();//读高电平持续时间,实际发过来的是低电平
uint8 GetLowTime();//获取低电平持续时间,实际发过来的是高电平
void ConfigTimer0(uint8 ms);
void LedScan();//数码管动态扫描刷新函数,需在定时中断中调用
void main()
{
EA=1;
InitInfrared();
ConfigTimer0(1); //定时器0初始化
PT0=1; //定义定时器0为高优先级中断
DataPort=0xfe; //取位码 第一位数码管选通,即二进制1111 1110
wela=1; //位锁存
wela=0;
while(1)
{
}
}
void InitInfrared()//红外线初始化
{
IR_RECEIVE=1;
TMOD&=0X0F;
TMOD|=0X10;
TR1=0;
ET1=0;
IT0=1;
EX0=1;
}
uint8 GetHighTime()//读高电平持续时间,实际发过来的是低电平
{
TH1=0;
TL1=0;
TR1=1;
while(IR_RECEIVE)//避免没有收到起始信号而使程序一直停滞在这一步,需有个定时
{
if(TH1>0X40)
{
break;
}
}
TR1=0;
return(TH1*256+TL1);//每个TH1代表256个TL1,1.09*(TH1*256+TL1)
}
uint8 GetLowTime()//获取低电平持续时间,实际发过来的是高电平
{
TH1=0;
TL1=0;
TR1=1;
while(!IR_RECEIVE)
{
if(TH1>0X40) //远远超过了9ms
{
break;
}
}
TR1=0;
return(TH1*256+TL1);
}
void INT0_Interrupt() interrupt 0
{
L0=0;
time=GetLowTime(); //获取低电平持续时间
if((time<7833)||(time>8755))// 8537-9542us,9ms误差允许
{
L1=0;
IE0=0;
return;
}
time=GetHighTime();//获取高电平持续时间
if((time<3686)||(time>4608))//4.5ms误差允许
{
L2=0;
IE0=0;
return;
}
for(i=0;i<4;i++)
{
if(i==0)L3=0;
if(i==1)L4=0;
if(i==2)L5=0;
if(i==3)L6=0;
for(j=0;j<8;j++)
{
time=GetLowTime();
if((time<313)||(time>718))//341-782,560us误差允许,发送过来的0和1都是从560us的高电平开始
{
IE0=0;
return;
}
time=GetHighTime();
if((time>313)&&(time<718))//如果560us(上一句),检测时间,与之前的560us合起来判断是0还是1,过后341-782,最好是560,如果是这种情况,则发送过来的则为0
{
byt>>=1;
}
else if((time>1345)&&(time<1751))//高电平持续时间1466-1908,最好是1690,发送过来的是1
{
byt>>=1;
byt|=0X80;
}
else
{
IE0=0;
return;
}
L7=0;
}
ircode[i]=byt;
irflag=1;
}
IR_RECEIVE=1;
IE0=0;
}
void ConfigTimer0(uint8 ms)
{
uint32 tmp;
tmp=11059200/12;
tmp=(tmp*ms)/1000;
tmp=65536-tmp;
tmp=tmp+18;//补偿中断响应延时造成的误差
T0RH=(uint8)(tmp>>8);
T0RL=(uint8)tmp;
TMOD&=0XF0;//清除T0的控制位
TMOD|=0X01;//配置T0为模式1
TH0=T0RH; //加载T0的重载值
TL0=T0RL;
ET0=1;
TR0=1;
}
void LedScan()//数码管动态扫描刷新函数,需在定时中断中调用
{
if(irflag)
{
irflag=0;
switch(ircode[2])
{
case 0X0C:DataPort=DuanMa[1];break;
case 0X18:DataPort=DuanMa[2];break;
case 0X5E:DataPort=DuanMa[3];break;
case 0X08:DataPort=DuanMa[4];break;
case 0X1C:DataPort=DuanMa[5];break;
case 0X5A:DataPort=DuanMa[6];break;
case 0X42:DataPort=DuanMa[7];break;
case 0X52:DataPort=DuanMa[8];break;
case 0X49:DataPort=DuanMa[9];break;
}
}
}
void T0_Interrupt() interrupt 1
{
TH0=T0RH;
TL0=T0RL;
LedScan();
}