低功耗编程
一、修改主频
STM32F4xx系列主频为168MHz,当板载8MHz晶振时,系统时钟HCLK满足公式 H C L K = H S E × P L L N P L L M × P L L P HCLK = \frac{HSE \times PLLN}{PLLM \times PLLP} HCLK=PLLM×PLLPHSE×PLLN,在文件stm32f4xx.h
中可修改HSE
在文件system_stm32f4xx.c
中可修改锁相环参数
适当降低主频可降低开发板功耗
二、睡眠模式
在主函数的while
循环中加上睡眠模式函数__WFI()
,代码如下
c
while(1)
{
if(Serial_GetRxFlag() == 1)
{
RxData = Serial_GetRxData();
Serial_SendOneByte(RxData);
OLED_ShowHexNum(1, 8, RxData, 2);
}
OLED_ShowString(2, 1, "Running");
Delay_ms(500);
OLED_ShowString(2, 1, " ");
Delay_ms(100);
__WFI();//睡眠模式,但是外设还是处于工作状态
}
可通过中断唤醒系统,完成中断任务之后继续进入睡眠模式
三、停机模式
停机模式下,CPU和外设都没有时钟,而外部中断不需要时钟因此只有外部中断可以唤醒,通过stm32f4xx_pwr.c
中的函数PWR_EnterSTOPMode()
进入停机模式。
c
int main(void)
{
OLED_Init();
CountSensor_Init();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
OLED_ShowString(1, 1, "Count:");
while (1)
{
OLED_ShowNum(1, 7, CountSensor_Get(), 5);
OLED_ShowString(2, 1, "Running");
Delay_ms(100);
OLED_ShowString(2, 1, " ");
Delay_ms(100);
//第一个参数是指定电压调节器在停止模式里的状态
//第二个参数是选择进入停止模式的指令
PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
SystemInit();//重新启动HSE
}
}
当一个中断唤醒导致退出停机模式时,HSI被选为系统时钟,需要注意。
四、待机模式
待机模式唤醒后,程序是从头开始执行的,也就是PWR_EnterSTANDBYMode();
之后的语句不会被执行,而是直接从头开始运行。在进入待机模式之前,都要尽可能把外挂的模块都关掉,以达到省电目的。
c
int main(void)
{
OLED_Init();
MyRTC_Init();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
OLED_ShowString(1, 1, "CNT :");
OLED_ShowString(2, 1, "ALR :");
OLED_ShowString(3, 1, "ALRF:");
PWR_WakeUpPinCmd(ENABLE);//测试WKUP引脚上升沿唤醒功能
uint32_t Alarm = RTC_GetCounter() + 10; //设定闹钟
RTC_SetAlarm(Alarm); //闹钟寄存器是"只写"
OLED_ShowNum(2, 6, Alarm, 10);
while (1)
{
OLED_ShowNum(1, 6, RTC_GetCounter(), 10);
OLED_ShowNum(3, 6, RTC_GetFlagStatus(RTC_FLAG_ALR), 1);//查看闹钟标志位
OLED_ShowString(4, 1, "Running");
Delay_ms(100);
OLED_ShowString(4, 1, " ");
Delay_ms(100);
OLED_ShowString(4, 9, "STANDBY");
Delay_ms(1000);
OLED_ShowString(4, 9, " ");
Delay_ms(100);
OLED_Clear();//关闭OLED
PWR_EnterSTANDBYMode();//进入待机模式后通过闹钟事件唤醒
}
}