STM32F103VE 三种低功耗模式
STM32F103VE 低功耗模式详解及示例代码
STM32F103VE 提供了三种低功耗模式,每种模式的特点如下:
1. 睡眠模式 (Sleep Mode)
特点:
- 仅CPU停止工作,外设继续运行
- 任何中断或事件都可以唤醒
- 唤醒时间最短
- 功耗降低最少
2. 停止模式 (Stop Mode)
特点:
- 所有时钟停止(HCLK, PCLK1, PCLK2)
- 1.8V区域供电保持
- SRAM和寄存器内容保持
- 外部中断或RTC闹钟可以唤醒
- 唤醒后时钟配置需要重新初始化
3. 待机模式 (Standby Mode)
特点:
- 最低功耗模式
- 1.8V区域断电(除了备份域和待机电路)
- SRAM和寄存器内容丢失(除了备份寄存器)
- 只有特定事件可以唤醒(WKUP引脚上升沿、RTC闹钟、NRST引脚外部复位)
- 唤醒后相当于复位重启
示例代码(使用标准库)
1. 睡眠模式
#include "stm32f10x.h"void Enter_Sleep_Mode(void)
{// 配置PA0为外部中断GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);// PA0配置为上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOA, &GPIO_InitStructure);// 配置EXTI线0GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿和下降沿EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);// 配置NVICNVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);// 进入睡眠模式__WFI(); // 等待中断唤醒
}void EXTI0_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line0) != RESET){EXTI_ClearITPendingBit(EXTI_Line0);// 唤醒后的处理}
}
2. 停止模式
void Enter_Stop_Mode(void)
{// 配置PA0为外部中断(与睡眠模式相同)// ...// 进入停止模式前可以选择降低电压调节器功耗PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);// 唤醒后需要重新配置系统时钟SystemInit(); // 重新初始化系统时钟
}void EXTI0_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line0) != RESET){EXTI_ClearITPendingBit(EXTI_Line0);// 唤醒后的处理}
}
3. 待机模式
// 检测是否从待机唤醒if (Check_WakeUpFromStandby()) {// 这里是唤醒后的特殊处理代码// 例如:点亮LED指示唤醒LED2_ON;GUI_Delay(500);LED2_OFF;ShowCommon();ShowStateScreen();goto USER_CODE;}// 配置PA0为唤醒引脚(WKUP)
void WKUP_Init(void) {GPIO_InitTypeDef GPIO_InitStructure;// 1. 使能GPIOA和PWR时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);// 2. 配置PA0为下拉输入(因为按键接3.3V)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入GPIO_Init(GPIOA, &GPIO_InitStructure);// 3. 使能WKUP引脚唤醒功能PWR_WakeUpPinCmd(ENABLE);
}// 关闭所有可能引起唤醒的外设
void Disable_Wakeup_Sources(void) {// 1. 禁用所有中断(除了EXTI0)NVIC->ICER[0] = 0xFFFFFFFF; // 禁用所有32个中断NVIC_EnableIRQ(EXTI0_IRQn); // 重新启用EXTI0中断// 2. 关闭不必要的外设时钟RCC->APB2ENR = 0;//RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, DISABLE);RCC->APB1ENR = 0;//RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, DISABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);// 3. 配置未使用的GPIO为模拟输入(降低功耗)GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_All;GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_Init(GPIOB, &GPIO_InitStruct);GPIO_Init(GPIOC, &GPIO_InitStruct);// 4. 特别关闭串口等可能产生中断的外设USART_Cmd(USART1, DISABLE);USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);USART_Cmd(USART2, DISABLE);USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);USART_Cmd(UART4, DISABLE);USART_ITConfig(UART4, USART_IT_RXNE, DISABLE);
}// 进入待机模式
void Enter_StandbyMode(void) {// 1. 清除所有唤醒标志PWR_ClearFlag(PWR_FLAG_WU);// 2. 禁用所有可能产生唤醒的外设Disable_Wakeup_Sources();// 3. 进入待机模式PWR_EnterSTANDBYMode();// 4. 唤醒后会从复位开始执行
}
主程序示例
int main(void)
{// 系统初始化SystemInit();// 其他初始化代码...while(1){// 检测按键按下if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0) // 按键按下(低电平,因为上拉到VCC){// 消抖Delay_ms(20);if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0){// 选择进入哪种低功耗模式// Enter_Sleep_Mode();// Enter_Stop_Mode();Enter_Standby_Mode();}while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0); // 等待按键释放}}
}
注意事项
- 进入低功耗模式前,应关闭不必要的外设时钟
- 停止模式唤醒后需要重新初始化系统时钟
- 待机模式唤醒后相当于复位,程序会从头开始执行
- 实际应用中需要根据需求选择适当的低功耗模式
- 唤醒源需要根据具体模式进行配置
以上代码基于STM32标准外设库,实际使用时需要根据具体硬件和需求进行调整。