最近在做一个红外解码的程序,要求解码红外并将解码结果通过串口输出,初步构思是先不管红外的标准,直接将接收到的高低电平状态及持续时间输出,当接收到红外时,触发外部中断0,中断函数如下:
- void to() interrupt 0//解码输出 外部中断0
{
uchar t;
t = IR;
TH0 = 0;
TL0 = 0;
TR0 = 1;
EX0 = 0;//故意关闭外部中断0
while(1)//直到输出完毕
{
LED = ~LED;//输出指示灯
t = IR;
TH0 = 0;
TL0 = 0;
TR0 = 1;//开启定时器0,开始计时
while(t == IR);//记录电平持续时间
TR0 = 0;
if((t == 1)&&((TH0*256+TL0)>50000))//如果电平持续时间
break;
dateSend(t);//输出高低电平状态
dateSend(TH0);
dateSend(TL0);//输出电平持续时间
}
dateSend(0xff);//为了判断中断运行完所加的
// EX0 = 1;故意注释的,只检测一次
}
复制代码
发送数据函数如下:
- void dateSend(uchar tempDate)
{
SBUF = tempDate;//发送数据
while(!TI);//未发送完毕
TI = 0;
}
复制代码但是问题是每次当我按下一次遥控器按钮后,程序会停止在中断里,因为我主程序调用了一个数码管动态扫描函数,8个数码管显示0,但我按一次键,只有一个数码管显示0,并且输出结果里没有我在中断函数里最后加的0xff,更头疼的是,我在中断里一开始就关闭了外部中断0,当第一次输出完毕后再次按下遥控器,串口仍然有输出数据,直到重复按几次后才会看到输出0xff,并且再按键也无反应,既推出中断,输出结果如下:
- [接收]00 20 D3 01 04 1E 01 00 D6 01 00 EE 01 04 C0 01 04 D2 01 04 DE 01 04 D2 01 00 CA 01 04 F0 01 00 EE 01 00 A0 01 00 BE 01 00 D6 01 00 EE 01 04 B4 01 85 C6 00 14 56 [接收]01 6B B8 00 14 E0 01 05 08 01 00 A0 01 00 B8 01 04 CC 01 04 D2 01 04 D8 01 04 CC 01 00 C4 01 04 F0 01 00 E2 01 00 A0 01 00 B8 01 00 D0 01 00 E8 01 04 AE [接收]01 85 A8 00 14 8C [接收]01 AE 30 00 14 FE 01 05 20 01 00 B8 01 00 D0 01 04 E4 01 04 EA 01 04 F6 01 04 E4 01 00 E2 01 05 08 01 00 A0 01 00 B8 01 00 D0 01 00 E8 01 00 A0 01 04 C6 01 85 BA 00 14 A4 [接收]FF
复制代码接收数据 3位一组,如打头的00 20 D3 ,说明是低电平,持续时间为0x20d3*1.085约等于9ms,11.0592的晶振,但是问题是仔细看后面就发现输出结果只有01的持续时间,就是只有高电平持续时间,由于红外一体化接收输出与发送反相,因此就是说数据0与1中的高电平没有记录输出,而这两者都是0.56ms,因此我觉得是不是因为单片发送数据的时间要大于这段时间,因此导致不能检测出来?还有上面括号中有5个接受最后才是FF,说明我按了5次遥控器才最后输出FF跳出中断,这是为什么?新手,望高手指点一下,谢谢。
此帖出自
小平头技术问答
这句是判断高电平时间的,因为平时没有接收到红外时外部中断0那个引脚是高电平,因此当高电平持续较长时间时就认为解码完毕
建议你开个缓冲全存,完后再发
另外定时器可以先开...
一周热门 更多>