找回密码
 立即注册

QQ登录

只需一步,快速开始

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

关于STC8掉电唤醒只能执行两次,之后就死机无法唤醒?

[复制链接]
跳转到指定楼层
楼主
ID:1047058 发表于 2022-10-9 14:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用外部中断1进行掉电唤醒操作,代码如下。但是在实际实验操作时,大部分情况是长按按键进入掉电状态,唤醒两次后就无法继续工作,一直保持在休眠状态,必须上电复位才可以。(上电--掉电--唤醒--掉电--唤醒--掉电--再也唤不醒)
但是有时候又可以唤醒到6次左右。
怀疑过是按键的问题,但是已经更换了电容确保灵敏度足够,只能从代码这里入手了。
已善用搜索,相关问题都查阅过,但是初学者还是有些迷茫,斗胆请教,希望各位指点!
//=======================单片机主程序=============================
  1. void main()
  2. {
  3.                 exint1Init() ;

  4.                 while(1)
  5.                 {
  6.                          KeyWorking() ;
  7.                          if( KeyWorking() == 1) //一个长按识别关机的标志,由此进入掉电状态
  8.                          {
  9.                                   EA  = 1;
  10.                                   EX1 = 0 ;                                                 //关闭INT1中断
  11.                                   IT1 = 1;
  12.                                   PCON |= 0x02;            //MCU进入掉电模式
  13.                                   _nop_();            //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序
  14.                                   _nop_();
  15.                                   _nop_() ;
  16.                                   _nop_() ;
  17.                                   _nop_() ;
  18.                                   _nop_() ;
  19.                          }        
  20.                 }
  21. }
复制代码


  1. //-----------------------------------------
  2. //中断INT1初始化程序
  3. void exint1Init()
  4. {               
  5.                 EA = 1;
  6.                 IT1 = 1;         //设置INT1的中断类型为仅下降沿,下降沿唤醒
  7.                 EX1 = 1;             //使能INT1中断

  8. }

  9. //-----------------------------------------
  10. //中断INT1服务程序
  11. void exint1() interrupt 2     //INT1中断入口
  12. {
  13.           EX1  = 0;
  14.           P3^2 = !P3^2;             //将测试口取反
  15.           INT1 = 0;                    //保存INT1口的状态, INT1=0(下降沿); INT1=1(上升沿)
  16.           PCON = 0x00 ;
  17.           EX1 = 1 ;
  18. }
复制代码

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

使用道具 举报

沙发
ID:879348 发表于 2022-10-9 17:03 | 只看该作者
为何要在中断里休眠?没有这样写程序的
回复

使用道具 举报

板凳
ID:1047058 发表于 2022-10-9 17:22 | 只看该作者
wufa1986 发表于 2022-10-9 17:03
为何要在中断里休眠?没有这样写程序的

那是需要把中断服务函数里的拎出来写一个休眠函数,然后在主函数调用吗?
回复

使用道具 举报

地板
ID:213173 发表于 2022-10-9 20:32 | 只看该作者
楼主为什么把代码写成这样,STC8有现成的官方示例。
回复

使用道具 举报

5#
ID:624769 发表于 2022-10-9 22:36 | 只看该作者
//中断INT1初始化程序
void exint1Init()
{               
                EA = 1;
                IT1 = 1;         //设置INT1的中断类型为仅下降沿,下降沿唤醒
                EX1 = 1;             //使能INT1中断

}

void main()
{
                exint1Init() ;

                while(1)
                {
                         KeyWorking() ;
                         if( KeyWorking() == 1) //一个长按识别关机的标志,由此进入掉电状态
                         {
                                  EA  = 1;
//                                  EX1 = 0 ;                                                 //关闭INT1中断
                                  IT1 = 1;
                                  PCON |= 0x02;            //MCU进入掉电模式
                                  _nop_();            //掉电模式被唤醒后,首先执行此语句,然后再进入中断服务程序
                                  _nop_();
                                  _nop_() ;
                                  _nop_() ;
                                  _nop_() ;
                                  _nop_() ;
                         }        
                }
}

void exint1() interrupt 2     //INT1中断入口
{
//          EX1  = 0;
          P3^2 = !P3^2;             //将测试口取反
//          INT1 = 0;                    //保存INT1口的状态, INT1=0(下降沿); INT1=1(上升沿)
//          PCON = 0x00 ;
//          EX1 = 1 ;

}
回复

使用道具 举报

6#
ID:879348 发表于 2022-10-10 08:19 | 只看该作者
Arouw 发表于 2022-10-9 17:22
那是需要把中断服务函数里的拎出来写一个休眠函数,然后在主函数调用吗?

不要在中断操作PCON
回复

使用道具 举报

7#
ID:1047058 发表于 2022-10-10 08:25 | 只看该作者
wulin 发表于 2022-10-9 20:32
楼主为什么把代码写成这样,STC8有现成的官方示例。

是因为这个是继承前辈的代码,功能不止这一个,所以不敢贸然改,而且我对stc8也不熟。。。
回复

使用道具 举报

8#
ID:401564 发表于 2022-10-10 08:44 | 只看该作者
5#已经给出正解的方法了
不要在中断中关闭中断
不要在中断中操作PCON
不要在中断中更改中断的相关设置
这些,都要在中断程序外执行
可以在退出中断之前加一条 IE1 = 0;
中断触发按键要有防抖
回复

使用道具 举报

9#
ID:123289 发表于 2022-10-10 09:26 | 只看该作者
告诉你原因:
进入中断的中断程序(响应中断)有以下条件,缺一不可:
1、中断被允许(你已做到了)。
2、中断源动作(你已做到了)。
3、没有更高级或同级的中断正在响应进行中(你只做到了一次,这是关键):
复位时,所有中断被清除,你可以进来。
进来后,你没有退出,也即一直处理中断服务程序进行中,如何能再响应新的中断呢?
原因是:同级中断(本中断)未退出,不再接受新的本中断!!!
回复

使用道具 举报

10#
ID:1034262 发表于 2022-10-10 14:29 | 只看该作者
建议直接测试STC ISP里的范例程序。
回复

使用道具 举报

11#
ID:1047058 发表于 2022-10-11 10:16 | 只看该作者
yzwzfyz 发表于 2022-10-10 09:26
告诉你原因:
进入中断的中断程序(响应中断)有以下条件,缺一不可:
1、中断被允许(你已做到了)。

按照您说的我尝试了很多次,但是还是有一些疑问:中断要在哪里退出呢?是长按唤醒模块退出还是长按掉电模块,还是写在主函数里?我每个地方都尝试了EX1=0可还是不行。

而且,为什么会出现同样的程序同样的操作,有时候可以正常唤醒多次,有时候甚至一次都不行呢,难道是硬件的问题吗?
回复

使用道具 举报

12#
ID:1047058 发表于 2022-10-11 10:47 | 只看该作者
各位好,这个问题已经解决了。原来是前辈的代码里已经写了关机模块,不需要我再次使用掉电唤醒,两个冲突了,注释掉相关的掉电唤醒模块后就可以正常开关机使用了。非常感谢各位大佬的分享和帮助,以后我一定认真阅读代码理解完毕后再动手去写!

再次谢谢各位,受益良多,对于掉电唤醒部分我也有所收获,打算利用手头的单片机板子下载STC的官方示例代码进一步学习。
回复

使用道具 举报

13#
ID:123289 发表于 2022-10-11 13:12 | 只看该作者
CPU是以RETI指令,来确定中断程序退出的。
而C语言是以函数结束,来确定中断程序退出的。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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