一、概述
CW32F030 是武汉芯源半导体推出的通用高性能 32 位微控制器,基于 ARM Cortex-M0+ 内核,最高主频 48MHz,内置最大 64KB Flash 与 8KB RAM。在电源管理方面,芯片提供了两种低功耗模式:睡眠模式(Sleep)与深度休眠模式(DeepSleep),并配有上电/掉电复位(POR/BOR)和可编程低电压检测器(LVD)。低功耗设计是电池供电类产品选型与开发的核心考量,本文围绕 CW32F030 的两种低功耗模式,介绍其原理、特点、唤醒机制、典型应用与调试心得。
二、睡眠模式(Sleep)
模式特点
睡眠模式下,CPU 内核时钟停止,程序暂停执行,但外设时钟可以独立配置为运行或停止。SRAM、寄存器和外设状态全部保持,任意中断或事件(如定时器中断、外部中断、串口接收等)都可以将 CPU 立即唤醒,唤醒时间只有几个时钟周期。
进入睡眠模式只需执行 WFI(等待中断)或 WFE(等待事件)指令。该模式下功耗取决于仍在运行的外设与时钟,一般在几十到几百微安量级。2. 适用场景
睡眠模式适合“短时间待命、快速响应”的场景,例如等待 CAN 报文、定时器事件、串口数据等,CPU 空闲但需要保持外设随时工作的场合。
三、深度休眠模式(DeepSleep)
模式特点
2. 如何进入
需要设置系统控制寄存器(SCR)中的 SLEEPDEEP 位,然后执行 WFI 或 WFE 指令进入。唤醒后相当于从停止状态恢复,需要重新初始化系统时钟树和相关外设。3. 唤醒机制
深度休眠支持多种唤醒源:RTC 闹钟或周期唤醒(最常用,适合定时采集与定时上报);外部 IO 中断(边沿或电平触发,配合内部上拉/下拉与滤波,适合按键、门磁等事件唤醒);复位引脚 NRST;LVD 低电压检测(电压异常时唤醒处理);IWDT 独立看门狗;UART(通过 RXD 引脚 GPIO 下降沿中断实现接收唤醒);VC 电压比较器与 AWT 异步唤醒定时器等。唤醒响应时间为微秒级,远快于复位重启,但比睡眠模式略长。4. 深度休眠下的 UART 接收唤醒
官方给出了在深度休眠下用 UART 接收数据的配置步骤:
第一步,使能 UARTx_RXD 对应引脚的 GPIO 下降沿中断;
第二步,设置 UARTx_CR1.START 为 1,选择 RXD 信号起始位判定方式为低电平;
第三步,使能 UART 接收(置 UARTx_CR1.RXEN 为 1);
第四步,进入深度休眠模式;
第五步,主机发送数据,产生 GPIO 下降沿中断唤醒 MCU;
第六步,关闭 RXD 对应引脚的 GPIO 中断功能,等待 RXD 接收完成。
软件进入深度睡眠模式
void DeepSleepModeTest(void)
{
uint8_t res = 0u;
GPIO_InitTypeDef GPIO_InitStructure;
PWR_InitTypeDef PWR_InitStructure;
/* Configure all GPIO as analog to reduce current consumption on non used IOs */
/* Warning : Reconfiguring all GPIO will close the connexion with the debugger */
/* Enable GPIOs clock */
//打开GPIO时钟
REGBITS_SET( CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk | SYSCTRL_AHBEN_GPIOB_Msk |\
SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.IT = GPIO_IT_NONE;
GPIO_InitStructure.Pins = GPIO_PIN_All;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_Init(CW_GPIOC, &GPIO_InitStructure);
GPIO_Init(CW_GPIOF, &GPIO_InitStructure);
//关闭GPIO时钟
REGBITS_CLR( CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk | SYSCTRL_AHBEN_GPIOB_Msk |\
SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);
/* Configure User Button */
BSP_PB_Init();
/* Configures system clock after wake-up from DeepSleep: enable HSI and PLL with HSI as source*/
// 唤醒后自动使用内部高速时钟(HSI)
RCC_WAKEUPCLK_Config(RCC_SYSCTRL_WAKEUPCLKEN);
/* Enter Stop Mode */
PWR_InitStructure.PWR_Sevonpend = PWR_Sevonpend_Disable;
PWR_InitStructure.PWR_SleepDeep = PWR_SleepDeep_Enable;
PWR_InitStructure.PWR_SleepOnExit = PWR_SleepOnExit_Disable;
PWR_Config(&PWR_InitStructure);
//打开FLASH时钟
REGBITS_SET( CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_FLASH_Msk);
REGBITS_SET(CW_FLASH->CR1, FLASH_CR1_STANDBY_Msk); //打开FLASH低功耗使能控制
//关闭FLASH时钟
REGBITS_CLR( CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_FLASH_Msk);
}进入睡眠模式:
void SleepModeTest(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
PWR_InitTypeDef PWR_InitStructure;
/* Configure all GPIO as analog to reduce current consumption on non used IOs */
/* Enable GPIOs clock */
/* Warning : Reconfiguring all GPIO will close the connexion with the debugger */
//打开GPIO时钟
REGBITS_SET( CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk | SYSCTRL_AHBEN_GPIOB_Msk |\
SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);
GPIO_InitStructure.Mode = GPIO_MODE_ANALOG;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.IT = GPIO_IT_NONE;
GPIO_InitStructure.Pins = GPIO_PIN_All;
GPIO_Init(CW_GPIOA, &GPIO_InitStructure);
GPIO_Init(CW_GPIOB, &GPIO_InitStructure);
GPIO_Init(CW_GPIOC, &GPIO_InitStructure);
GPIO_Init(CW_GPIOF, &GPIO_InitStructure);
/* Disable GPIOs clock */
REGBITS_CLR( CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOA_Msk | SYSCTRL_AHBEN_GPIOB_Msk |\
SYSCTRL_AHBEN_GPIOC_Msk | SYSCTRL_AHBEN_GPIOF_Msk);
/* Configure User push-button as external interrupt generator */
BSP_PB_Init();
/*Suspend Tick increment to prevent wakeup by Systick interrupt.
Otherwise the Systick interrupt will wake up the device within 1ms (HAL time base)*/
SuspendTick();
/* Request to enter SLEEP mode */
//HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
PWR_InitStructure.PWR_Sevonpend = PWR_Sevonpend_Disable;
PWR_InitStructure.PWR_SleepDeep = PWR_SleepDeep_Disable;
PWR_InitStructure.PWR_SleepOnExit = PWR_SleepOnExit_Disable;
PWR_Config(&PWR_InitStructure);
PWR_GotoLpmMode();
/* Resume Tick interrupt if disabled prior to sleep mode entry*/
ResumeTick();
/* Initialize led */
LED_Init();
}总结
CW32F030 的睡眠模式适合“短待机、快响应”,深度休眠模式则是长待机低功耗产品的核心武器。用好这两种模式的关键,一是休眠前把不必要的外设与时钟全部关掉,
二是唤醒后完整重建时钟与外设环境,
三是合理设计唤醒源并实测验证。掌握这些要点,就能在性能与功耗之间取得良好平衡。
我要赚赏金
