打印

AT89S51的外部中断问题

[复制链接]
4477|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
njcindy|  楼主 | 2009-2-25 14:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问各位大侠,我的AT89S51的INT0、INT1均设置为下降沿触发,当INT0来了一个下降沿并且一直保持低电平,运行完INT0的中断服务程序后,系统进入掉电模式,然后INT1来一个下降沿将AT89S51唤醒,但是我发现唤醒后不仅INT1的中断服务程序被执行了,INT0的中断服务程序竟然也执行了,这是怎么回事?谢谢!

相关帖子

沙发
红心j| | 2009-2-25 17:44 | 只看该作者

(1)程序问题(2)信号问题

没见程序只能猜

使用特权

评论回复
板凳
hab2000| | 2009-2-25 17:49 | 只看该作者

很多单片机在睡眠前如果中断I/O是低电平是唤不醒的!!!

以前遇到过类似问题,建议睡觉前检测一下I/O,
1、如果是低等高了再睡;
2、如果等不了建议用其它中断唤醒(改变唤醒周期)。

使用特权

评论回复
地板
njcindy|  楼主 | 2009-2-25 18:44 | 只看该作者

唤醒后执行了不该执行的程序

在Power down 时,INT0脚是低电平,实际情况要求不能等到INT0脚变高了再掉电,掉电后通过INT1的下降沿唤醒CPU,我测试了,能够唤醒,但是唤醒后不仅执行了INT1的中断服务程序,想不通的是还执行了INT0的中断程序,请各位帮我分析一下原因,谢谢!

使用特权

评论回复
5
gw29| | 2009-2-25 21:59 | 只看该作者

re

猜测原因如下
INT1中断是肯定要执行的
INT0信号不稳定,在睡眠期间出现下降沿,所以执行完int1中断接着执行int0中断

使用特权

评论回复
6
njcindy|  楼主 | 2009-2-25 23:31 | 只看该作者

奇怪的掉电后中断唤醒

应该不是INT0在掉电期间出现了下降沿,如果是的话,应该不用INT1的下降沿,CPU就能醒过来。因为在INT0为低电平时掉电,每次都是通过INT1的下降沿醒过来,而且醒过来后先执行的是INT0的中断服务程序,然后才执行INT1的中断服务程序,真是奇怪啦!

使用特权

评论回复
7
hab2000| | 2009-2-26 10:05 | 只看该作者

贴程序

使用特权

评论回复
8
lyjian| | 2009-2-26 12:55 | 只看该作者

运行完INT0的中断服务程序后

你本来就在运行INT0的中断服务程序

使用特权

评论回复
9
njcindy|  楼主 | 2009-2-26 13:27 | 只看该作者

程序片段

//****************************************************************************
void low_power(void)
{
 if(awake_state==is_leisure)
  {
   IT0=1;            //两个外中断下降沿触发以便唤醒
   IT1=1;
   IE0=0;
   IE1=0;
   EX0=1;            //打开组合中断
   EX1=1;

   shift_LED=1;
   risk_LED=1;
   guard_LED=1; 

   //FeedWDT
   PCON|=0x02;        //power down cpu
   //FeedWDT
  }
}
//****************************************************************************
void int0() interrupt 0         //为转移、危险和警戒组合中断
{
 IT0 = 1;                        //外中断0下降沿触发
 EX0 = 0;                       //close int0 interrupt

 t0_times=0;
 t0_constant=200;              //50ms*1200=60s
 timeout_flag=0;

 keystate=audition;
 if(!shift)
   awake_state=is_shift;
 else if(!risk)
   awake_state=is_risk;
 else if(!guard)
   awake_state=is_guard;

 shift_LED=0;
 dlms(3000);
 shift_LED=1;
 
 IE0 = 0;
 TR0 = 1;                            //启动定时器0
}
//****************************************************************************
void int1() interrupt 2         //按一下按键,试听一种报警声,报警声持续5s后自动停止,若在这5s期间按键再次被按下,则报警声停止
{                               //在报警声响时,按下按键,则为消音;无报警声响时,按下按键则为试听。
 EX0=0;
 IE0=0;
 risk_LED=0;
 dlms(3000);
 risk_LED=1;
 IT1 = 1;                        //防止再次中断,外中断1改为下降沿触发
 EX1 = 0;
 
 /*dlms(10);                      //消抖
 if(int1_query)
   {
    IE1=0;
    EX1 = 1;
    return;
   }*/

 wait_undo:
            while(!int1_query)//FeedWDT  
            dlms(10);                              //消抖
            //FeedWDT
            if(int1_query==0)goto wait_undo;
                                     
 if(awake_state!=is_leisure)
   {
    TR0=0;
    t0_times=0;
    keystate=silence;
    if(awake_state==is_audition)
      {
       int1hear_times=0x03&(++int1hear_times);
       if(int1hear_times==0x03)
         int1hear_times=0;
      }
    awake_state=is_leisure;
    TL0 = -46080%256;
    TH0 = -46080/256;                   //50ms=50000*11.0592/12=46080
   }                
 else
   {
    t0_times=0;
    t0_constant=100;                 //50ms*100=5s
    timeout_flag=0;
    keystate=audition;
    awake_state=is_audition;
    TR0 = 1;                             //启动定时器0
   }

 IE1=0;
 EX1 = 1;
}
//****************************************************************************

使用特权

评论回复
10
njcindy|  楼主 | 2009-2-26 16:45 | 只看该作者

掉电时,ALE=1,/PSEN=0

另外,当INT0为低电平时进入掉电状态,测得ALE为高电平,/PSEN为低电平;还有,如果当INT0为低电平时进入空闲状态,则INT1的下降沿唤醒CPU时,则不会执行INT0的中断服务程序,只执行INT1的中断服务程序

使用特权

评论回复
11
njcindy|  楼主 | 2009-2-26 16:49 | 只看该作者

掉电之前,令EX0=0

进入掉电之前,EX0=0关掉INT0的中断使能,则INT1下降沿唤醒CPU时不执行INT0的中断服务程序

使用特权

评论回复
12
ayb_ice| | 2009-2-26 20:16 | 只看该作者

还是要去仔细看DATASHEET

要想用外部中断唤醒掉电模式,必须设为低电平中断,有些MCU会自动转换成低电平中断,这个地方要求还是很多的,仔细看资料。。。

使用特权

评论回复
13
njcindy|  楼主 | 2009-2-27 12:57 | 只看该作者

下降沿和低电平方式都可以唤醒处于掉电状态的AT89S51

下降沿和低电平方式都可以唤醒处于掉电状态的AT89S51。假设下降沿是自动转换成低电平唤醒CPU的,那INT0一直为低电平时,CPU是睡不着的(一掉电就会被唤醒),但实际情况是设置为下降沿触发方式且INT0一直为低电平时,CPU能够睡着。

使用特权

评论回复
14
quakegod| | 2009-2-28 05:09 | 只看该作者

偶觉得是不是可以这么解释啊

因为INT0在睡眠是一直保持低电平,
而MCU唤醒的时候,MCU重新得电,使得相对于MCU来说,INT0又产生了一次下降沿。

使用特权

评论回复
15
ayb_ice| | 2009-2-28 17:49 | 只看该作者

S51的外部中断必须是低电平唤醒掉电模式

使用特权

评论回复
16
gw29| | 2009-2-28 23:27 | 只看该作者

re

程序中哪里调用 低功耗 子程序

使用特权

评论回复
17
bg6nw| | 2009-3-1 06:34 | 只看该作者

看样子只能

掉电之前关掉int0的中断功能,唤醒后执行完int1的中断程序后,再打开它。
另外,你可以把int1的优先级设的高于int0试试。

使用特权

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

本版积分规则

3

主题

11

帖子

0

粉丝