打印

红外解码,为何总是解码不出?

[复制链接]
3405|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ningling_21|  楼主 | 2010-3-22 13:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ningling_21 于 2010-3-22 13:40 编辑

/****************************************************************************************** *函数名称 : void ir_decode(void) mcu=89s52,12Mhz *函数功能描述: 外中断0服务函数-红外解码 *入口参数 : 无 *返回信息 : dcode[0],dcode[1],dcode[2],dcode[3]; ******************************************************************************************/

void ir_decode(void)interrupt 0
{
uchar j,temp,i=0;
EA=0;
//----------------------检测引导码9MS 低电平
for(i=0;i<11;i++)
{ dlay_880us();
if(r_ed)
{
led2=~led2; //解码出错,LED亮
led1=~led1;
return; }
}
while(!r_ed); //----------------------检测引导码4.5MS 高电平
dlay_4d5ms(); //4.5ms
dlay(118); //241us
while(r_ed);
///////////////////////////////////////
for(j=0;j<4;j++) //接收红外数据共4个字节
{
for(i=0;i<8;i++) //每个字节8位
{
while(!r_ed);
dlay_880us(); //延时880US,后判断红外检测引脚状态
if(r_ed) //为1,这个位是1,为0这个位是0
{
temp|=0x80;
dlay_nms(1);//1000us
}
else //为0
{
temp&=0x7f;
}
temp>>=1;
}
dcode[j]=temp;
} //----------------------判断接收到的数据是否正确
if((((dcode[0]|dcode[1])==0XFF))||((dcode[2]|dcode[3])==0XFF))
{
ir_flag=1;
led1=1; //解码正确 ir_flag=1,led熄灭
led2=1;
EA=1;
}
else
{
led1=0;
led2=0;
ir_flag=0; //解码出错时 ir_flag=0;
EA=1;
}
}

相关帖子

沙发
xxdcq| | 2010-3-22 16:55 | 只看该作者
只能解NEC的
意义不大!

使用特权

评论回复
板凳
headwolf_83| | 2010-3-22 17:06 | 只看该作者
遥控器确实是NEC编码吧。别发现是什么RC5。

使用特权

评论回复
地板
ningling_21|  楼主 | 2010-3-22 18:13 | 只看该作者
是NEC 的编码遥控器,但总是解码不到,或解码错误...

使用特权

评论回复
5
ppsen| | 2010-3-23 00:29 | 只看该作者
注意时序

使用特权

评论回复
6
dcp| | 2010-3-23 02:13 | 只看该作者
用定时中断来做时序

使用特权

评论回复
7
ningling_21|  楼主 | 2010-3-23 11:15 | 只看该作者
楼上是说,用定时器中断来检测红外信号?
给个思路...

使用特权

评论回复
8
hxlwjn| | 2010-3-23 11:40 | 只看该作者
你要先知道是哪里出错了。是检测引导码9MS 低电平,还是接收到的数据错误?可以考虑用200us的定时中断来做,不过程序比这个外部中断要复杂些。

使用特权

评论回复
9
ningling_21|  楼主 | 2010-3-23 12:55 | 只看该作者
是解码后的数据错误...

使用特权

评论回复
10
123987| | 2010-3-23 14:21 | 只看该作者
以前做过红外接收。不过我做的很简单。遥控器买现成的电视机上用的,用了一个HS0038做接收头。其实这个东西只要掌握好了时序应该没有啥问题吧。还有你说的解码后数据错误是指校验错误还是就是数据本身错误。如果是前者一个建议:在采样时刻上增加或减少半个采样周期试试看。有时候可能是由于温度等等原因造成发射或接受时刻的偏差。想当初我接收实验做成功后还分别往前和往后调整采样时刻试着使接受数据本身错误。然后前后误差一平均搞出一理想采样时刻。嘿嘿嘿嘿!个人的一点体会,希望有用。

使用特权

评论回复
11
ningling_21|  楼主 | 2010-3-25 18:32 | 只看该作者
或谁有程序,贴出来,共享一下...

使用特权

评论回复
12
ningling_21|  楼主 | 2010-3-28 12:44 | 只看该作者
继续...

使用特权

评论回复
13
woshixinshou| | 2010-3-28 15:04 | 只看该作者
邮购网站那边有个说是终极解码的程序,也是NEC的,用中断计时法,实测实可以的,但是好像有时会死机, LCD_IR_OK.rar (51.16 KB) 贴上来给你看看,

使用特权

评论回复
14
tj_zhaozq| | 2010-3-28 15:50 | 只看该作者
如果用52的话,可以考虑用输入捕获的方法。程序简单,占用的时间资源少。如果你是做产品,可以考虑给你。你现在的这种方法玩玩而已,用在产品里的话,会死的比较惨。

使用特权

评论回复
15
wsjhy1| | 2010-3-29 10:30 | 只看该作者
一定要用C 语言编程吗VB行不

使用特权

评论回复
16
ningling_21|  楼主 | 2010-3-29 13:40 | 只看该作者
本帖最后由 ningling_21 于 2010-3-29 13:41 编辑

THANKS   13楼
回15楼,用汇编写的,已经搞好了,但C写 的就不行,所以来请教大家...

使用特权

评论回复
17
yddjz| | 2017-5-6 01:14 | 只看该作者
还是时序问题

使用特权

评论回复
18
liwen_01| | 2017-5-6 08:59 | 只看该作者
这个不难啊。我写过无数次了。定时扫描啊。

使用特权

评论回复
19
liwen_01| | 2017-5-6 09:01 | 只看该作者
我发一段给你。
void jm_ir()
{
        if(a1==0)
                {if(IR==1)
                        {time_a1++;
                                if(time_a1>=1200)//判断放手高电平50MS
                                {a1=1,time_a1=0;
//value_yhm=0;     //任意遥控器。sbf
//value_sgm=0;
//value_yhfm=0;
                                }
                        }
                else{time_a1=0;}
                }


if(a1==1)
        {
                if(IR==0)
                        {time_a2++;
                                if(time_a2>=70)//9MS低电平时间
                                        {time_a2=0;
                                        a1=2;
                                        d1=0;
                                        }
                        }
                else{time_a2=0;}
        }


if(a1==2)
        {
                if(IR==1)
                {time_a2++;
                        if(time_a2>=30) //3.5MS
                        {time_a2=0;
                                a1=3;
//d1=0;
                        }
                }
                else{time_a2=0;}
        }

        if(a1==3)
                {
                        if(IR==0)
                                {
                                a1=4;
                                }
                }
        if(a1==4)
                {
                        if(IR==1)
                                {
                                a1=5;
                                }
                }
        if(a1==5)
                {
                        if(IR==1)
                                {time_a2++;
                                }
                        if(IR==0){a1=6;}
                }
        if(a1==6)
                {d1++;
                        if(d1>=1&&d1<=8)
                        {
                        if(time_a2>=8){value0<<=1,value0|=0x01;}  
                        else{value0<<=1;}
                        }
                       
                        if(d1>=9&&d1<=16)
                        {
                        if(time_a2>=8){value1<<=1,value1|=0x01;}  
                        else{value1<<=1;}
                        }

                        if(d1>=17&&d1<=24)
                        {
                        if(time_a2>=8){value2<<=1,value2|=0x01;}  
                        else{value2<<=1;}
                        }
                        a1=4;
                        time_a2=0;
                        if(d1>=24)
                        {a1=0;
                        value_yhm=value0;  //用户码,
                        value_yhfm=value1;//用户反码,
                        value_sgm=value2;//数据码;
                        value0=0;
                        value1=0;
                        value2=0;
                        d1=0;
                        }
                }
}

使用特权

评论回复
20
JerryWu75| | 2017-5-6 11:00 | 只看该作者
本帖最后由 JerryWu75 于 2017-5-6 11:09 编辑

这个一般用中断+脉宽捕捉会比较好, 例如一个红外脉冲序列:____|====, _表示低电平,=表示高电平。我们可以认为下降沿表示一个位接收结束。在软件中我们需要一个计数器计算低电平的宽度,一个计数器计算高电平的宽度,然后在下降沿中断中对脉冲宽度进行判断。

void fillISR()
{
    if(等待引导码){
        if(lowcnt和highcnt是引导码){
            状态机改为等待数据;
        } else {
            状态机复位,等待引导码;
        }
    } else if(等待数据){
        if(lowcnt和highcnt是数据0或者1){
            接收数据;
            if(数据接收完成){
                通知应用程序接收到数据;
                状态机复位,等待引导码;
            }
        } else {
            状态机复位,等待引导码;
        }
    }
    lowcnt=0,highcnt=0;
}
void TimeISR()
{
    if(低电平){
       lowcnt+=1;
    } else if(高电平){
        highcnt+=1;
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5013

主题

17716

帖子

51

粉丝