5.1实验内容
通过本实验主要学习以下内容:
- PMU原理;
- 低功耗的进入以及退出操作;
5.2实验原理
5.2.1PMU结构原理
PMU即电源管理单元,其内部结构下图所示,由该图可知,GD32F4xx系列MCU具有三个电源域,包括VDD/VDDA电源域、1.2V电源域以及电池备份域,其中,VDD /VDDA域由电源直接供电。在VDD/VDDA域中嵌入了一个LDO,用来为1.2V域供电。在备份域中有一个电源切换器,当VDD/VDDA电源关闭时,电源切换器可以将备份域的电源切换到VBAT引脚,此时备份域由VBAT引脚(电池)供电。
- VDD/VDDA电源域
VDD 域为数字电源域包括HXTAL(高速外部晶体振荡器)、LDO(电压调节器)、POR / PDR(上电/掉电复位)、FWDGT(独立看门狗定时器)和除PC13、PC14和PC15之外的所有PAD等等。另外,上图中与PMU控制器连接的PA0、NRST、FWDGT以及RTC表示待机模式下的唤醒源。VDDA域为模拟电源域包括ADC / DAC(AD / DA转换器)、IRC16M(内部16M RC振荡器)、IRC32K(内部32KHz RC振荡器)PLLs(锁相环)和LVD(低电压检测器)等等。
POR / PDR(上电/掉电复位) 电路检测VDD / VDDA并在电压低于特定阈值时产生电源复位信号复位除备份域之外的整个芯片。 下图显示了供电电压和电源复位信号之间的关系。VPOR表示上电复位的阈值电压,典型值约为2.45V,VPDR表示掉电复位的阈值电压,典型值约为1.82V。迟滞电压Vhyst值约为600mV。
GD32F4XX系列MCU具有LVD低电压检测功能,如下图所示,LVD的功能是检测VDD / VDDA供电电压是否低于低电压检测阈值,该阈值由电源控制寄存器(PMU_CTL) 中的LVDT[2:0]位进行配置。LVD通过LVDEN置位使能,位于电源状态寄存器(PMU_CS) 中的LVDF位表示低电压事件是否出现,该事件连接至EXTI的第16线,用户可以通过配置EXTI的第16线产生相应的中断。LVD中断信号依赖于EXTI第16线的上升或下降沿配置。迟滞电压Vhyst值为100mV。
|
- 1.2V电源域
1.2V 电源域为Cortex®-M4内核逻辑、AHB / APB外设、备份域和VDD / VDDA域的APB接口等供电。若系统系统工作在高频状态建议使能高驱模式。
- 电池备份域
电池备份域由内部电源切换器来选择VDD供电或VBAT(电池)供电,然后由VBAK为备份域供电,该备份域包含RTC(实时时钟)、LXTAL(低速外部晶体振荡器)、BPOR(备份域上电复位)、BREG(备份寄存器),以及PC13至PC15共3个BKPPAD。为了确保备份域中寄存器的内容及RTC正常工作,当VDD关闭时,VBAT引脚可以连接至电池或其他等备份源供电。电源切换器是由VDD / VDDA域掉电复位电路控制的。对于没有外部电池的应用,建议将VBAT引脚通过100nF的外部陶瓷去耦电容连接到VDD引脚上。
|
若读者有在VDD掉电情况下RTC继续工作的应用需求,需要VBAT引脚外接电池并使用LXTAL外部低频晶振,这样在VDD掉电的情况下,VBAT供电将会由VDD切换到VBAT,LXTAL和RTC均可正常工作,后续VDD上电后同步RTC寄存器即可获取正确的RTC时间。
5.2.2低功耗模式
GD32F4xx系列MCU具有三种低功耗模式,分别为睡眠模式、深度睡眠模式和待机模式。
睡眠模式与 Cortex®-M4 的SLEEPING模式相对应。在睡眠模式下,仅关闭Cortex®-M4的时钟,如需进入睡眠模式,只要清除Cortex®-M4系统控制寄存器中的SLEEPDEEP位,并执行一条WFI或WFE指令即可。
深度睡眠模式与 Cortex®-M4 的SLEEPDEEP模式相对应。在深度睡眠模式下,1.2V域中的所有时钟全部关闭,IRC16M、HXTAL及PLLs也全部被禁用。SRAM和寄存器中的内容被保留。根据PMU_CTL寄存器的LDOLP位的配置,可控制LDO工作在正常模式或低功耗模式。进入深度睡眠模式之前,先将Cortex®-M4系统控制寄存器的SLEEPDEEP位置1,再清除PMU_CTL寄存器的STBMOD位,然后执行WFI或WFE指令即可进入深度睡眠模式。如果睡眠模式是通过执行WFI指令进入的, 任何来自EXTI的中断可以将系统从深度睡眠模式中唤醒。如果睡眠模式是通过执行WFE指令进入的, 任何来自EXTI的事件可以将系统从深度睡眠模式中唤醒(如果SEVONPEND为1,任何来自EXTI的中断都可以唤醒系统,请参考Cortex®-M4技术手册)。 刚退出深度睡眠模式时,IRC16M被选中作为系统时钟。请注意,如果LDO工作在低功耗模式,那么唤醒时需额外的延时时间。
待机模式是基于 Cortex®-M4 的SLEEPDEEP模式实现的。在待机模式下,整个1.2V域全部停止供电,同时LDO和包括IRC16M、HXTAL和PLL也会被关闭。进入待机模式前,先将Cortex®-M4系统控制寄存器的SLEEPDEEP位置1,再将PMU_CTL寄存器的STBMOD位置1,再清除PMU_CS寄存器的WUF位,然后执行WFI或WFE指令,系统进入待机模式,PMU_CS寄存器的STBF位状态表示MCU是否已进入待机模式。待机模式有四个唤醒源,包括来自NRST引脚的外部复位,RTC唤醒事件,包括RTC侵入事件、RTC闹钟事件、RTC时间戳事件或RTC唤醒事件,FWDGT复位,WKUP引脚的上升沿。待机模式可以达到最低的功耗,但唤醒时间最长。另外,一旦进入待机模式,SRAM和1.2V电源域寄存器(除了备份SRAM,当BLDOON置位时)的内容都会丢失。退出待机模式时,会发生上电复位,复位之后Cortex®-M4将从0x00000000地址开始执行指令代码。
低功耗模式相关数据可参考下表,不同的低功耗模式是通过关闭不同时钟以及电源来实现的,关闭的时钟和电源越多,MCU所进入的睡眠模式将会越深,功耗也会越低,带来的唤醒时间也会越长,其唤醒源也会越少。睡眠模式是最浅的低功耗模式,仅关闭了CPU,代码不再运行,所有的中断或事件均可唤醒,唤醒时间也最快;深度睡眠模式时中间的低功耗模式,关闭了1.2V电源域时钟以及IRC8M/HXTAL/PLL,仅可通过EXTI中断或事件唤醒,唤醒后需要重新配置系统时钟;待机模式是功耗最低的低功耗模式,关闭了1.2V电源域电源以及IRC8M/HXTAL/PLL,仅可通过NRST/看门狗/RTC闹钟/WKUP引脚唤醒,唤醒后MCU将会复位重启。
各种睡眠模式下的功耗可以参考数据手册描述,睡眠模式下相较于同主频模式下的运行模式功耗减少约50%,深度睡眠和待机模式功耗更低,如下表所示,深度睡眠模式下功耗常温典型值为1.3ma,待机模式下功耗常温典型值为9uA。
|
5.3硬件设计
本例程stanby的唤醒使用到了PA0唤醒引脚,其电路如下所示。
5.4代码解析
本例程实现deepsleep以及standby的进入以及唤醒测试,首先我们来看下主函数,如下所示。该主函数首先配置了系统主时钟、延迟、打印和LED函数,并打印Example of Low Power Test Demo。之后查询是否进入过Standby模式,如果进入过Standby模式,表示当前状态为standby唤醒后的复位,则打印A reset event from Standby mode has occurred,并翻转LED2,因而验证standby唤醒的时候,其现象可观察到LED2的翻转。之后使能wakeup引脚的唤醒以及USER按键的初始化,此时将wakeup KEY配置为中断模式。在while(1)中,查询USER KEY按下的时间,如果按下超过3S,则打印Entering Standby Mode.并进入standby模式,如果USER KEY按下不超过3S,则打印Enter Deepsleep mode.并进入Deepsleep模式,从deepsleep模式唤醒后需要重新配置时钟,打印Exit Deepsleep mode.并翻转LED1。Standby的唤醒使用PA0 wakeup引脚,deepsleep的唤醒可使用任何EXTI中断,本实例中使用wakeup按键中断唤醒。
C int main(void) { rcu_periph_clock_enable(RCU_PMU); driver_init(); //注册按键扫描 driver_tick_handle[0].tick_value=10; driver_tick_handle[0].tick_task_callback=key_scan_10ms_callhandle; bsp_uart_init(&BOARD_UART); /* 板载UART初始化 */ printf_log("Example of Low Power Test Demo.\r\n"); delay_ms(2000); bsp_led_group_init(); /* 判断是否进入过Stanby模式 */ if(pmu_flag_get(PMU_FLAG_RESET_STANDBY)==SET) { printf_log("A reset event from Standby mode has occurred.\r\n"); bsp_led_toggle(&LED2); pmu_flag_clear(PMU_FLAG_RESET_STANDBY); } /* 配置PA0 Wakeup唤醒功能 */ pmu_wakeup_pin_enable(); WKUP_KEY.key_gpio->gpio_mode = INT_HIGH; WKUP_KEY.key_gpio->int_callback = WKUP_KEY_IRQ_callback; bsp_key_group_init(); nvic_irq_enable(EXTI0_IRQn,0,0); while (1) { /* 检测KEY1按键是否被按下,如果按下,进入standby模式 */ if(USER_KEY.press_timerms >= PRESS_3000MS) { USER_KEY.press_timerms=PRESS_NONE; printf_log("Entering Standby Mode.\r\n"); bsp_led_toggle(&LED2); pmu_to_standbymode(WFI_CMD); } /* 检测KEY2按键是否被按下,如果按下,进入Deepsleep模式 */ if(USER_KEY.press_timerms >= PRESS_50MS) { USER_KEY.press_timerms=PRESS_NONE; printf_log("Enter Deepsleep mode.\r\n"); bsp_led_toggle(&LED1); bsp_lcd_backlight_off(); pmu_to_deepsleepmode(PMU_LDO_NORMAL, PMU_LOWDRIVER_DISABLE, WFI_CMD); bsp_lcd_backlight_on(); printf_log("Exit Deepsleep mode.\r\n"); bsp_led_toggle(&LED1); } } } |
5.5实验结果
将本实验历程烧录到紫藤派开发板中,按下user key按键超过3S,松开后MCU将进入standby模式,并打印Entering Standby Mode.,然后按下wakeup按键,将从stanby模式唤醒,打印A reset event from Standby mode has occurred.并翻转LED2,之后短按USER KEY,将打印Enter Deepsleep mode.进入deepsleep模式,然后按下wakeup按键将从deepsleep模式下唤醒,唤醒后重新配置时钟,打印Exit Deepsleep mode.并将LED1翻转。
具体现象如下所示。
-
单片机
+关注
关注
6035文章
44554浏览量
634634 -
低功耗
+关注
关注
10文章
2396浏览量
103670 -
开发板
+关注
关注
25文章
5032浏览量
97371 -
PMU
+关注
关注
1文章
108浏览量
21592 -
GD32
+关注
关注
7文章
403浏览量
24328
发布评论请先 登录
相关推荐
评论