找回密码
 立即注册

QQ登录

只需一步,快速开始

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

[求助]又一个关于单片机中断的问题

[复制链接]
跳转到指定楼层
楼主
ID:7020 发表于 2008-11-22 19:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

刚学单片机,在中断这块我总是遇见问题,下面这段程序我想现实的效果是:开机时两端的LED灯闪烁,当我给单片机一个外部中断的时候,小灯熄灭一段时间后,第二个LED灯和倒数第二个LED灯闪烁,持续2秒(用定时器中断实现)然后所有的灯熄灭。可是当我给单片机一个外部中断后,小灯确实灭了一段时间,可是过了一段时间后并没有出现第二个LED灯和倒数第二个LED灯闪烁持续2秒,然后熄灭的情况,而是返回了开始两端LED灯闪烁的情况!(好像下面代码红色的部分没执行)我都改了N+1遍了都没有出现我想要的情况,都快绝望了!请大家帮帮忙,解决一下。(LED灯接P0口)

#include<reg52.h>
int n,a;
void delaytime(int ms) //控制小灯的闪烁
{
 int x,y;
 for(x=ms;x>0;x--)
 for(y=200;y>0;y--);
}

void forword()   //使p0.0和P0.7口闪烁(两端的小灯闪烁)
{
  while(1)
    {
      P0=0x7e;
      delaytime(20);
      P0=0xff;
      delaytime(20);
    }
}

void back()  //P0.1和P0.6口灯闪烁(第二个灯和倒数第二个灯闪烁)2秒后熄灭
{
 TMOD=0x01; //定时器工作在方式1
 TH0=(65536-50000)/256;  // 50ms定时
 TL0=(65536-50000)%256;
 ET0=1; //允许定时器中断
 TR0=1; //开启定时器
 while(1)
 {
  if(n==40)  //判断是否到了两秒(40*50ms),到了  关闭所有灯
  {
      P0=0xff; // 灯灭
      while(1);
  }
      P0=0xbd; //P0.1和P0.6口灯亮
      delaytime(20);
      P0=0xff;
      delaytime(20);
 }
}

void main()
{
 a=0;
 IT0=1; //外部0中断,跳沿触发方式
 EA=1;  // 开总中断
 EX0=1; //允许外部0中断
 if(a!=0) //判断a==1?,不等于则调用back(),使P0.6和P0.2口灯闪烁2秒后灭掉
 back();
 else
 forword(); //否则调用forward(),使p0.0和P0.7口灯闪烁
}


void extinter() interrupt 0 //外部中断0函数
{
 a++; 
 P0=0xff;  //所有的灯灭
 delaytime(100); // 延时 
}

void timer0() interrupt 1 //定时器0中断函数
{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 n++;
}
起初我以为是因为中断优先级的问题,可是当我把外部中断0改为外部中断1时还是不行。
当我把 back()函数放在外部中断函数里调用的时候,它的确被调用了,但是出现了 P0.1和P0.6口灯一直在闪烁(第二个灯和倒数第二个灯闪烁)的情况,而并没有出现持续两秒后自动熄灭的效果,好像并没有调用定时器中断;当我在forward()中加入
if(a!=0) back();时出现的情况还是跟我提出的问题一样,并没有调用back()函数

[此贴子已经被作者于2008-11-23 11:02:05编辑过]
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:7167 发表于 2008-11-24 15:07 | 只看该作者
你的主函数里,if语句不对,back函数里,定时安排不对,都没考虑返回语句,只能执行一种情况。我修改一下,延时只能用一次,以后都使用外部中断。编程时,要把思路搞清楚。程序如下:
#include<reg52.h>
int n,a;
void delaytime(int ms) //控制小灯的闪烁
{
 int x,y;
 for(x=ms;x>0;x--)
 for(y=200;y>0;y--);
}
void back()  //P0.1和P0.6口灯闪烁(第二个灯和倒数第二个灯闪烁)2秒后熄灭
{
 TMOD=0x01; //定时器工作在方式1
 TH0=(65536-50000)/256;  // 50ms定时
 TL0=(65536-50000)%256;
 ET0=1; //允许定时器中断
 TR0=1; //开启定时器
 while(1)
 {
  if(n==40)  //判断是否到了两秒(40*50ms),到了  关闭所有灯
  {
      P0=0xff; // 灯灭
      delaytime(2000);
  }
      P0=0xbd; //P0.1和P0.6口灯亮
      delaytime(20);
      P0=0xff;
      delaytime(20);
 }
}
void forword()   //使p0.0和P0.7口闪烁(两端的小灯闪烁)
{
  while(1)
    {
      P0=0x7e;
      delaytime(20);
      P0=0xff;
      delaytime(20);
   if(a!=0) //判断a==1?,不等于则调用back(),使P0.6和P0.2口灯闪烁2秒后灭掉
      back();
    }
}
void main()
{
 a=0;
 IT0=1; //外部0中断,跳沿触发方式
 EA=1;  // 开总中断
 EX0=1; //允许外部0中断
 forword(); //否则调用forward(),使p0.0和P0.7口灯闪烁
}
void extinter() interrupt 0 //外部中断0函数
{
 a++;
 P0=0xff;  //所有的灯灭
 delaytime(100); // 延时
}
void timer0() interrupt 1 //定时器0中断函数
{
 TH0=(65536-50000)/256;
 TL0=(65536-50000)%256;
 n++;
}
回复

使用道具 举报

板凳
ID:7020 发表于 2008-11-25 20:02 | 只看该作者

真的是太感谢你了!以前我对当中断程序返回后返回的地址不是很了解,通过这次的这个程序我对这个问题相对以前有了更加深刻的理解!

[此贴子已经被作者于2008-11-25 20:04:23编辑过]
回复

使用道具 举报

地板
ID:7228 发表于 2008-11-26 12:48 | 只看该作者
IF  语句 有什么问题吗?  我看他程序只是 中断跟定时混乱了  菜鸟请教
回复

使用道具 举报

5#
ID:7020 发表于 2008-11-27 23:33 | 只看该作者
按照我以前的写法当外部中断返回的时候,返回到的是forward()函数里面,而不是返回到 if 判断的位置?因为外部中断响应前,程序一直在执行forward()函数,当中断响应的时候只把forward()函数的地址压入栈内了,而并未保存if()的地址.
回复

使用道具 举报

6#
ID:7228 发表于 2008-12-4 15:09 | 只看该作者
     你的这个意思我知道  其实就是中断 的处理 有问题    但是IF语句本身没问题的  只不过IF语句位置不对   是这样的吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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