极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 36400|回复: 1

Arduino省电模式下看门狗中断的奇怪现象分析

[复制链接]
发表于 2021-2-23 21:48:25 | 显示全部楼层 |阅读模式
做了一个单片机控制音乐播放的闹钟,闹钟在整点与半点时会按照设定的音乐播放。
晚上忽然想到在电池供电时,如何达到省电的效果,使电池的使用时间更长。
查找了网络,受网上《Arduino休眠模式和看门狗以及中断详解》的启发,对主程序进行了休眠模式改进,程序如下:
原程序出处:https://blog.csdn.net/qq_39400113/article/details/107536805

  1. #include <avr/wdt.h>  
  2. #include <avr/sleep.h>
  3. int ledPin = 13;
  4. int data=0;

  5. ISR(WDT_vect)
  6. {
  7.   //看门狗唤醒执行函数1重启看门狗
  8.   data++;
  9. }
  10. void setup()
  11. {
  12.   Serial.begin(9600);
  13.   pinMode(ledPin, OUTPUT);   
  14.   set_sleep_mode(SLEEP_MODE_PWR_DOWN); //设置休眠模式。
  15.   sleep_enable(); //开启休眠功能。
  16.                   //ACSR |=_BV(ACD);//关掉ACD,据说很省电。不知道唤醒以后要不要重新开,怎么开?
  17.                   //ADCSRA=0;//关掉ADC,据说很省电。不知道唤醒以后要不要重新开,怎么开?
  18.                   //按照官方解释,sleep_enable()最好写在中断(attachInterrupt())前,防止中断在开始休眠前就提前释放而造成休眠后无法唤醒。
  19.                   //开始设置看门狗中断,用来唤醒。   
  20.   MCUSR &= ~(1<<WDRF);
  21.   WDTCSR |= (1<<WDCE) | (1<<WDE);
  22.   WDTCSR = 1<<WDP1 | 1<<WDP2;
  23.   WDTCSR |= _BV(WDIE);
  24. }  
  25. void loop()  
  26. {  
  27.    Serial.println("1");    //串口输出主程序开始

  28.   if (data>=5)
  29.   {
  30.     digitalWrite(ledPin, HIGH);   
  31.     delay(500);     
  32.     digitalWrite(ledPin, LOW);  
  33.     delay(500);   
  34.     data=0;
  35.     Serial.println("2");     //5秒进入if程序,串口输出:2
  36.   }
  37.     Serial.println("3");    //串口输出主程序结束   
  38.   sleep_cpu();//进入休眠状态,从此处开始进入休眠。这里不需要喂狗。目的就是等狗超时后执行唤醒函数。

  39. }
复制代码



发现了如下的奇怪现象,如下视频所示:
1. sleep_cpu();执行后程序开始进入休眠,sleep_cpu休眠时间1秒钟:进入休眠后,主程序不执行。
2. 可以从没有执行 Serial.println("1");  Serial.println("3"); 观察到主程序没有执行。
3. 但是当5秒钟时,进入if程序里面,此时pin13管脚的Led灯闪,伴随连续输出4组 1 3 1 3 1 3 1 3.

一开始我非常纳闷,if语句中并没有Serial.println("1");  Serial.println("3"); 为什么会在进入if后连续输出4组 1 3 1 3 1 3 1 3.
仔细研究后发现:在if程序执行后,LED灯灭掉,TX灯亮,但是串口没有接收到数据。
分析后我认为:sleep_cpu();执行后程序开始进入休眠,休眠后主程序停止。当1秒钟后看门狗溢出,主程序执行,每次单片机会向串口缓存存入1组“1”“3”.这样经过4次溢出,就会存入4组“1”“3”,但是这4组数据都会在单片机缓存内,并不会输出,因为主程序执行速度太快了,串口还没来得及输出,就执行器sleep_cpu()进入了休眠模式。只有当5秒后进入if语句,此时有大量时间可以让串口输出,串口就一下子把所有的数据都吐出来了。

同学们一起来分析分析

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2021-2-24 19:12:17 | 显示全部楼层
串口输出没有加一点延时确实可能是处于奇怪工作状态,可以尝试的1,3输出前或者后加一点延时。
回复 支持 反对

使用道具 举报

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

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 07:05 , Processed in 0.046871 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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