本帖最后由 meiyaolei 于 2024-12-29 23:45 编辑
唤醒的理解:
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也会随之进行点亮。
|