搜索
bottom↓
回复: 7

【已解决】51简单的红外程序,出了邪门了,大家都来帮帮...

[复制链接]

出0入0汤圆

发表于 2012-4-26 20:06:13 | 显示全部楼层 |阅读模式
本帖最后由 512826028 于 2012-4-26 23:59 编辑

    我是今天买了一个红外的遥控器,写了一个红外接收的程序。一开始,解码都正常。后来,我在中断中添加一个加一,和减一的代码。但是,结果出人意料,程序会自动运行两边。本意是这样的,按下一个键,表示加一,计数增加一。程序放在中断中进行,进入中断就关闭了EA,应该不会再自动重复进入中断吧?我先给大家上中断部分的程序。
/************************中断0解码服务子程序**********************/
void int0(void) interrupt 0      
{
        EA=0;
        irdalow = IRDA_JIEMA();//得到解码的数据 这个数据只包括数据码!
        Delay_ms(255);//
        Delay_ms(255);//
        if(irdalow == 0x0df2) //如果按下的向上,就减一
                {
                Delay_ms(200);
                if(SCREEN_MUSIC>0)
                        SCREEN_MUSIC = SCREEN_MUSIC-1;                //向上翻
                }
        if(irdalow == 0x0ef1)//如果按下的是向下,就加一
                {
                Delay_ms(200);
                SCREEN_MUSIC = SCREEN_MUSIC+1;                //向下翻
                if(SCREEN_MUSIC>7)  //不可以超出7
                        SCREEN_MUSIC=7;
                LCD12864S_WCOM(0x86);//这句和下句是在LCD的指定位置显示出SCREEN_MUSIC的值。+0x30是转换成字符。
                LCD12864S_WDATA(0x30+SCREEN_MUSIC);
                }
        Delay_ms(255);//       
        Delay_ms(255);//       
        SCREEN_DISP();//刷新显示函数
        SCREEN_GUANGBIAO(SCREEN_MUSIC-SCREEN_ROW);//这个是控制光标位置的。移动光标。
        Delay_ms(255);//
        Delay_ms(255);//       
        EA=1;
}
    我在说一下问题。这个中断程序就是这样。运行起来之后,我按下向下键,就会自动增加2,而不是一。为了能看出变化,我添加了LCD显示SCREEN_MUSIC值的语句,同时,在中断的多个地方,做了大量的延时处理,最后看出了程序执行的过程。
    程序是直接运行了两边!按下“向下键”之后,在LCD上可以看到显示的SCREEN_MUSIC从0显示为1,然后移动一下光标。然后,LCD上又看到SCREEN_MUSIC的值变为2,又移动了一次光标。
    这样,按下一次,程序就是增加的二!而且是从头到尾的执行了两遍!!
    我真的不知道这个事什么问题导致的。希望大家都能帮帮。。。。。。。。。。。谢谢啦!

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2012-4-26 20:24:35 | 显示全部楼层
现在的感觉就是,按下一次之后,好像就是产生了两次中断。不知道怎么解决这个问题。延时再长,但是,都是运行两边。很是郁闷。。。

出0入0汤圆

发表于 2012-4-26 21:27:58 | 显示全部楼层
用的什么格式遥控码,“一开始,解码都正常”,你是怎么知道正常的?

出0入0汤圆

发表于 2012-4-26 22:12:47 | 显示全部楼层
向上翻/向下翻的动作不要放在中断代码里面

出0入0汤圆

发表于 2012-4-26 22:23:34 | 显示全部楼层
本帖最后由 HeP028 于 2012-4-26 22:24 编辑

那你把中断最后的EA = 1先去掉测试嘛!先干一次看对不对塞!
另外把你红外读取的函数展览出来塞!指不定问题出那里面呢!

出0入0汤圆

 楼主| 发表于 2012-4-26 23:51:43 | 显示全部楼层
sf49ers 发表于 2012-4-26 21:27
用的什么格式遥控码,“一开始,解码都正常”,你是怎么知道正常的?

这个之前是先用LCD显示出所有的按键的用户码,做了一个表格。然后才进行的这一步。

出0入0汤圆

 楼主| 发表于 2012-4-26 23:54:47 | 显示全部楼层
HeP028 发表于 2012-4-26 22:23
那你把中断最后的EA = 1先去掉测试嘛!先干一次看对不对塞!
另外把你红外读取的函数展览出来塞!指不定问 ...

这个是拿的别人的程序改的。这个是源代码。
/************************中断0解码服务子程序**********************/
void int0(void) interrupt 0      
{

EA=0;

for(k=0;k<10;k++)
   {
           Delay0_9ms();
    if (IRDATA==1)         //如果0.9ms后IRDATA=1,说明不是引导码
                {k=10;break;}
    else if(k==9)           //如果持续了10×0.9ms=9ms的低电平,说明是引导码
                {
                        while(IRDATA==0);
                                Delay4_5ms();        //跳过持续4.5ms的高电平

                        for(i=0;i<4;i++)       //分别读取4个字节
                                {for(j=1;j<=8;j++)      //每个字节8个bit的判断
                                        {
                                                while(IRDATA==0);       //等待上升沿
                                                Delay0_9ms();      //从上升沿那一时刻开始延时0.9ms,再判断IRDATA
                                                if(IRDATA==1)     //如果IRDATA是"1",则向右移入一位"1"
                                                {
                                                        Delay1ms();
                                                        CodeTemp=CodeTemp|0x80;
                                                        if(j<8) CodeTemp=CodeTemp>>1;
                                                }
                                                else if(j<8)
                                                  CodeTemp=CodeTemp>>1;//如果IRDATA是"0",则向右移一位,自动补"0"
                                        }
                                        hongwaicode=CodeTemp;
                                        CodeTemp=0;
                                }
                }
        }
recodehigh=hongwaicode[0]<<8|hongwaicode[1];
recodelow=hongwaicode[2]<<8|hongwaicode[3];
recode=recodehigh;
recode=recode<<16;
recode=recode|recodelow;
//显示出读出的数据
// printf("%#X\n",hongwaicode);
// printf("%#X\n",recodehigh);
// printf("%#X\n",recodelow);
// printf("%#X\n",recode);
//LCD12864S_WSTR(1,0,hongwaicode);
IRDA_DISP();
EA=1;
}

再附上 全部的延时函数:
/**************************延时50us子程序**********************/
void Delay_50us(INT16U t)
{
      INT8U j;
      for(;t>0;t--)   
             for(j=20;j>0;j--);              
}

/**************************延时0.9ms子程序**********************/
void Delay0_9ms(void)
{INT8U j,k;
     for(j=18;j>0;j--)
       for(k=20;k>0;k--) ;
}
/***************************延时1ms子程序**********************/
void Delay1ms(void)
{INT8U i,j;
   for(i=2;i>0;i--)
      for(j=240;j>0;j--) ;
}
/***************************延时4.5ms子程序**********************/
void Delay4_5ms(void)
{INT8U i,j;
     for(i=10;i>0;i--)
      for(j=230;j>0;j--) ;
}


说明:此程序来源于 长沙太阳人”杯红外波形显示单片机设计大赛   制作人:小杨(杨再兴)   <2010.7.5>   

出0入0汤圆

 楼主| 发表于 2012-4-26 23:58:59 | 显示全部楼层
lxa0 发表于 2012-4-26 22:12
向上翻/向下翻的动作不要放在中断代码里面

谢谢大哥。这个是正解。

我设定了部分全局变量

在中断中,只是置位对应的变量,然后,在主程序的while循环里判断就可以解决这个问题了。呵呵

中断程序如下:
/************************中断0解码服务子程序**********************/
void int0(void) interrupt 0      
{
        EA=0;
        irdalow = IRDA_JIEMA();//得到解码的数据 这个数据只包括数据码!
        Delay_ms(20);
        //sprintf(yonghuma,"%04X",irdalow);
        //强制格式化,把数据转为4位的16进制数据。
        if(irdalow == 0x0af5)
                ;                                //你按下了音量+
        if(irdalow == 0x09f6)
                ;                                //你按下了音量—
        if(irdalow == 0x0df2)        {KEY_UP = 1;        }        //上翻标志置一
        if(irdalow == 0x0ef1)        {KEY_DOWN = 1;        }        //下翻标志置一
        if(irdalow == 0x02fd)        {KEY_PLAY = 1;        }        //播放音乐标志置位
        if(irdalow == 0x01fe)        {KEY_MENU = 1;        }        //菜单键意味着返回键的意思。
       
        if(irdalow == 0x09F6)        {KEY_VOL_LOW = 1;        }        //VOL--
        if(irdalow == 0x0AF5)        {KEY_VOL_HIGH = 1;        }        //vol++

        EA=1;
}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 02:22

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表