找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3107|回复: 2
打印 上一主题 下一主题
收起左侧

这个红外遥控代码的中断部分请大侠解释一下,感谢

[复制链接]
跳转到指定楼层
楼主
ID:111882 发表于 2016-4-2 10:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
代码如下:
#include<reg51.h>

sbit IRIN=P3^2;
sbit led1 = P2^0;
sbit led2 = P2^1;

unsigned char IrValue[6];
unsigned char Time;
void IrInit();
void DelayMs(unsigned int );
code unsigned char Tab[17] =
         {//定义数码管字型数据
                0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,        //0123456789
                 0x77,0x7C,0x39,0x5E,0x79,0x71,        //AbCdEF
                 0x40        //-
         };
/*******************************************************************************
* 函数名         : main
* 函数功能                   : 主函数
* 输入           : 无
* 输出                  : 无
*******************************************************************************/

void main()
{
         IrInit();
         while(1)
         {
         switch(IrValue[2])
         {
                 case 0: P0 = Tab[0];break;
                 case 1: P0 = Tab[1];break;
                 case 2: P0 = Tab[2];break;
                 case 3: P0 = Tab[3];break;
                 case 4: P0 = Tab[4];break;
                 case 5: P0 = Tab[5];break;
                 case 6: P0 = Tab[6];break;
                 case 7: P0 = Tab[7];break;
                 case 8: P0 = Tab[8];break;
                 case 9: P0 = Tab[9];break;
         }
     }

}                                                                        
/*******************************************************************************
* 函数名         : DelayMs()
* 函数功能                   : 延时
* 输入           : x
* 输出                  : 无
*******************************************************************************/

void DelayMs(unsigned int x)   //0.14ms误差 0us
{
unsigned char i;
   while(x--)
{
   for (i = 0; i<13; i++)
{}
}
}
/*******************************************************************************
* 函数名         : IrInit()
* 函数功能                   : 初始化红外线接收
* 输入           : 无
* 输出                  : 无
*******************************************************************************/

void IrInit()
{
         IT0=1;//下降沿触发
        EX0=1;//打开中断0允许
        EA=1;        //打开总中断

        IRIN=1;//初始化端口
}
/*******************************************************************************
* 函数名         : ReadIr()
* 函数功能                   : 读取红外数值的中断函数
* 输入           : 无
* 输出                  : 无
*******************************************************************************/

void ReadIr() interrupt 0
{
         unsigned char j,k;
         unsigned int err;
         Time=0;                                         
         DelayMs(70);

         if(IRIN==0)                //确认是否真的接收到正确的信号
        {         
                 
                 err=1000;                                //1000*10us=10ms,超过说明接收到错误的信号
                /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
                侯,程序死在这里*/        
                 while((IRIN==0)&&(err>0))        //等待前面9ms的低电平过去                  
                 {                        
                         DelayMs(1);
                         err--;
                 }
                 if(IRIN==1)                        //如果正确等到9ms低电平
                {
                         err=500;
                         while((IRIN==1)&&(err>0))                 //等待4.5ms的起始高电平过去
                        {
                                 DelayMs(1);
                                 err--;
                         }
                         for(k=0;k<4;k++)                //共有4组数据
                        {                                
                                 for(j=0;j<8;j++)        //接收一组数据
                                {

                                         err=60;               
                                         while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
//                                        while (!IRIN)
                                         {
                                                 DelayMs(1);
                                                 err--;
                                         }
                                         err=500;
                                         while((IRIN==1)&&(err>0))         //计算高电平的时间长度。
                                        {
                                                 DelayMs(1);//0.14ms
                                                 Time++;
                                                 err--;
                                                 if(Time>30)
                                                 {
                                                         EX0=1;
                                                         return;
                                                 }
                                         }
                                         IrValue[k]>>=1;         //k表示第几组数据
                                        if(Time>=8)                        //如果高电平出现大于565us,那么是1
                                         {
                                                 IrValue[k]|=0x80;
                                         }
                                         Time=0;                //用完时间要重新赋值                                                        
                                 }
                         }
                 }
                 if(IrValue[2]!=~IrValue[3])
                 {
                         return;
                 }
         }                        
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111882 发表于 2016-4-2 10:25 | 只看该作者
问题1:进入中断后,有DelayMs(70),即延时9.8ms,而遥控发射端发射码在9ms后进入4.5ms的高电平,此时IRIN==1,无法执行下面语句 if(IRIN==0) ,但程序编译后运行正常。
问题2:下降沿触发是否每个下降沿都要触发中断,因为在中断程序执行过程中,有很多触发条件,如何理解此时的中断执行过程。
问题3:调试时,进入中断后,试着关闭中断,在退出中断服务后打开中断,为何会在执行时无反应,假死。
问题4:在中断服务函数结尾处,  
if(IrValue[2]!=~IrValue[3])
                  {
                          return;
                    }
大括号内部加延时语句为何没有反应?
if(IrValue[2]!=~IrValue[3])
                  {
                          DelayMs(1000);
                          return;
                    }

感谢大神帮助解答!
回复

使用道具 举报

板凳
ID:57006 发表于 2016-12-22 22:55 | 只看该作者
第一个问题:有两种可能1.有可能实际在单片机上跑时 delayms(70);运行耗时可能少于9 ms。你可以在Keil调试中看一下那个delayms(1);时耗时多少ms。2.有可能是NEC协议对时间要求没那么严格。我试着把delayms(70);给注释掉,下载到实验板上正常工作。
第二个问题:可能是每当下降沿产生一个中断硬件自动置EX0=0,执行完中断函数自动置EX0=1。
第三个问题:我进入中断函数手动置EX0=0,函数结尾手动置EX0=1,下载到实验板上对程序正常运行没什么影响,没有你说的假死的问题。
以上只是我的推理和理解。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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