开发环境:
MDK:Keil 5.30
开发板:GD32F207I-EVAL
MCU:GD32F207IK
1 GD32电源管理
GD32的工作电压(VDD)为2.0~3.6V。通过内置的电压调节器提供所需的1.8V电源。当主电源VDD掉电后,通过VBAT脚为实时时钟(RTC)和备份寄存器提供电源。
使用电池或其他电源连接到VBAT脚上,当VDD断电时,可以保存备份寄存器的内容和维持RTC的功能。
VBAT脚为RTC、 LSE振荡器和PC13至PC15端口供电,可以保证当主电源被切断时RTC能继续工作。切换到VBAT供电的开关,由复位模块中的掉电复位功能控制。
当备份域由VDD供电(VBAK连接至VDD)时,以下功能可用:
● PC13可以作为通用I/O口或RTC功能引脚;
● PC14和PC15可以作为通用I/O口或LXTAL晶振引脚。
● PI8可以作为通用I/O口或RTC功能引脚
当备份域由VBAT电源供电时(VBAK连接至VBAT),以下功能可用:
● PC13仅可以作为RTC功能引脚;
● PC14和PC15仅可作为LXTAL晶振引脚。
● PI8仅可以作为RTC功能引脚
注意:由于PC13至PC15引脚是通过电源切换器供电的,电源切换器仅可通过小电流,因此当PC13至PC15的GPIO口在输出模式时,其工作的速度不能超过2MHz(最大负载为30pF)。
2 GD32低功耗模式
在系统或电源复位以后,微控制器处于运行状态。当CPU不需继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个外部事件时。用户需要根据最低电源消耗、最快速启动时间和可用的唤醒源等条件,选定一个最佳的低功耗模式。
GD32F207有三种低功耗模式:
睡眠模式(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行)
● 深度睡眠/停止模式(所有的时钟都已停止)
● 待机模式(1.8V电源关闭)
此外,在运行模式下,可以通过以下方式中的一种降低功耗:
● 降低系统时钟
● 关闭APB和AHB总线上未被使用的外设时钟。
从表中可以看到,这三种低功耗模式层层递进,运行的时钟或芯片功能越来越少,因而功耗越来越低。
在睡眠模式中,仅关闭了 CPU 时钟, CPU 停止运行 ,但其片上外设,CM3 核心外设全都还照常运行。有两种方式进入睡眠模式,它的进入方式决定了从睡眠唤醒的方式,分别是 WFI(wait for interrupt)和 WFE(wait for event),即由等待“中断”唤醒和由“事件”唤醒。
在深度睡眠模式中, 进一步关闭了其它所有的时钟 ,于是所有的外设都停止了工作,但由于其 1.8V 区域的电源没有关闭,还保留了 CPU 的寄存器、内存的信息,所以深度睡眠模式唤醒,并重新开启时钟后,还可以从上次深度睡眠处继续执行代码。深度睡眠模式可以由任意一个外部中断(EXTI)唤醒。在深度睡眠模式中可以选择电压调节器为开模式或低功耗模式,若选择低功耗模式,在唤醒时会加上电压调节器的唤醒延迟。
待机模式,这与我们平时印象中的手机关机模式相似,它除了关闭所有的时钟,还把1.8V 区域的电源也关闭了,也就是说,从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测 boot 条件,从头开始执行程序。它有四种唤醒方式,分别是 WKUP(PA0)引脚的上升沿,RTC 闹钟事件,NRST 引脚的复位和FWDGT复位。
在运行模式下,任何时候都可以通过停止为外设和内存提供时钟来减少功耗。为了在睡眠模式下更多地减少功耗,可在执行WFI或WFE指令前关闭所有外设的时钟。
通过设置AHB外设时钟使能寄存器、APB2外设时钟使能寄存器和APB1外设时钟使能寄存器来开关各个外设模块的时钟。
2.1睡眠模式
进入睡眠模式
通过执行WFI或WFE指令进入睡眠状态。根据Cortex™-M3中SCR(系统控制寄存器)的SLEEPONEXIT位,有两种睡眠进入机制选项:
● Sleep-now:如果SLEEPONEXIT位被清零,一旦执行WFI或WFE指令, MCU立即进入睡眠模式;
● Sleep-on-exit:如果SLEEPONEXIT位被置位,当系统从最低优先级的中断处理程序离开后, MCU立即进入睡眠模式。
在睡眠模式下,所有的I/O引脚都保持它们在运行模式时的状态。
退出睡眠模式
如果执行WFI指令进入睡眠模式,任意一个被嵌套向量中断控制器响应的外设中断都能将系统从睡眠模式唤醒。
如果执行WFE指令进入睡眠模式,则一旦发生唤醒事件时,微处理器都将从睡眠模式退出。唤醒事件可以通过下述方式产生:
● 在外设控制寄存器中使能一个中断,而不是在NVIC(嵌套向量中断控制器)中使能,并且在Cortex-M3系统控制寄存器中使能SEVONPEND位。当MCU从WFE中唤醒后,外设的中断挂起位和外设的NVIC中断通道挂起位(在NVIC中断清除挂起寄存器中)必须被清除。
● 配置一个外部或内部的EXIT线为事件模式。当MCU从WFE中唤醒后,因为与事件线对应的挂起位未被设置,不必清除外设的中断挂起位或外设的NVIC中断通道挂起位。
该模式唤醒所需的时间最短,因为没有时间损失在中断的进入或退出上。
| SLEEP-NOW****模式 | 说明 |
|---|---|
| 进入 | 在以下条件下执行WFI(等待中断)或WFE(等待事件)指令: –SLEEPDEEP = 0和–SLEEPONEXIT = 0参考Cortex-M3系统控制寄存器。 |
| 退出 | 如果执行WFI进入睡眠模式:中断。 如果执行WFE进入睡眠模式:唤醒事件。 |
| 唤醒延时 | 无 |
| SLEEP-ON_EXIT****模式 | 说明 |
|---|---|
| 进入 | 在以下条件下执行WFI指令:–SLEEPDEEP = 0和–SLEEPONEXIT = 1参考Cortex™-M3系统控制寄存器 |
| 退出 | 中断:参考中断向量表 |
| 唤醒延时 | 无 |
2.2 深度睡眠模式
深度睡眠模式是在Cortex™-M3的深睡眠模式基础上结合了外设的时钟控制机制,深度睡眠模式与 Cortex™-M3 的 SLEEPDEEP 模式相对应。在深度睡眠模式下,1.2V 域中的所有时钟全部关闭,IRC8M、HXTAL及PLLs 也全部被禁用。SRAM和寄存器中的内容被保留。
在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。
进入深度睡眠模式
在深度睡眠模式下,通过设置电源控制寄存器PMU_CTL的LDOLP位使内部调节器进入低功耗模式,能够降低更多的功耗。
如果正在进行闪存编程,直到对内存访问完成,系统才进入深度睡眠模式。
如果正在进行对APB的访问,直到对APB访问完成,系统才进入深度睡眠模式。可以通过对独立的控制位进行编程。
在深度睡眠模式下,如果在进入该模式前ADC和DAC没有被关闭,那么这些外设仍然消耗电流。
退出深度睡眠模式
当一个中断或唤醒事件导致退出深度睡眠模式时,IRC8M、IRC40K振荡器被选为系统时钟。
当电压调节器处于低功耗模式下,当系统从深度睡眠模式退出时,将会有一段额外的启动延时。如果在深度睡眠模式期间保持内部调节器开启,则退出启动时间会缩短,但相应的功耗会增加。
| 深度睡眠模式 | 说明 |
|---|---|
| 进入 | 在以下条件下执行WFI(等待中断)或WFE(等待事件)指令: –设置Cortex-M3系统控制寄存器中的SLEEPDEEP位 –清除电源控制寄存器(PMU_CTL)中的STBMOD位 –通过设置PMU_CTL中LDOLP位选择电压调节器的模式 注:为了进入停止模式,所有的外部中断的请求位(挂起寄存器)和RTC的闹钟标志都必须被清除,否则停止模式的进入流程将会被跳过,程序继续运行。 |
| 退出 | 如果执行WFI进入停止模式: 设置任一外部中断线为中断模式(在NVIC中必须使能相应的外部中断向量)。参见中断向量。 如果执行WFE进入停止模式: 设置任一外部中断线为事件模式。参见唤醒事件管理。 |
| 唤醒延时 | IRC8M、IRC40K唤醒时间+电压调节器从低功耗唤醒的时间。 |
2.3待机模式
待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。IRC8M、HXTAL 和 PLL振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
进入待机模式
进入待机模式前,先将Cortex™-M3 系统控制寄存器的 SLEEPDEEP 位置 1,再将 PMU_CTL 寄存器的 STBMOD 位置 1,再清除 PMU_CS 寄存器的 WUF 位,然后执行 WFI 或 WFE 指令,系统进入待机模式,PMU_CS 寄存器的 STBF 位状态表示 MCU 是否已进入待机模式。
退出待机模式
当一个外部复位(NRST引脚)、 FWDGT复位、 WKUP引脚上的上升沿或RTC闹钟事件的上升沿发生时,微控制器从待机模式退出。从待机唤醒后,除了电源控制/状态寄存器(PWR_CS),所有寄存器被复位。
从待机模式唤醒后的代码执行等同于复位后的执行(采样启动模式引脚、读取复位向量等)。 电源控制/状态寄存器(PWR_CS)将会指示内核由待机状态退出。
待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。IRC8M、HXTAL 和 PLL振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
| 待机模式 | 说明 |
|---|---|
| 进入 | 在以下条件下执行WFI(等待中断)或WFE(等待事件)指令: –设置Cortex™-M3系统控制寄存器中的SLEEPDEEP位 –设置电源控制寄存器(PWR_CTL)中的STBMOD位 –清除电源控制/状态寄存器(PWR_CS)中的WUF位 |
| 退出 | WKUP引脚的上升沿、RTC闹钟事件的上升沿、NRST引脚上外部复位、FWDGT复位。 |
| 唤醒延时 | 复位阶段时电压调节器的启动 |
3 低功耗的寄存器描述
电源控制寄存器(PWR_CTL),该寄存器的各位描述如下图所示:
我们通过设置 PWR_CTL的 STBMOD位,使 CPU 进入深度睡眠时进入待机模式。
电源控制/状态寄存器( PWR_CS)的各位描述如图所示。
通过设置 PWR_CS的 WUPEN 位,来使能 WKUP 引脚用于待机模式唤醒。我们还可以从 WUF 来检查是否发生了唤醒事件。
4 低功耗具体代码实现
通过以上介绍,我们了解了进入低功耗模式的三种方法,在者三种模式中待机模式功耗最低。笔者这里使用的是按键唤醒,其电路如下:
4.1睡眠模式
睡眠模式很简单,就是通过以下指令进入睡眠:
__WFI();
__WFE();
那么以上两条指令又是啥意思呢?WFI(Wait for interrupt)和WFE(Wait for event)是两个让ARM核进入low-power standby模式的指令,由ARM architecture定义,由ARM core实现。我们可以在core_cmx3.h(笔者使用的是GD32F207,对应的就是core_cmx3.h,其他内核类似),中找到以上指令的定义。
static __INLINE void __WFI() { __ASM volatile ('wfi'); }
static __INLINE void __WFE() { __ASM volatile ('wfe'); }
以上就是把汇编指令都封装成了诸如__Commnad()的函数形式,并且预编译为二进制包。那么以上指令都能让ARM进入睡眠模式,又有啥区别呢?
对WFI来说,执行WFI指令后,ARM core会立即进入low-power standby state,直到有WFI Wakeup events发生。
而WFE则稍微不同,执行WFE指令后,根据Event Register(一个单bit的寄存器,每个PE一个)的状态,有两种情况:如果Event Register为1,该指令会把它清零,然后执行完成(不会standby);如果Event Register为0,和WFI类似,进入low-power standby state,直到有WFE Wakeup events发生。
总结一下,这两条指令的作用都是令MCU进入休眠/待机状态以便降低功耗,但是略有区别:
WFI: wait for Interrupt 等待中断,即下一次中断发生前都在此hold住不干活
WFE: wait for Events 等待事件,即下一次事件发生前都在此hold住不干活
因此我们要项唤醒MCU,最简单的就是通过中断唤醒。
睡眠模式时通过按键中断唤醒,代码如下:
/*
brief main function
param[in] none
param[out] none
retval none
*/
int main(void)
{
//usart init 115200 8-N-1
com_init(COM1, USART_MODE_GPIO, 115200, 0, 1);
/* configure LED1 GPIO port */
led_init(LED1);
/* configure LED2 GPIO port */
led_init(LED2);
/* configure LED3 GPIO port */
led_init(LED3);
/* configure LED4 GPIO port */
led_init(LED4);
//key init
key_init(KEY_WAKEUP, KEY_MODE_EXTI);
printf('\r\n Sleep Test \r\n');
while(1)
{
led_toggle(LED1);
Delay(0xFFFFF);
led_toggle(LED2);
Delay(0xFFFFF);
led_toggle(LED3);
Delay(0xFFFFF);
led_toggle(LED4);
//__WFI(); //进入睡眠模式,等待中断唤醒 方式一
__WFE(); //方式二
}
}
进入睡眠模式也可调用库函数。
void pmu_to_sleepmode(uint8_t sleepmodecmd)
值得注意的是,这里不能用滴答定时器来延时,因为这里使用的是中断方式实现的。
WFI和WFE两条指令让MCU进入睡眠模式,均可通过按键中断唤醒,但是他们的唤醒本质是有区别的。
如上图所示,图中的蓝色虚线箭头标出了中断信号的传输路径,而红色箭头标出了事件的传输路径。虽然中断和事件的产生源都是一样的,都是通过按键产生,但是路径却有不同,中断是需要CPU参与的,需要软件的中断服务函数才能完成中断后产生的结果;事件是靠脉冲发生器产生一个脉冲,进而由硬件自动完成这个事件产生的结果,当然相应的联动部件需要先设置好,比如引起DMA操作,AD转换等。
4.2 深度睡眠模式
进入深度睡眠模式之后,任何外部中断都可以唤醒低功耗,但是需要重新配置时钟,不然系统将以默认时钟(没有经过倍频)运行。笔者这里还是使用外部中断唤醒。我们先看看主函数。
/*
brief main function
param[in] none
param[out] none
retval none
*/
int main(void)
{
//usart init 115200 8-N-1
com_init(COM1, USART_MODE_GPIO, 115200, 0, 1);
/* configure LED1 GPIO port */
led_init(LED1);
/* configure LED2 GPIO port */
led_init(LED2);
/* configure LED3 GPIO port */
led_init(LED3);
/* configure LED4 GPIO port */
led_init(LED4);
//key init
key_init(KEY_WAKEUP, KEY_MODE_EXTI);
/* 使能电源管理单元的时钟 */
rcu_periph_clock_enable(RCU_PMU);
printf('\r\n Enter stop mode \r\n');
/* 进入深度睡眠模式,设置电压调节器为低功耗模式,等待中断唤醒*/
pmu_to_deepsleepmode(PMU_LDO_LOWPOWER,WFI_CMD);
while(1)
{
led_toggle(LED1);
Delay(0xFFFFF);
led_toggle(LED2);
Delay(0xFFFFF);
led_toggle(LED3);
Delay(0xFFFFF);
led_toggle(LED4);
}
}
以上最重要的就一句:
pmu_to_deepsleepmode(PMU_LDO_LOWPOWER,WFI_CMD);
这是MCU进入低功耗模式的库函数,在gd32f20x_pmu.c中实现,原型如下:
/*!
\brief PMU work in deepsleep mode
\param[in] ldo:
only one parameter can be selected which is shown as below:
\arg PMU_LDO_NORMAL: LDO work at normal power mode when pmu enter deepsleep mode
\arg PMU_LDO_LOWPOWER: LDO work at low power mode when pmu enter deepsleep mode
\param[in] deepsleepmodecmd:
only one parameter can be selected which is shown as below:
\arg WFI_CMD: use WFI command
\arg WFE_CMD: use WFE command
\param[out] none
\retval none
*/
void pmu_to_deepsleepmode(uint32_t ldo, uint8_t deepsleepmodecmd)
{
static uint32_t reg_snap[4];
/* clear stbmod and ldolp bits */
PMU_CTL &= ~((uint32_t)(PMU_CTL_STBMOD | PMU_CTL_LDOLP));
/* set ldolp bit according to pmu_ldo */
PMU_CTL |= ldo;
/* set sleepdeep bit of Cortex-M3 system control register */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
reg_snap[0] = REG32(0xE000E010U);
reg_snap[1] = REG32(0xE000E100U);
reg_snap[2] = REG32(0xE000E104U);
reg_snap[3] = REG32(0xE000E108U);
REG32(0xE000E010U) &= 0x00010004U;
REG32(0xE000E180U) = 0XFF7FF83DU;
REG32(0xE000E184U) = 0XBFFFF8FFU;
REG32(0xE000E188U) = 0xFFFFFFFFU;
/* select WFI or WFE command to enter deepsleep mode */
if(WFI_CMD == deepsleepmodecmd) {
上一篇:GD32 MCU内部温度传感器如何使用,以及适合哪种应用场景?
下一篇:GD32 MCU进入低功耗模式导致无法再进行程序下载怎么办?
推荐阅读最新更新时间:2026-03-25 11:38
- 用于 7VIN 至 16VIN、1.5V 和 1.2V 输出的 LTM4628EV DC/DC 模块稳压器的典型应用电路
- 使用 Analog Devices 的 LTC3728LIGN 的参考设计
- DER-406 - 适用于 A19 灯的 5.76 W 高 PF 非隔离降压-升压型 TRIAC 调光 LED 驱动器
- ADR5045B 5V 输出精密微功率并联模式电压基准的典型应用
- LT3970EDDB-3.42 2.5V 降压转换器的典型应用
- MC78M08BDTG 8V 电流调节器的典型应用
- LT1021DCN8-5 精密电压基准的典型应用
- DER-282 - 100W, 扁平(11 mm), LLC DC-DC转换器
- REF193 低压差开尔文连接电压基准的典型应用电路
- LT3088EM 线性稳压器用于添加软启动的典型应用
- MTBF突破4万小时!这家工业级3D相机品牌产品稳定性获权威机构认可
- 英特尔创始人、“摩尔定律”提出者戈登·摩尔去世
- 本周机器人行业大事件TOP5
- G20周刊|埃斯顿与北自所达成战略合作、海康机器人发布光伏组件汇流带视觉检测解决方案
- 14家工业智能企业入选《上海市智能机器人标杆企业与应用场景推荐目录》
- OPPO中国区总裁刘波:坚持高质量发展,为中国手机行业创造新的竞争优势
- 贸泽电子开售适用于汽车外部照明的ams OSRAM OSLON Black Flat X LED器件
- 工业机器人坐标系有哪几种?各工业机器人坐标系的优缺点
- 暴增3倍!澳大利亚锂出口收入预计在2022-23年超过160亿美元
- 盘点:2022年全球储能领域最大的项目、融资和收购交易



GD32F30X_Firmware_Libarary
低功耗、高可靠性SRAM存储单元与阵列设计(Low Power And Reliable SRAM Memory Cell and Array design)
【Follow me第三季第4期】CY8CPROTO-063-BLE开发任务汇总代码
现代雷达系统的信号设计
BFR340T






京公网安备 11010802033920号