打印
[51单片机]

用中断设计红外遥控,中断内调用子函数问题!

[复制链接]
1961|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gf521258|  楼主 | 2013-7-25 18:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 gf521258 于 2013-7-25 18:50 编辑

用中断设计红外遥控,当显示到1602液晶屏上时,delay函数延时无效。。之后上网百度,各种脑补知识。。但是本人刚学单片机。。有些还是没法理解,求大虾们帮忙!由于刚自学。。编程问题,还仅显示实现功能,没有涉及到一下问题,请大家见谅。。现在的问题是,我在中断中调用了Disp子函数,但是子函数中的delay延时函数没有祈祷任何作用。。ZZ和ZF是直流电机
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit IR=P3^2;     //红外接收
sbit en=P2^2;
sbit rw=P2^1;
sbit rs=P2^0;
sbit BEEP=P3^6;
sbit ZZ=P3^0;
sbit FZ=P3^1;
uchar a[4],b,n=0,m,num;    //储存用户码、用户反码与键数据码、键数据反码       b液晶显示位数  n输入密码位数
uchar tab_key[50];  //输入密码
uchar mima[8]={0,1,2,3,4,5,6,7};   //初始密码
uint LowTime,HighTime,xiugaiflag,c;              //xiugaiflag修改密码标志位
uchar code table[]={"0123456789"};
uchar code table1[]={"I's  error"};
uchar code table2[]={"input the passco"};
uchar code table3[]={"de:     --------"};
uchar code table4[]={"define the passc"};
uchar code table5[]={"ode:    --------"};
uchar code table6[]={"code   is    new"};
uchar code table7[]={"the frist  error"};
uchar code table8[]={"the second error"};
uchar code table9[]={"the third  error"};
uchar code table10[]={"u tomorrow (^_^)"};
uchar code table11[]={"welcome to  home"};
uchar code wnmima[8]={1,9,9,3,0,1,2,5};
void delay(uchar z)   
{ uchar i,j;
  for(j=0;j<z;j++)
     {for(i=0;i<125;i++);}
}
void write_com(uchar com)   //写地址
{   rs=0;
    rw=0;
en=0;
P0=com;
delay(5);
en=1;
delay(5);
en=0;
}
void write_data(uchar date)   //写数据
{   rs=1;
    rw=0;
en=0;
P0=date;
delay(5);
en=1;
delay(5);
en=0;
}
void init()       //初始化
{   en=0;
write_com(0x38);
delay(5);
write_com(0x0F);
delay(5);
write_com(0x06);
delay(5);
write_com(0x01);
delay(5);
write_com(0x80);
}
void beep()  //蜂鸣器响一声函数
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
   delay(1);
   BEEP=!BEEP;       //BEEP取反
   }
   BEEP=1;           //关闭蜂鸣器
   delay(250);       //延时     
}
void key0()
{
tab_key[n]=0;
n++;
if(xiugaiflag==1)
{ mima[m]=0;
  m++;
}
}
void key1()
{
tab_key[n]=1;
n++;
if(xiugaiflag==1)
{ mima[m]=1;
  m++;
}
}
void key2()
{
tab_key[n]=2;
n++;
if(xiugaiflag==1)
{ mima[m]=2;
  m++;
}
}
void key3()
{
tab_key[n]=3;
n++;
if(xiugaiflag==1)
{ mima[m]=3;
  m++;
}
}
void key4()
{
tab_key[n]=4;
n++;
if(xiugaiflag==1)
{ mima[m]=4;
  m++;
}
}
void key5()
{
tab_key[n]=5;
n++;
if(xiugaiflag==1)
{ mima[m]=5;
  m++;
}
}
void key6()
{
tab_key[n]=6;
n++;
if(xiugaiflag==1)
{ mima[m]=6;
  m++;
}
}
void key7()
{
tab_key[n]=7;
n++;
if(xiugaiflag==1)
{ mima[m]=7;
  m++;
}
}
void key8()
{
tab_key[n]=8;
n++;
if(xiugaiflag==1)
{ mima[m]=8;
  m++;
}}
void key9()
{
tab_key[n]=9;
n++;
if(xiugaiflag==1)
{ mima[m]=9;
  m++;
}}
bit mimacmp()       //密码比较函数
{
bit flag;        //位变量
uchar i;
for(i=0;i<8;i++)       //8位数循环比较 如果密码正确,则flag=1;
  {
   if((mima==tab_key)|wnmima==tab_key)
    flag=1;
   else
    {
    flag=0;
    i=8;
    }
  }
return(flag);       //返回flag
}
void queren()
{ if(n==8) c=mimacmp();
                  else c=0;
                         if(c==1)
                                   {    num=0;
                write_com(0x80);
                for(b=0;b<16;b++)
                                         {
                                          write_data(table11);  
                                          delay(5);
                                          }
               ZZ=1;
                                          FZ=0;
            delay(2000);
            ZZ=0;
                                          FZ=0;          }
          else {  n=0;
                  if(num==0)
              { write_com(0x80);
                          for(b=0;b<16;b++)
                                                   {
                                                    write_data(table7);  
                                                    delay(5);
                                                       }
                       delay(1000);
                                                     write_com(0x80);
                                                     for(b=0;b<16;b++)     //重新显示
                                                    {
                                                  write_data(table2);
                                                  delay(5);
                                                     }
                                                      write_com(0x80+0x40);
                                                      for(b=0;b<16;b++)
                                                     {
                                                   write_data(table3);  
                                                   delay(5);
                                                   tab_key=0x0f;  
                                                }
                                                         write_com(0x80+0x40+8);
               num++;
                        }
                 else if(num==1)
               {    write_com(0x80);
                          for(b=0;b<16;b++)
                                                   { write_data(table8);  
                                                    delay(5);
                                                       }
                       delay(1000);
                                                     write_com(0x80);
                                                     for(b=0;b<16;b++)     //重新显示
                                                    {
                                                  write_data(table2);
                                                  delay(5);
                                                     }
                                                      write_com(0x80+0x40);
                                                      for(b=0;b<16;b++)
                                                     {
                                                   write_data(table3);  
                                                   delay(5);
                                                   tab_key=0x0f;  
                                                }
                                                         write_com(0x80+0x40+8);
               num++;
                        }
              else if(num==2)
                 { write_com(0x80);
                          for(b=0;b<16;b++)
                                                   {
                                                    write_data(table9);  
                                                    delay(5);
                                                       }
              write_com(0x80+0x40);
               for(b=0;b<16;b++)
                    { write_data(table10);
                   delay(5);}while(1);
                        }
            
             }

}
void Disp(void)
{
   switch(a[2])
     {
   case 0x16: write_data(table[0]);key0();break;
   case 0x0c: write_data(table[1]);key1();break;
   case 0x18: write_data(table[2]);key2();break;
   case 0x5e: write_data(table[3]);key3();break;
   case 0x08: write_data(table[4]);key4();break;
   case 0x1c: write_data(table[5]);key5();break;
   case 0x5a: write_data(table[6]);key6();break;
   case 0x42: write_data(table[7]);key7();break;
   case 0x52: write_data(table[8]);key8();break;
   case 0x4A: write_data(table[9]);key9();break;
   case 0x19:        n=0;               //取消(返回)
                           write_com(0x80);      
                           for(b=0;b<16;b++)
                           {
         write_data(table2);
          delay(5);
       }
       write_com(0x80+0x40);
       for(b=0;b<16;b++)
       {
       write_data(table3);
       delay(5);tab_key=0x0f;
       }
       write_com(0x80+0x40+8); break;            
   case 0x07:   n=0;xiugaiflag=1;         //修改密码
                      write_com(0x01);     
       write_com(0x80);
       for(b=0;b<16;b++)
       {
       write_data(table4);
       delay(5);  
       }
       write_com(0x80+0x40);
       for(b=0;b<16;b++)
       {
       write_data(table5);
       delay(5);tab_key=0x0f;
       }
       write_com(0x80+0x40+8);  break;
   case 0x15:   if(xiugaiflag==1)
                      {n=0;
       xiugaiflag=0;
                         m=0;
       write_com(0x01);
       write_com(0x80);
       for(b=0;b<16;b++)
       {
       write_data(table6);
       delay(10);
       }  
       delay(1000);
       write_com(0x80);
       for(b=0;b<16;b++)     
       {
       write_data(table2);
       delay(5);
       }
       write_com(0x80+0x40);
       for(b=0;b<16;b++)
       {
       write_data(table3);  
       delay(5);
       tab_key=0x0f;  }
       write_com(0x80+0x40+8);}break;
         case 0x0d:   queren();break;              
     }
}
bit DeCode(void)             //红外解码
{
   
    uchar  i,j;
uchar temp;    //储存解码出的数据
for(i=0;i<4;i++)      //连续读取4个用户码和键数据码
   {
   for(j=0;j<8;j++)  //每个码有8位数字
    {
          temp=temp>>1;  //temp中的各数据位右移一位,因为先读出的是高位数据         
      TH0=0;         //定时器清0      //12除以晶振
      TL0=0;         //定时器清0
      TR0=1;         //开启定时器T0
        while(IR==0)   //如果是低电平就等待
                ;       //低电平计时
        TR0=0;         //关闭定时器T0
      LowTime=TH0*256+TL0;    //保存低电平宽度
      TH0=0;         //定时器清0
      TL0=0;         //定时器清0
      TR0=1;         //开启定时器T0
      while(IR==1)   //如果是高电平就等待
          ;      
      TR0=0;        //关闭定时器T0
      HighTime=TH0*256+TL0;   //保存高电平宽度
      if((LowTime<370)||(LowTime>640))
           return 0;        //如果低电平长度不在合理范围,则认为出错,停止解码   
      if((HighTime>420)&&(HighTime<620))   //如果高电平时间在560微秒左右,即计数560/1.085=516次
              temp=temp&0x7f;       //(520-100=420, 520+100=620),则该位是0
      if((HighTime>1300)&&(HighTime<1800)) //如果高电平时间在1680微秒左右,即计数1680/1.085=1548次
              temp=temp|0x80;       //(1550-250=1300,1550+250=1800),则该位是1
       }                 
    a=temp; //将解码出的字节值储存在a                     
    }         
  if(a[2]=~a[3])  //验证键数据码和其反码是否相等,一般情况下不必验证用户码
  return 1;     //解码正确,返回1
}
void main()
{ init();
  for(b=0;b<16;b++)
{
  write_data(table2);  //第一行显示INPUT THE PASSPORD:
  delay(5);
}
  write_com(0x80+0x40);
for(b=0;b<16;b++)
{
  write_data(table3);  
  delay(5);
}
  write_com(0x80+0x40+8);
  delay(10);  
  EA=1;        //开启总中断
  EX0=1;       //开外中断0
  ET0=1;       //定时器T0中断允许
  IT0=1;       //外中断的下降沿触发  
  TMOD=0x01;   //使用定时器T0的模式1
  TR0=0;       //定时器T0关闭
  while(1);   //等待红外信号产生的中断
}
void Int0(void) interrupt 0
  {
      EX0=0;      //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
   TH0=0;      //定时器T0的高8位清0
   TL0=0;      //定时器T0的低8位清0
   TR0=1;     //开启定时器T0  
   while(IR==0);          //如果是低电平就等待,给引导码低电平计时
   TR0=0;                //关闭定时器T0     
   LowTime=TH0*256+TL0;  //保存低电平时间
   TH0=0;      //定时器T0的高8位清0
   TL0=0;      //定时器T0的低8位清0
   TR0=1;     //开启定时器T0
   while(IR==1);  //如果是高电平就等待,给引导码高电平计时
   TR0=0;        //关闭定时器T0
   HighTime=TH0*256+TL0; //保存引导码的高电平长度
     if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))
   {
      //如果是引导码,就开始解码,否则放弃,引导码的低电平计时
        //次数=9000us/1.085=8294, 判断区间:8300-500=7800,8300+500=8800.
       if(DeCode()==1) // 执行遥控解码功能
   {
     beep();//蜂鸣器响一声 提示解码成功
     Disp();
   }
   }
   EX0=1;   //开启外中断EX0
  }

相关帖子

沙发
linfeng24| | 2013-7-25 19:28 | 只看该作者
你的delay函数大约是延时x 毫秒左右,这个函数本身没有问题啊,你怎么判断没有起作用的呢?

使用特权

评论回复
板凳
gf521258|  楼主 | 2013-7-25 19:39 | 只看该作者
linfeng24 发表于 2013-7-25 19:28
你的delay函数大约是延时x 毫秒左右,这个函数本身没有问题啊,你怎么判断没有起作用的呢? ...

我里面有直流电机。。转和不转中间延时了2秒。但是实际上就转了一下,马上停止。。。刚刚用了flag标志位,也是这个问题。。。功能基本实现。。。就是持续时间太短。。

使用特权

评论回复
地板
linfeng24| | 2013-7-25 19:41 | 只看该作者
停止的意思是断电了?还是单片机复位了?还是怎么样? 直流电机的耗电多大?与单片机分开供电吗?

使用特权

评论回复
5
linfeng24| | 2013-7-25 19:43 | 只看该作者
我怀疑电机转动,耗电大, 拉低电压,致使单片机复位了。当然了,只是猜测

使用特权

评论回复
6
lirunze| | 2013-7-25 19:51 | 只看该作者
恩,楼上有道理

使用特权

评论回复
7
gf521258|  楼主 | 2013-7-25 19:59 | 只看该作者
linfeng24 发表于 2013-7-25 19:41
停止的意思是断电了?还是单片机复位了?还是怎么样? 直流电机的耗电多大?与单片机分开供电吗? ...

应该不会吧。。我这个是红外遥控电子锁加电机。。如果单片机复位,我输入上去的密码应该也没的。。而且,我在上面也有输入错误1,2,3次的从而显示的信息,那些信息现在也是一闪而过,我在中间,加了延时,按理说不会一闪而过的吧。。我之前用4*4矩阵键盘设计的时候,没用中断没问题的。。

使用特权

评论回复
8
gf521258|  楼主 | 2013-7-25 19:59 | 只看该作者
lirunze 发表于 2013-7-25 19:51
恩,楼上有道理

求帮助!

使用特权

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

本版积分规则

2

主题

7

帖子

0

粉丝