RISC-V MCU应用教程之低功耗之停止模式

以RISC-V MCU CH32V307为例

1. 停止模式简介

停止模式是在内核深睡眠模式(SLEEPDEEP)基础上结合了外设的时钟控制机制,并可以让电压调节器运行在低功耗模式。

此模式下,高频时钟(HSE/HSI/PLL)被关闭,SRAM和寄存器内容保持,IO引脚状态保持。

该模式唤醒后,系统可继续运行,特别注意的是,此时默认系统时钟为内部 8MHz HSI,如有需要,可调用 SystemInit() 重新初始化时钟

停止模式下可工作的模块:

  • 独立看门狗(IWDG)

  • 实时时钟(RTC)

  • 低频时钟(LSI/LSE)

该模式下的唤醒时间为 HSI RC唤醒时间(23.1 us) + 电压调节器从低功耗模式唤醒时间(53.6 us 如果开启),总共约 76.7us

此模式下,电压调节器处于低功耗模式的睡眠电流约为 34uA,电压调节器处于正常状态的睡眠电流约为 110.5uA

:::tip

为了进一步降低功耗,建议将不用的 IO 引脚初始化为下拉输入模式

:::

 

2. 进入停止模式

进入停止模式的步骤:

  • 配置内核寄存器 PFIC_SCTLR 控制位 SLEEPDEEP=1

  • 如果需要配置调压器进入低功耗模式,将电源控制寄存器 PWR_CTLR 控制位 PDDS = 0,控制位 LPDS=1

  • 执行 WFIWFE 指令

:::tip

  • 如果正在进行闪存编程,直到对内存访问完成,系统才进入停止模式;

  • 如果正在进行对APB 的访问,直到对APB 访问完成,系统才进入停止模式

:::

3. 退出停止模式

退出停止模式的条件:

  • 任一外部中断 EXTI0~ EXTI21,需要在外部中断寄存器中设置

  • 唤醒事件:

    • 配置一个外部EXTI线为事件模式,当CPU从WFE唤醒后,因为对应事件线的挂起位没有被置位,不必清除相应外设的中断挂起位或PFIC中断通道挂起位。

    • 在外设的控制寄存器使能一个中断,但不在PFIC中使能,同时需要使能寄存器 PFIC_SCTLR 控制位 SEVONPEND。当CPU从WFE唤醒后,需要清除相应外设的中断挂起位或PFIC中断通道挂起位。

:::caution

不支持WKUP引脚上升沿唤醒

:::

 

4. 参考代码

复制代码
 1 #include "debug.h"
 2 
 3 void wakeup_init(void)
 4 {
 5     GPIO_InitTypeDef GPIO_InitStructure = {0};
 6     EXTI_InitTypeDef EXTI_InitStructure = {0};
 7 
 8     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO , ENABLE);
 9 
10     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
11     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
12     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13     GPIO_Init(GPIOA, &GPIO_InitStructure);
14 
15     /* GPIOA.3 ----> EXTI_Line3 */
16     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);
17     EXTI_InitStructure.EXTI_Line = EXTI_Line3;
18 
19     /* WFI - EXTI_Mode_Interrupt, WFE - EXTI_Mode_Event*/
20     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
21 
22     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
23     EXTI_InitStructure.EXTI_LineCmd = ENABLE;
24     EXTI_Init(&EXTI_InitStructure);
25 
26     /* when configured as event, no need to enable NVIC */
27     NVIC_SetPriority(EXTI3_IRQn,0x00);
28     NVIC_EnableIRQ(EXTI3_IRQn);
29 
30 }
31 
32 int main(void)
33 {
34 
35     /* Configure unused GPIO as IPD to reduce power consumption */
36     GPIO_InitTypeDef GPIO_InitStructure = {0};   
37     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|
38              RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE, ENABLE);
39     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
40     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
41 
42     GPIO_Init(GPIOA, &GPIO_InitStructure);
43     GPIO_Init(GPIOB, &GPIO_InitStructure);
44     GPIO_Init(GPIOC, &GPIO_InitStructure);
45     GPIO_Init(GPIOD, &GPIO_InitStructure);
46     GPIO_Init(GPIOE, &GPIO_InitStructure);
47     /***************************************/
48 
49     Delay_Init();
50     USART_Printf_Init(256000);
51 
52     wakeup_init();
53     
54     printf("ch32v307 stop test\r\n");
55     Delay_Ms(2000);
56 
57     // NVIC->SCTLR |= (1<<1); /* set SLEEPONEXIT */
58 
59     /* set regulator in low power mode,need enable rcc of pwr */
60     RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 
61     PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
62 
63     // PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
64 
65     printf("wakeup\r\n");
66 
67     while(1)
68     {
69         printf("run in main loop\r\n");
70         Delay_Ms(1000);
71     }
72 }
73 
74 
75 __attribute__((interrupt("WCH-Interrupt-fast")))
76 void EXTI3_IRQHandler(void)
77 {
78     if(EXTI_GetITStatus(EXTI_Line3)!=RESET)
79     {
80         SystemInit();
81         printf("exti3 interrupt\r\n");
82         EXTI_ClearITPendingBit(EXTI_Line3);     /* Clear Flag */
83     }
84 }
复制代码

:::tip 当MCU处于停止模式或待机模式时,两线调试仿真接口是处于关闭状态,此时是无法用 WCH-Link 进行程序的下载。若唤醒配置不正确,MCU无法唤醒,此时就会和MCU失联。解决方式如下:

  • 在主函数启动时加一个较长的延时函数,按住板子的复位键,使系统处于复位状态,然后点击 IDE 下载按钮,这时再释放复位键,这样MCU上电后执行延时函数期间对低功耗程序进行擦除。

  • 选择启动方式,通过将BOOT0拉高,重新上电使MCU从SRAM启动,重新选择一个非睡眠程序下载,下载完成后将BOOT0拉低,然后重新上电即可重新下载程序。

:::

posted @   Zhu_zzzzzz  阅读(180)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示