PWR & 低功耗三种模式

发布时间 2023-09-08 16:03:44作者: 磕伴

睡眠模式:

int main(void)
{
    OLED_Init();
    OLED_ShowString(1, 1, "RxData:");
    
    Serial_Init();
    
    while (1)
    {
        if (Serial_GetRxFlag() == 1)
        {
            RxData = Serial_GetRxData();
            Serial_SendByte(RxData);
            OLED_ShowHexNum(1, 8, RxData, 2);
        }
        
        OLED_ShowString(2, 1, "Running");
        Delay_ms(100);
        OLED_ShowString(2, 1, "       ");
        Delay_ms(100);

        __WFI();
    }
}
View Code

在低功耗下无法直接下载程序到单片机,需要长按复位按钮,然后点击下载后松开,就可下载成功

只有在发送数据时,单片机接收数据并处理,运行到__WFI();时就进入睡眠状态,(循环体里面的逻辑不再执行),等待唤醒:USART收到数据产生中断, 唤醒之后程序继续执行,因为此时有中断,所以直接进入到中断函数内处理逻辑,再进入主循环

 ---

 

cpu核心以1.8V(内核电压一般1.2-1.8V左右)供电(省电),对外转换成3.3V

三种低功耗模式,从上到下越来越省电(越来越难唤醒)

PDDS=0,进入停机模式,PDDS=1。进入待机模式 ;然后LPDS,用来设置最后这个电压调节器(0开启,1进入低功耗模式),再使用WFI或WFE命令,芯片就可以进入停机模式

SHI&HSE关闭,LHI&LSE(内外部低速时钟)若之前开启的话不会关闭【因为维持着RTC和看门狗IWDG】

电压调节器开启或低功耗都可以维持1.8V区域寄存器和存储器的数据内容,区别是更省电(唤醒时间更久)与否

待机模式:PDDS=1  SLEEPDEEP=1  +FEI或WFE 进入,只有特定唤醒。

 

 当停止后重新唤醒,HSI为系统时钟8M,此时需要重启HSE,配置主频率为72M  (Systemlnit函数)

 停止模式设置内核外的电路操作,需要用到PWR外设

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();
    }
}
View Code

 

示例用定时器间隔唤醒 

使用待机模式一定把外部耗电电路的元器件省去隔绝(LDO&指示发光二极管等),才能真正省电

int main(void)
{     //因为是从头开始运行,自动调用SystemInit();
    OLED_Init();
    MyRTC_Init();
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//开启PWR时钟
    
    OLED_ShowString(1, 1, "CNT :");
    OLED_ShowString(2, 1, "ALR :");
    OLED_ShowString(3, 1, "ALRF:");
    
    PWR_WakeUpPinCmd(ENABLE);//可以使用引脚触发高电平唤醒,使能后自动配置这个引脚
    
    uint32_t Alarm = RTC_GetCounter() + 10;
    RTC_SetAlarm(Alarm);
    OLED_ShowNum(2, 6, Alarm, 10);
    
    while (1)
    {
        OLED_ShowNum(1, 6, RTC_GetCounter(), 10); //随着CNT增大,会和设定的闹钟值ALR相等,触发闹钟标志位1(可开中断)
        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();
        
        PWR_EnterSTANDBYMode(); //开启待机
    }
}
View Code

 

 当VDD或VDDA电压过低时复位

 

 可编程PVD

正常供电3.3   ;

2.9-2.2 PVD监控【正常0,过低1】(提醒电压低), 可申请中断(外部中断【可以唤醒低功耗】),此时还可以正常工作

1.9就是复位电路工作了,不让动了