arduino休眠唤醒

进入休眠模式及休眠唤醒而不是重启

进入休眠

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <avr/sleep.h>
#include <avr/power.h>

// 关闭ACD和ADC
void OFFACDDC()
{
ACSR |= _BV(ACD);
ADCSRA = 0;
}

// 开启ACD和ADC
void ONACDDC()
{
ACSR &= ~_BV(ACIE);
ACSR &= ~_BV(ACD);
ADCSRA |= _BV(ADEN);
ADCSRA |= _BV(ADIF);
}

// 进入睡眠状态
void enterSleep(void)
{
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // 采用“Power-down”睡眠模式
sleep_enable(); // 启动睡眠模式
sleep_mode();
sleep_disable();
power_all_enable();
}

定时唤醒

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <avr/wdt.h>

void wdt_setup(int ii)
{
// ii为看门狗超时时间,支持以下数值:
// 0=16毫秒, 1=32毫秒,2=64毫秒,3=128毫秒,4=250毫秒,5=500毫秒
// 6=1秒 ,7=2秒, 8=4秒, 9=8秒
byte bb;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
//开始设置看门狗中断
MCUSR &= ~(1<<WDRF); //清除复位标志
WDTCSR |= (1<<WDCE) | (1<<WDE);
//设置新的看门狗超时时间
WDTCSR = bb;
//设置为定时中断而不是复位
WDTCSR |= _BV(WDIE);
}

//别忘了设置【看门狗唤醒执行函数】
ISR(WDT_vect)
{
//唤醒后执行的代码
}

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>


void OFFACDDC()
{ // 关闭ACD和ADC
ACSR |= _BV(ACD);
ADCSRA = 0;
}

void ONACDDC()
{ // 开启ACD和ADC
ACSR &= ~_BV(ACIE);
ACSR &= ~_BV(ACD);
ADCSRA |= _BV(ADEN);
ADCSRA |= _BV(ADIF);
}

volatile int f_wdt = 1; // 看门狗计数

ISR(WDT_vect)
{ // 看门狗唤醒执行函数
f_wdt++;
}

void wdt_setup(int ii)
{
// ii为看门狗超时时间,支持以下数值:
// 0=16毫秒, 1=32毫秒,2=64毫秒,3=128毫秒,4=250毫秒,5=500毫秒
// 6=1秒 ,7=2秒, 8=4秒, 9=8秒
byte bb;
if (ii > 9 ) ii = 9;
bb = ii & 7;
if (ii > 7) bb |= (1 << 5);
bb |= (1 << WDCE);
//开始设置看门狗中断
MCUSR &= ~(1<<WDRF); //清除复位标志
WDTCSR |= (1<<WDCE) | (1<<WDE);
//设置新的看门狗超时时间
WDTCSR = bb;
//设置为定时中断而不是复位
WDTCSR |= _BV(WDIE);
//别忘了设置【看门狗唤醒执行函数】
}

void enterSleep(void)
{ // 进入睡眠状态
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
sleep_disable();
power_all_enable();
}

void setup()
{
OFFACDDC();
wdt_setup(8);
}

void loop()
{
// 唤醒后是会运行loop的,这时候检查唤醒次数
if (f_wdt >= 15)
{
ONACDDC(); // 开启ADC,这样模拟输入IO口才可以恢复使用

// 正常流程


// 重置
f_wdt = 0;
OFFACDDC();
}

enterSleep(); // 继续休眠
}

arduino休眠唤醒
https://www.goozoe.com/posts/60922.html
作者
一起吃西瓜
发布于
2023年2月18日
许可协议