单片机睡眠模式详解:睡眠、停止与待机
目录
一、睡眠模式(Sleep Mode)
二、停止模式(Stop Mode)
三、待机模式(Standby Mode)
四、模式对比与选择
单片机在实际应用中,常常需要在等待任务或空闲时降低功耗,延长电池寿命。为此,现代单片机都提供了多种睡眠模式(低功耗模式),通过关闭不必要的硬件模块和降低时钟频率来减少能量消耗。
一、睡眠模式(Sleep Mode)
睡眠模式是最轻度的低功耗模式,主要特点是:
核心特性:
- CPU 停止工作,但所有外设和系统时钟仍正常运行
- 可以被任何中断或事件唤醒
- 唤醒后程序从断点处继续执行,无需重新初始化
会关闭的部分:
- CPU 核心停止运行
- 指令执行流水线暂停
不会关闭的部分:
- 所有系统时钟(HSE、HSI、PLL 等)继续运行
- 所有外设(定时器、UART、SPI、I2C 等)保持工作
- RAM 和寄存器内容保持不变
适用场景:
- 需要快速响应外部事件的应用
- 短时间等待(微秒到毫秒级)
- 需要外设继续工作的场景(如定时器中断)
典型应用:
- 数据采集系统中等待下一次采样
- 通信设备等待数据包
- 实时控制系统等待定时任务
二、停止模式(Stop Mode)
停止模式是中度低功耗模式,相比睡眠模式关闭了更多硬件:
核心特性:
- CPU 和大部分外设停止工作
- 主系统时钟关闭,但低速时钟可能保持运行
- RAM 和寄存器内容保持不变
- 只能被特定中断或唤醒引脚唤醒
会关闭的部分:
- CPU 核心停止运行
- 主系统时钟(HSE、HSI、PLL)关闭
- 大部分外设停止工作
可能保持运行的部分:
- 低速时钟(LSI、LSE)可配置为保持运行
- RTC(实时时钟)可继续工作
- 部分唤醒引脚保持响应
- RAM 和寄存器内容保持不变
适用场景:
- 需要较长时间等待(毫秒到秒级)
- 只需 RTC 或少数外设工作
- 需要保持数据在 RAM 中
典型应用:
- 定期采集数据的电池供电设备
- 需要 RTC 定时唤醒的系统
- 低功耗传感器节点
三、待机模式(Standby Mode)
待机模式是最深的低功耗模式,功耗最低:
核心特性:
- 几乎所有电路都停止工作
- RAM 和寄存器内容丢失(相当于系统复位)
- 只有少数关键引脚和模块保持工作
- 唤醒后系统重新启动,执行复位程序
会关闭的部分:
- CPU 核心停止运行
- 所有系统时钟关闭
- 所有外设停止工作
- RAM 和寄存器内容丢失
可能保持运行的部分:
- RTC(可配置)
- 电源管理单元
- 少数唤醒引脚
适用场景:
- 需要最长时间休眠(秒到小时级)
- 不需要保持数据在 RAM 中
- 仅需被特定事件唤醒的应用
典型应用:
- 遥控器
- 烟雾报警器
- 电池供电的物联网传感器节点
- 智能水表 / 电表
四、模式对比与选择
特性 | 睡眠模式 | 停止模式 | 待机模式 |
---|---|---|---|
功耗 | 较高 | 中等 | 最低 |
唤醒时间 | 最短(微秒级) | 中等(微秒到毫秒级) | 最长(毫秒级) |
数据保持 | 全部保持 | 全部保持 | 全部丢失 |
唤醒源 | 任何中断 / 事件 | 特定中断 / 唤醒引脚 | 少数特定唤醒源 |
适用等待时间 | 短(<1ms) | 中等(1ms-1s) | 长(>1s) |
Arduino——LowPower低功耗库测试代码:
#include <LowPower.h>// 定义LED引脚(板上内置LED为PIN 13)
#define LED_PIN 13void setup() {pinMode(LED_PIN, OUTPUT);Serial.begin(9600);// 启动提示Serial.println("Arduino低功耗模式测试开始...");Serial.println("将依次测试:正常模式 -> 睡眠模式 -> 停止模式 -> 待机模式");// 闪烁LED表示程序开始blinkLED(3, 200);
}void loop() {// 1. 正常模式运行Serial.println("\n--- 正常模式 ---");digitalWrite(LED_PIN, HIGH);delay(2000); // 正常模式延时2秒digitalWrite(LED_PIN, LOW);// 2. 进入睡眠模式(Idle模式)Serial.println("--- 进入睡眠模式 (8秒后唤醒) ---");// 睡眠8秒,可被任何中断唤醒LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF,TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);Serial.println("--- 从睡眠模式唤醒 ---");blinkLED(2, 300);// 3. 进入停止模式(Power-Down模式)Serial.println("--- 进入停止模式 (8秒后唤醒) ---");// 深度睡眠,仅保留定时器2或外部中断唤醒// 使用Watchdog Timer唤醒LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);Serial.println("--- 从停止模式唤醒 ---");blinkLED(2, 300);// 4. 进入待机模式(Power-Save模式)Serial.println("--- 进入待机模式 (8秒后唤醒) ---");// 保留定时器2运行,可用于定时唤醒LowPower.powerSave(SLEEP_8S, ADC_OFF, BOD_OFF);Serial.println("--- 从待机模式唤醒 ---");blinkLED(2, 300);// 循环测试delay(1000);
}// 闪烁LED函数
void blinkLED(int times, int duration) {for(int i = 0; i < times; i++) {digitalWrite(LED_PIN, HIGH);delay(duration);digitalWrite(LED_PIN, LOW);delay(duration);}
}