STM32低功耗寄存器开发与HAL库实战教程:附例程源码详解

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、低功耗是什么?
  • 二、三种低功耗模式
  • 1、睡眠模式
  • 进入睡眠模式
  • 退出睡眠模式
  • 2.停止模式
  • 进入停止模式
  • 退出停止模式
  • 注意
  • 3.待机模式
  • 进入待机模式
  • 退出待机模式
  • 注意
  • 总结
  • 参考文献

  • 前言

    在对续航要求比较高的产品中,往往需要控制功耗,stm32给我们提供了低功耗模式。
    例如 电压表,移动穿戴设备等等。
    下面是搜索关联:请无视。
    stm32功耗高怎么解决。
    低功耗方案。
    stm32低功耗寄存器开发
    stm32低功耗hal库开发”

    一、低功耗是什么?

    单片机的四种工作模式
    运行、睡眠、停止(停机)、待机。
    其中睡眠、停止(停机)、待机这三种模式属于地公告模式

    二、三种低功耗模式

    在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
    STM32F10xxx有三种低功耗模式:
    ● 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行)
    ● 停止模式(所有的时钟都已停止)
    ● 待机模式(1.8V电源关闭)

    此外,在运行模式下,可以通过以下方式中的一种降低功耗:
    ● 降低系统时钟
    ● 关闭APB和AHB总线上未被使用的外设时钟。
    这种方式我们应该都经常使用,例如系统时钟常常配置为72MHZ,为了降低功耗可以降低这个频率,当然降低频率后性能也会下降。我们可以在进入睡眠模式的前一刻降低系统时钟达到降低功耗的效果。唤醒后在切换回去
    还有使用到相应的外设使能对应的时钟,用不到的则不使能。并且在睡眠模式前关闭所有时钟,退出睡眠模式时在打开。
    这两种方式的一些知识都贯穿stm32的学习过程,应该比较好理解。

    1、睡眠模式

    进入睡眠模式

    通过执行WFI或WFE指令进入睡眠状态。根据Cortex™-M3系统控制寄存器中的SLEEPONEXIT位的值,有两种选项可用于选择睡眠模式进入机制:
    ● SLEEP-NOW:如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微控制器立即进入睡眠模式。
    ● SLEEP-ON-EXIT:如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。
    在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。

    退出睡眠模式

    如果执行WFI指令进入睡眠模式,任意一个被嵌套向量中断控制器响应的外设中断都能将系统从睡眠模式唤醒。
    如果执行WFE指令进入睡眠模式,则一旦发生唤醒事件时,微处理器都将从睡眠模式退出。唤醒事件可以通过下述方式产生:
    ● 在外设控制寄存器中使能一个中断,而不是在NVIC(嵌套向量中断控制器)中使能,并且在Cortex-M3系统控制寄存器中使能SEVONPEND位。当MCU从WFE中唤醒后,外设的中断挂起位和外设的NVIC中断通道挂起位(在NVIC中断清除挂起寄存器中)必须被清除。
    ● 配置一个外部或内部的EXIT线为事件模式。当MCU从WFE中唤醒后,因为与事件线对应的挂起位未被设置,不必清除外设的中断挂起位或外设的NVIC中断通道挂起位。该模式唤醒所需的时间最短,因为没有时间损失在中断的进入或退出上。

    在有些开发板的例程,在开启睡眠模式前要关闭SysTick中断,否则可能会唤醒stm32,。但经过我实际测试不关闭SysTick中断,也不会唤醒stm32。
    这一点有争议的可能是线面这句话,这句话是从stm32数据手册中摘抄下来的。
    ● 睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时
    钟(SysTick)等仍在运行)
    我的建议是关了总比不关好吧,哈哈,保守一点。不过在关闭后,唤醒时,要重新打开SysTick中断。

    下面程序的功能:
    SLEEP-NOW模式,立刻睡眠,WFI (中断唤醒)

    #define REGISTER 2
    
    void lpwr_enter_sleep(void)
    {
    #if REGISTER == 0/* HAL库开发 */
        HAL_SuspendTick();/* 关闭SysTick中断 */
        HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
        HAL_ResumeTick();/* 打开SysTick中断 */
    #elif REGISTER == 1
        /* 寄存器开发 1*/
        *((uint32_t *)0xE000E010) &= ~(1<<1);/* 关闭SysTick中断 */
        *((uint32_t *)0xE000ED10) &= ~(1<<1);// SLEEPONEXIT = 0
        *((uint32_t *)0xE000ED10) &= ~(1<<2);// SLEEPDEEP = 0
        __ASM volatile("wfi");//wfi指令
        *((uint32_t *)0xE000E010) |= 1<<1;/* 打开SysTick中断 */
    #elif REGISTER == 2
        /* 寄存器开发 2*/
        SysTick->CTRL &= ~(1<<1);/* 关闭SysTick中断 */
        SCB->SCR &= 1<<1;// SLEEPONEXIT = 0
        SCB->SCR &= 1<<2;// SLEEPDEEP = 0
        __ASM volatile("wfi");//wfi指令
        SysTick->CTRL |= 1<<1;/* 打开SysTick中断 */
    #endif
    }
    

    2.停止模式

    停止模式是在Cortex™-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止,PLL、SI和HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。
    在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。

    进入停止模式

    关于如何进入停止模式,详见表11。
    在停止模式下,通过设置电源控制寄存器(PWR_CR)的LPDS位使内部调节器进入低功耗模,
    能够降低更多的功耗。
    如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式。
    如果正在进行对APB的访问,直到对APB访问完成,系统才进入停止模式。
    可以通过对独立的控制位进行编程,可选择以下功能:
    电源控制(PWR)
    ● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了
    独立看门狗,除了系统复位,它不能再被停止。详见17.3节。
    ● 实时时钟(RTC):通过备份域控制寄存器 (RCC_BDCR)的RTCEN位来设置。
    ● 内部RC振荡器(LSI RC):通过控制/状态寄存器 (RCC_CSR)的LSION位来设置。
    ● 外部32.768kHz振荡器(LSE):通过备份域控制寄存器 (RCC_BDCR)的LSEON位设置。
    在停止模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。过设置寄存器ADC_CR2的ADON位和寄存器DAC_CR的ENx位为0可关闭这2个外设。

    退出停止模式

    关于如何退出停止模式,详见下表。
    当一个中断或唤醒事件导致退出停止模式时,HSI RC振荡器被选为系统时钟。
    当电压调节器处于低功耗模式下,当系统从停止模式退出时,将会有一段额外的启动延时。如
    果在停止模式期间保持内部调节器开启,则退出启动时间会缩短,但相应的功耗会增加。

    注意

    从停止模式被唤醒后需要需要重新设置时钟。因为被唤醒后,默认使用HSI

    #define REGISTER 2
    void lpwr_enter_stop(void)
    {
    #if REGISTER == 0/* HAL库开发 */
        __HAL_RCC_PWR_CLK_ENABLE();     /* 使能电源时钟 */
        HAL_SuspendTick();  /* 关闭SysTick中断 */
        HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);/* 进入停止模式,设置稳压器为低功耗模式,等待中断唤醒 */
        stm32_clock_init(RCC_PLL_MUL9);
        HAL_ResumeTick();/* 打开SysTick中断 */
        #elif REGISTER == 1
        
        #elif REGISTER == 2
        RCC->APB1ENR |= 1 << 28;        /* 使能电源时钟 */
        EXTI->PR = 1<<0;                /* 清除WKUP上的中断标志位 */
        PWR->CR |= 1 << 0;              /* LPDS=1, 停止模式下电压调节器处于低功耗模式 */
        PWR->CR &= ~(1 << 1);           /* PDDS=0, CPU深度睡眠时进入停止模式 */
        SCB->SCR |= 1 << 2;             /* 使能SLEEPDEEP位 */
        __ASM volatile("wfi");          //wfi指令
        SCB->SCR &= ~(1 << 2);          /* 关闭SLEEPDEEP位 */
        stm32_clock_init(RCC_PLL_MUL9); //这里重新设置时钟,为了省事就不用寄存器写了。类似的函数大家应该都有封装。
        #endif
    }
    

    3.待机模式

    待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电(见图4)。

    进入待机模式

    关于如何进入待机模式,详见表12。
    可以通过设置独立的控制位,选择以下待机模式的功能:
    ● 独立看门狗(IWDG):可通过写入看门狗的键寄存器或硬件选择来启动IWDG。一旦启动了独立看门狗,除了系统复位,它不能再被停止。详见17.3节。
    ● 实时时钟(RTC):通过备用区域控制寄存器(RCC_BDCR)的RTCEN位来设置。
    ● 内部RC振荡器(LSI RC):通过控制/状态寄存器(RCC_CSR)的LSION位来设置。
    ● 外部32.768kHz振荡器(LSE):通过备用区域控制寄存器(RCC_BDCR)的LSEON位设置。

    退出待机模式

    当一个外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件的上升沿发生时(见图154:简化的RTC框图),微控制器从待机模式退出。从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR)(见第4.4.2节),所有寄存器被复位。
    从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。电源控制/状态寄存器(PWR_CSR)(见第4.4.2节)将会指示内核由待机状态退出。

    注意

    待机模式唤醒后程序会复位,重新开始运行。





    总结

    以上就是本文的全部内容了,谢谢观看。

    参考文献

    正点原子例程,stm32官方例程,stm32官方文档。

    作者:achun_electronic

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32低功耗寄存器开发与HAL库实战教程:附例程源码详解

    发表回复