这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 红外解码的异常问题,求帮助

共7条 1/1 1 跳转至

红外解码的异常问题,求帮助

菜鸟
2011-03-29 16:16:37     打赏
最近在用51做红外遥控器的解码实验,出现异常的现象,异常现象如下:

解码程序下载进去后,当按下遥控器不同按键时,数码管都显示解码字段都一样,都显示

1A-dc,也就是说遥控器的所有按键的编码都一样,都为1A-dc。(我晕了,这不可能吧,要是所有按键的编码都一样,那做一个按键就行了。。。)

其次,当按下按键的时间较长时,数码管又都显示FF-FF


实验材料如下:

遥控器不知道是什么芯片编码的,遥控器上显示字样:57L5,58A3,54B4,55K2四合一。

红外线接收头是tl1838,接收头的数据引脚连接51的P3^3(P3^3是51的外部中断1引脚)



解码程序如下,用中断1解码,都有注释,很好读,希望大家能帮助分析出现此种现象可能原因,谢谢啦。



#include<reg52.h> //52单片机头文件,一般不要改动,里面包含特殊功能寄存器的定义
#include<intrins.h>

sbit hwx=P3^3; //定义红外接收脚,

code unsigned char table[]=
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};
//共阴数码管 0-9 a-f - 表
unsigned char l_tmpdate[8]={0,0,0x10,0,0};//显示管数据

unsigned char l_lhj[66]; //定义66位数组变量来存储接收的时间参数
void delay();//延时子函数
void display(unsigned char *lp,unsigned char lc);//数字的显示函数;lp为指向数组的地址,lc为显示的个数

void main(void) //入口函数
{
EA=1; //首先开启总中断
EX1=1; //开启外部中断 1
IT1=1; // 设置成 下降沿触发方式
while(1){ //循环显示,接收都由中断处理
display(l_tmpdate,5);
}

}
void display(unsigned char *lp,unsigned char lc)//显示
{
unsigned char i; //定义变量
P2=0; //端口2为输出
P1=P1&0xF8; //将P1口的前3位输出0,对应138译门输入脚,全0为第一位数码管
for(i=0;i<lc;i++){ //循环显示
P2=table[lp[i]]; //查表法得到要显示数字的数码段
delay(); //延时
P2=0; //清0端口,准备显示下位
if(i==7) //检测显示完8位否,完成直接退出,不让P1口再加1,否则进位影响到第四位数据
break;
P1++; //下一位数码管
}
}
void delay(void) //空5个指令
{
unsigned char i=13;
while(i)
i--;
}
void hongwai(void) interrupt 2 //外部中断 1 ,INT1(P3^3)连接红外线接收IC数据脚
{
unsigned char i,j,tmp;
EX1=0;
// hwx=1;
j=33; //传送一组数包括引导码1位,地址码8位加反码8位,指令码8位加反码8位,总共33位
i=0; //从第一维数组开始
tmp=100; //加八延时,
while(tmp){
tmp--;
}
if(hwx){ //然后再检测红线接收脚是有数据招收,有继续,没有则退出
EX1=1;
return;
}
while(j){ //循环接收33位数据,为何我们用到66位数组,我们可以不接收高电平时间常数,只接低电平常数就
//可以判断1或0了,在这里我们都接收,为串口调试软件接收计算波形
//还有一点要知道,接收波形是反向,在没有接收时端口为高电平
tmp=0;
l_lhj[i]=1; //时间量从1开始
while(!hwx){ //检测高低电平的变化
l_lhj[i]++; //没变继续加1
delay(); //加入延时,是因为我们采用8位二进来存储,如果不加延时,时间量将计满
tmp++; //此变量为防止干扰带来的死循环
if(tmp==250)
break;
}
i++;
tmp=0;
l_lhj[i]=1; //时间量从1开始
while(hwx){ //检测高低电平的变化
l_lhj[i]++; //没变继续加1
delay(); //同上
tmp++;
if(tmp==250)
break;
}
i++;
j--;
}
i=255; //加入循环延时,抗干扰
while(i){
tmp=255;
while(tmp){
P2=0XF0;
tmp--;
}
i--;
}
tmp=0;
for(i=3;i<19;i++,i++){ //处理地址位,对低电平时间数据的数理,这里我们只处理地址码和指令码,引导码和反码我们就忽略
tmp>>=1; //右移一位,接收低电平在前
if(l_lhj[i]>30) //检测低电平时间超过30就确认为1
tmp+=0x80;
}
l_tmpdate[0]=tmp/16; //分开2位以16进制显示
l_tmpdate[1]=tmp%16;
tmp=0;
for(i=35;i<51;i++,i++){ //同上,这里处理指令位
tmp>>=1;
if(l_lhj[i]>30)
tmp+=0x80;
}
l_tmpdate[3]=tmp/16;
l_tmpdate[4]=tmp%16;
EX1=1;
}



关键词: 红外     解码     异常     问题     帮助     显示     接收     unsi    

菜鸟
2011-03-29 18:27:01     打赏
2楼
也就是说,我在中断里只负责快速的接收编码,处理编码是留在中断外来做,是这样吗?

菜鸟
2011-04-02 09:27:48     打赏
3楼
应该不是吧。因为这样做只是减少中断服务子程序的代码量,执行时间并没有减少。
应该是在中断服务子程序里只负责接收红外信号。

菜鸟
2011-04-02 09:37:25     打赏
4楼
遥控器上的字样:57L5,58A3,54B4,55K2四合一是什么意思啊?
该遥控器是是NEC的编码吗?
大家提点意见。。。。

菜鸟
2011-04-02 09:45:12     打赏
5楼

//该遥控器是NEC编码的,在中断里我这样接收红外信号,是否可行

uchar chubus[33],用于接收时间常数

void ex1() interrupt 2//外部中断1接收红外数据
{
 static bit startflag;//开始接收标志位
 static uchar i;

 if(startflag)
 {
  if(timedata<60&&timedata>=36)  i=0;//一位引导码 9+4.5毫秒
  chubus[i]=timedata;   //timedata用定时器方式1计时,0.25毫秒中断一次
  timedata=0;
  i++;
  if(i==33)
  {
  overflag=1;
  startflag=0;
  i=0;
  }  
 }
 else
 {
  startflag=1;
  timedata=0;
 }
}


菜鸟
2011-04-02 09:55:30     打赏
6楼
我明白了。不过还有个小问题:就是我一进中断服务子程序就关闭外部中断1了,也就是不响

应中断了,然后我在该中断服务子程序中首先先负责接收该按键编码所有位时间常量,接收完

后,我才处理数据,这样可行吗?

菜鸟
2011-04-04 15:48:58     打赏
7楼

已调试好,谢谢大家帮助。


共7条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]