唤醒的理解:
CW32L010 是一款低功耗的微控制器,在实际应用中,利用其低功耗唤醒功能可以有效降低系统功耗,延长电池使用寿命。
硬件方面
电源配置
确保电源供应稳定且满足低功耗要求。对于电池供电的应用,选择合适的电池类型和电源管理芯片,以减少静态电流。合理布局电源线路,减少电源噪声对芯片的干扰,这对于维持低功耗模式下的稳定性至关重要。
外部中断引脚连接
CW32L010 的 GPIO 引脚可配置为外部中断输入,用于唤醒芯片。将需要用作唤醒源的外部信号连接到对应的 GPIO 引脚。例如,如果使用按键作为唤醒源,将按键一端接地,另一端连接到选定的 GPIO 引脚,同时通过上拉或下拉电阻确保引脚在按键未按下时处于稳定电平。
其他外设连接
若使用其他外设 RTC、定时器等作为唤醒源,需正确连接相关引脚。例如,RTC 的相关引脚需正确连接,以确保 RTC 能够正常工作并在设定时间触发唤醒事件。
软件方面
初始化配置
系统时钟配置:在进入低功耗模式前,合理配置系统时钟,选择合适的低功耗时钟源,如低速内部时钟(LSI)。例如,使用以下代码使能 LSI 时钟:
变量定义与 GPIO 时钟使能
uint16_t tmp; 初始引脚电平设置与按键等待操作 GPIO_InitTypeDef GPIO_InitStruct = {0}; __SYSCTRL_GPIOA_CLK_ENABLE(); __SYSCTRL_GPIOB_CLK_ENABLE();
按键相关 GPIO 引脚配置(输入模式,带内部上拉,下降沿触发中断)
GPIO_InitStruct.IT = GPIO_IT_FALLING; GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; GPIO_InitStruct.Pins = KEY_GPIO_PINS; GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct);
初始引脚电平设置与按键等待操作
PB02_SETHIGH(); while (PA06_GETVALUE()); GPIOA_INTFLAG_CLR(bv6); NVIC_EnableIRQ(GPIOA_IRQn); PB02_SETLOW();
低功耗等待唤醒循环
while (1) { SCB->SCR = 0x04; __WFI(); tmp++; PB02_TOG(); }
完整代码:
#include <stdint.h> // 假设这里包含了stdint.h以支持int32_t和uint16_t等类型 // 主函数 int32_t main(void) { uint16_t tmp; // 定义一个16位无符号整型变量tmp,用于循环计数或其他目的 GPIO_InitTypeDef GPIO_InitStruct = {0}; // 初始化GPIO配置结构体为0 // 使能GPIOA和GPIOB的时钟 __SYSCTRL_GPIOA_CLK_ENABLE(); __SYSCTRL_GPIOB_CLK_ENABLE(); // 配置用于按键输入的GPIO GPIO_InitStruct.IT = GPIO_IT_FALLING; // 配置为下降沿中断(假设按键按下时触发) GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP; // 配置为输入模式,内部上拉 GPIO_InitStruct.Pins = KEY_GPIO_PINS; // 选择特定的引脚(KEY_GPIO_PINS需要在其他地方定义) GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStruct); // 应用配置到指定的GPIO端口 // 配置用于LED输出的GPIO GPIO_InitStruct.IT = GPIO_IT_NONE; // 禁用中断 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 配置为推挽输出模式 GPIO_InitStruct.Pins = GPIO_PIN_2; // 选择第2个引脚 GPIO_Init(CW_GPIOB, &GPIO_InitStruct); // 应用配置到GPIOB // 配置GPIOA的滤波器(可能是用于去抖动或其他目的) GPIO_ConfigFilter(CW_GPIOA, bv6, GPIO_FLTCLK_LSI); // bv6可能是一个位掩码,表示要配置的引脚,GPIO_FLTCLK_LSI表示使用低速内部时钟作为滤波器时钟源 // 将PB02引脚设置为高电平(可能是为了点亮LED) PB02_SETHIGH(); // 等待PA06引脚变为低电平(可能是等待按键按下) while (PA06_GETVALUE()); // 清除GPIOA的中断标志(可能是为了响应之前的按键事件) GPIOA_INTFLAG_CLR(bv6); // 使能GPIOA的中断请求 NVIC_EnableIRQ(GPIOA_IRQn); // 将PB02引脚设置为低电平(可能是为了熄灭LED) PB02_SETLOW(); tmp = 0x00; // 初始化tmp变量 // 主循环 while (1) { // 触发系统控制块(SCB)的睡眠模式,尝试进入低功耗状态 SCB->SCR = 0x04; // 0x04可能表示某种睡眠模式 __WFI(); // 等待中断(Wakeup from Interrupt) // 增加tmp变量的值(尽管在这个上下文中它没有被使用) tmp++; // 切换PB02引脚的状态(可能是为了闪烁LED) PB02_TOG(); } }
使用M0+ 内核的ARM 等待中断专用指令,WFI(Wait for Interrupt),配合M0+ 内核的系统控制寄存器(SCR,
System Control Register)的SLEEPONEXIT 和SLEEPDEEP 位域,可实现立即进入或退出(中断服务程序)时进
入休眠模式或深度休眠模式。
立即进入
执行WFI 指令,MCU 将立即进入休眠模式(SLEEPDEEP 为0 时)或深度休眠模式(SLEEPDEEP 为1 时)。
退出时进入
将SLEEPONEXIT 位置1,当退出最低优先级的中断服务程序后,MCU 会进入休眠模式(SLEEPDEEP 为0 时)
或深度休眠模式(SLEEPDEEP 为1 时),而不需执行WFI 指令 。
退出休眠模式或深度休眠模式
在休眠模式或深度休眠模式下,均可通过中断来唤醒CPU,返回到运行模式。如果用户在中断服务程序中执行WFI 命令进入休眠(包括深度休眠),则需要比此中断更高优先级的中断才能唤醒CPU,因此,
我们强烈建议用户在准备进入休眠前,应先处理完所有中断服务程序,并且清除所有中断请求和中断标志。
低功耗模式及其唤醒时间下表给出的唤醒时间是在HSIOSC的唤醒阶段测试得到的。从Sleep模式及DeepSleep模式唤醒后,SYSCLK时钟源设置保持不变。
实际操作结果 :KEY2按下后,将系统从休眠中唤醒,同时LED2也会随之进行点亮。