[APM32F0] F0与F1系列的低功耗模式学习

[复制链接]
 楼主| 1455555 发表于 2023-12-22 13:28 | 显示全部楼层 |阅读模式
本帖最后由 1455555 于 2023-12-25 15:43 编辑

1、引言
在不需要微控制器运行时,可以使其进入低功耗模式,降低系统功耗。当需要微控制器运行时,再唤醒即可。
这段时间我学习了一下几种低功耗模式。参考了APM32F072(M0),APM32F003(M0),APM32F103(M3)三款芯片,发现他们的低功耗模式有一些差异。下面我将从三款芯片各自的用户手册中摘出低功耗相关表格。
APM32F4XX
f4.png
APM32F103
f103.png
APM32F072
f072.png
APM32F003
f003.png
根据贴出来的四张图可以发现M3,M4内核的产品和072的低功耗模式都分为三种:睡眠模式、停止模式和待机模式。但003特立独行,分为等待模式、快速活跃停机模式、慢速活跃停机模式、停机模式四种。
仔细对比每个模式下的各个设置,发现003的四种和072的三种并没有能完全吻合的分类。下面将其放置在一张表格中,可能更清晰一些。
表.png

2、例程介绍
接下来每款芯片介绍一种模式下的唤醒例程。

2、1 F003等待模式串口中断唤醒
注意到F003等待模式下的唤醒方式可以为所有外部内部中断。这里我们使用串口中断作为唤醒方式。例程设置等待一段时间后,系统自动进入低功耗模式下。在串口助手发送任意字符可以唤醒MCU。
  1. void Delay(void);
  2. void USART_WakeUp_Init(void);

  3. int main(void)
  4. {
  5.     volatile uint8_t i = 10;
  6.     APM_MINI_LEDInit(LED2);
  7.    
  8.     USART_WakeUp_Init();
  9.    
  10.     while(1)
  11.     {
  12.         APM_MINI_LEDToggle(LED2);
  13.         Delay();
  14.         if(i)
  15.         {
  16.             i--;
  17.             if(i == 0)
  18.             {
  19.                 PMU_EnterWaitMode();
  20.             }
  21.         }
  22.     }
  23. }
例程中给出是否进入低功耗信号:LED灯是否闪烁。进入等待模式后,CPU停止,代码运行停止在进入低功耗这句指令后。唤醒后,从该指令后开始继续执行。所以,记得在进入低功耗之前对串口进行配置,设置好唤醒方式。在中断服务函数中,等待标志位后,只进行了清除操作。
  1. void USART1_RX_IRQHandler(void)
  2. {
  3.     if(USART_ReadIntFlag(USART1,USART_INT_FLAG_RX) == SET)
  4.     {
  5.        USART_ClearIntFlag(USART1,USART_INT_FLAG_RX);
  6.     }
  7. }
这个例程前期没有加入再次进入低功耗的处理。如果平时正常使用,可以在前面加入一个按键,在按键按下时,进入睡眠模式。串口接收数据时,唤醒CPU。唤醒后需要进入睡眠模式,再次按下按键即可。
2、2 F003活跃停机模式下通过WUPT唤醒
活跃停机分为快速活跃停机和慢速活跃停机模式,快速活跃停机模式唤醒时间在低功耗唤醒时间里最短。(为啥?如果是因为主电压调节器,那睡眠模式下主电压调节器也开着啊?)
2_2.png
例程使用WUPT,在一定的延时后产生一个内部唤醒事件,延迟时间可由编程设置。编程中发现标准库里有WUPT延时设置封装好的函数,直接使用。
  1. #include "main.h"

  2. void Delay(void);

  3. int main(void)
  4. {
  5.     volatile uint8_t i = 10;
  6.     APM_MINI_LEDInit(LED2);
  7.    
  8.     while(1)
  9.     {
  10.         APM_MINI_LEDToggle(LED2);
  11.         Delay();
  12.         i--;
  13.         if(i == 0)
  14.         {
  15.             i = 10;
  16.             APM_MINI_LEDOff(LED2);
  17.             WUPT_Config(AWU_TIMEBASE_2S);
  18.             NVIC_EnableIRQRequest(WUPT_IRQn,0X01);
  19.             PMU_EnterHaltModeWFI();
  20.         }
  21.     }
  22. }

  23. void Delay(void)
  24. {
  25.     volatile uint32_t delaytime = 0xfffff;
  26.     while(delaytime--);
  27. }
其中WUPT_Config()
  1. void WUPT_Config(WUPT_TIMEBASE_T timeBase)
  2. {
  3.     WUPT->TBC = (uint32_t)g_timeBaseTab[(uint32_t)timeBase];

  4.     WUPT->DIV = (uint32_t)g_dividerTab[(uint32_t)timeBase];

  5.     WUPT->CSTS_B.WUPTEN = BIT_SET;
  6. }
2.3 F072待机模式下使用WAKEUP_PIN唤醒
待机模式下所有外设都关闭,CPU与主电压调节器都关闭。例程为按下按键产生中断,在中断中进入待机模式。进入待机模式前,使能WAKEPIN。WAKEUP_PIN对应引脚查找数据手册引脚分布图。
2_3.png
  1. void Delay(uint32_t count);

  2. int main(void)
  3. {
  4.     APM_MINI_LEDInit(LED2);
  5.     APM_MINI_LEDInit(LED3);
  6.     APM_MINI_PBInit(BUTTON_KEY2, BUTTON_MODE_EINT);
  7.     APM_MINI_COMInit(COM1);

  8.     PMU_Reset();
  9.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);

  10.     /* Enable PC13 as system WakeUp pin for standby mode */
  11.     PMU_EnableWakeUpPin(PMU_WAKEUPPIN_2);

  12.     printf("\r\nSystem is Init\r\n");
  13.     printf("Press KEY2   : ENTER StandBy Mode\r\n");

  14.     for (;;)
  15.     {
  16.         Delay(0xfffff);
  17.         APM_MINI_LEDToggle(LED2);
  18.         APM_MINI_LEDToggle(LED3);
  19.         printf("\r\nSystem is running\r\n");
  20.     }
  21. }

  22. void APM_MINI_PB_PMU_Isr()
  23. {
  24.     if (EINT_ReadStatusFlag(EINT_LINE0) == SET)
  25.     {
  26.         printf("\r\nSystem have entered STANDBY mode\r\n");
  27.         printf("now, LED2 and LED3 is off\r\n");
  28.         printf("please give PC13 a rising edge or reset System to recover System\r\n\r\n");

  29.         /* Clear flag bit to prevent repeated entry interrupt*/
  30.         PMU_ClearStatusFlag(PMU_FLAG_STDBYF);
  31.         PMU_ClearStatusFlag(PMU_FLAG_WUPF);

  32.         /* Enter StandBy Mode*/
  33.         PMU_EnterSTANDBYMode();
  34.         EINT_ClearStatusFlag(EINT_LINE0);
  35.     }
  36. }

  37. void Delay(uint32_t count)
  38. {
  39. volatile uint32_t delay = count;
  40.   while (delay--);
  41. }
2.4 F103停止模式下通过按键唤醒
这个例程可以通过选择是否定义KEY1_WAKEUP来决定是否需要使用按键唤醒,同时,可以通过定义REGULATOR_ON/LowPower选择停止模式下电压调节器的模式。前面对IO的配置用于满足低功耗模式功耗测试的要求。
  1. #define DEBUG_USART USART1

  2. /*choose which condition of STANDBY MODE to enter*/
  3. #define REGULATOR_ON
  4. //#define REGULATOR_OFF

  5. /*choose if need key1 to wake up*/
  6. #define KEY1_WAKEUP

  7. void Delay(uint32_t count);

  8. int main(void)
  9. {
  10.     GPIO_Config_T  gpioConfig;

  11.     /* Disable clock to reduce current consumption*/
  12.     RCM_DisableHSI();
  13.    
  14.     /*Disable LSE to reduce current consumption*/
  15.     RCM_EnableAPB1PeriphClock((RCM_APB1_PERIPH_T)(RCM_APB1_PERIPH_PMU | RCM_APB1_PERIPH_BAKR));
  16.     PMU->CTRL_B.BPWEN = 0X01;
  17.     RCM_ConfigLSE(RCM_LSE_CLOSE);
  18.     RCM_DisableAPB1PeriphClock(RCM_APB1_PERIPH_BAKR);
  19.    
  20.     /* Configure all GPIO as analog to reduce current consumption on non used IOs */
  21.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOB | RCM_APB2_PERIPH_GPIOC |
  22.                               RCM_APB2_PERIPH_GPIOD | RCM_APB2_PERIPH_GPIOE | RCM_APB2_PERIPH_GPIOF | RCM_APB2_PERIPH_GPIOG) ;
  23.    
  24.     gpioConfig.mode = GPIO_MODE_ANALOG;
  25.     gpioConfig.pin = GPIO_PIN_ALL;
  26.     GPIO_Config(GPIOA,&gpioConfig);
  27.     GPIO_Config(GPIOB,&gpioConfig);
  28.     GPIO_Config(GPIOC,&gpioConfig);
  29.     GPIO_Config(GPIOD,&gpioConfig);
  30.     GPIO_Config(GPIOE,&gpioConfig);
  31.     GPIO_Config(GPIOF,&gpioConfig);
  32.     GPIO_Config(GPIOG,&gpioConfig);
  33.    
  34.     RCM_DisableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOB | RCM_APB2_PERIPH_GPIOC |
  35.                               RCM_APB2_PERIPH_GPIOD | RCM_APB2_PERIPH_GPIOE | RCM_APB2_PERIPH_GPIOF | RCM_APB2_PERIPH_GPIOG);
  36.    
  37.     #ifdef KEY1_WAKEUP
  38.       /* Config KEY1 to wake up cpu from stop mode*/
  39.       APM_MINI_PBInit(BUTTON_KEY1, BUTTON_MODE_EINT);
  40.     #endif

  41.     /* Enable PMU Periph Clock */
  42.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_PMU);
  43.     PMU_Reset();
  44.    
  45.     Delay(0x6fffff);
  46.    
  47.     #ifdef REGULATOR_ON
  48.       PMU_EnterSTOPMode(PMU_REGULATOR_ON,PMU_STOP_ENTRY_WFI);
  49.     #elif defined REGULATOR_LowPower
  50.       PMU_EnterSTOPMode(PMU_REGULATOR_LOWPOWER,PMU_STOP_ENTRY_WFI);
  51.     #endif
  52.    
  53.     APM_MINI_LEDInit(LED2);

  54.     while(1)
  55.     {
  56.         APM_MINI_LEDToggle(LED2);
  57.         Delay(0xfffff);  
  58.     }
  59. }

  60. void Eint1_Isr(void)
  61. {
  62.     if (EINT_ReadIntFlag(KEY1_BUTTON_EINT_LINE) != RESET)
  63.     {
  64.         SystemInit();
  65.         EINT_ClearIntFlag(KEY1_BUTTON_EINT_LINE);
  66.     }
  67. }
3、总结
在低功耗学习中,我尝试测试进入低功耗模式下的功耗,编写了相应满足测试条件的代码。测出的数据没办法达到手册理想值,后面了解到数据手册上的理想值为测试部门使用专门的功耗版,放置裸片测试的结果。如果我们测试想要达到理想数值,那么需要对照原理图,把相关影响项断开,进行测试。制作小玩意时,可以尝试进入睡眠模式,通过语音唤醒等外部事件进行唤醒,降低产品使用的功耗。

10299823 发表于 2024-1-3 11:48 | 显示全部楼层
单片机都支持多种低功耗模式,包括睡眠模式、停止模式和待机模式。
jkl21 发表于 2024-1-3 12:35 | 显示全部楼层
在长时间无操作但需维持RTC和小部分外设运行的情况下,可能选择STOP模式;而在系统长时间休眠仅需维持极低功耗和RTC运行时,则可能选择STANDBY模式。
zerorobert 发表于 2024-1-3 13:22 | 显示全部楼层
睡眠模式              
pixhw 发表于 2024-1-3 13:46 | 显示全部楼层
旨在根据应用需求降低芯片的能耗。
plsbackup 发表于 2024-1-3 14:09 | 显示全部楼层
提供了多种低功耗模式,包括睡眠模式、停止模式和待机模式
sanfuzi 发表于 2024-1-3 14:27 | 显示全部楼层
根据实际需求选择合适的低功耗模式。例如,如果需要快速唤醒,可以选择待机模式;如果需要长时间保持低功耗,可以选择深度睡眠模式。
zerorobert 发表于 2024-1-3 17:53 | 显示全部楼层
可以使用 标准库函数,如PWR_EnterSleepMode()、PWR_EnterSTOPMode()和PWR_EnterSTANDBYMode()。
wilhelmina2 发表于 2024-1-3 18:30 | 显示全部楼层
这些模式可以通过不同的方式实现,例如使用时钟控制或电源管理功能。
qiufengsd 发表于 2024-1-3 19:51 | 显示全部楼层
要实现低功耗模式,需要配置相应的寄存器和外设。
uptown 发表于 2024-1-3 20:11 | 显示全部楼层
待机模式:这是最低的功耗模式,它会关闭1.8V的内核电源。在这种模式下,只有特定的事件和引脚才能唤醒单片机,因此它的实时性可能不如其他模式。
huquanz711 发表于 2024-1-4 08:04 来自手机 | 显示全部楼层
M0内核的功耗要比M3内核的功耗低一些
elsaflower 发表于 2024-1-4 09:53 | 显示全部楼层
当需要从低功耗模式唤醒时,可以通过外部中断、定时器溢出、串口接收等事件来实现。
vivilyly 发表于 2024-1-4 10:24 | 显示全部楼层
睡眠模式是最低的功耗模式,其中微控制器的所有时钟都被关闭,除了维持核心功能的时钟(如RTC和WDT)。在睡眠模式下,CPU不运行任何代码,但可以唤醒以响应外部中断。
earlmax 发表于 2024-1-4 10:54 | 显示全部楼层
F0和F1系列都提供了低功耗模式,这些模式有助于降低系统的功耗。
dspmana 发表于 2024-1-4 11:24 | 显示全部楼层
主要包括以下几种:

睡眠模式(Sleep Mode)
停止模式(Stop Mode)
待机模式(Standby Mode)
深度睡眠模式(Deep-sleep Mode)
深待机模式(Power-down Mode)
houjiakai 发表于 2024-1-4 11:55 | 显示全部楼层
F0和F1系列的具体低功耗模式实现可能会根据具体型号和硬件架构有所不同
qiufengsd 发表于 2024-1-4 12:25 | 显示全部楼层
掌握如何正确设置进入和退出低功耗模式的代码,特别是关于时钟配置、GPIO状态保存与恢复、外设电源管理等方面的处理。
chenci2013 发表于 2024-1-4 13:35 | 显示全部楼层
在停止模式下,CPU不执行任何代码,但某些外设(如定时器或ADC)可以继续运行,以便在唤醒时立即恢复操作。
phoenixwhite 发表于 2024-1-4 16:37 | 显示全部楼层
需考虑外部中断、定时器等硬件资源的合理配置,以实现低功耗与性能之间的平衡
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

17

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部