【WCH蓝牙系列芯片】-基于CH582开发板—四种低功耗模式电流测试
-------------------------------------------------------------------------------------------------------------------------------------
在WCH沁恒官方提供的CH583的EVT资源包中,找到BLE文件中找到PW这个工程文件,这是一个系统睡眠模式并唤醒例程;其中GPIOA_5作为唤醒源,共4种功耗等级。
芯片提供以下 4 种主要的低功耗模式:
1、空闲模式(Idle)
所有外设保持正常供电,内核停止运行,时钟系统运转。检测到唤醒事件后,可以立即唤醒。
2、暂停模式(Halt)
在空闲模式的基础上,时钟系统停止。检测到唤醒事件后,首先时钟运转,然后唤醒内核运行。
3、睡眠模式(Sleep)
主 LDO 关闭,由超低功耗 ULP-LDO 维持 PMU、内核和基本外设供电,LSE 或 LSI 可以选择是否开启,RAM2K、RAM30K、USB 和 RF 配置可以选择是否维持供电。检测到唤醒事件后,首先主 LDO 开启,然后时钟运转,最后唤醒内核,程序继续运行,需要时可以重新设置到更高主频
4、下电模式(Shutdown)
在睡眠模式的基础上,关闭了内核和基本外设以及 USB 和 RF 配置,LSE 或 LSI 可以选择是否开启,RAM2K、RAM30K 可以选择是否维持供电。检测到唤醒事件后,PMU 将执行 GRWSM 复位,软件可根据复位标志 RB_RESET_FLAG 和可选的 RAM 中的保持数据区分于 RPOR
在数据手册上针对每一个模式,有具体的特征和进入条件,还有唤醒事件以及具体功耗的范围值。
在EVT资源包中的PW例程中只包含外部中断引脚PA5的方式唤醒睡眠,在此基础上,加入RTC中断唤醒。
GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
在主程序中,GPOIO中都没有内部断开模式,上电后,默认状态为浮空输入状态,当引脚浮空状态非常耗电,所以在低功耗模式,要将在初始化时,需要将所有的IO口设置为模拟输入,这样可以避免有额外电流。
1、利用GPIO引脚中断唤醒和RTC定时模式作为唤醒源
唤醒引脚支持PA0-PA15,PB0-PB15(PB8、PB9除外)
#if 1 /* 配置唤醒源为 GPIO - PA5 */ GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_PU); //输入模式 GPIOA_ITModeCfg(GPIO_Pin_5, GPIO_ITMode_FallEdge); // 下降沿唤醒 PFIC_EnableIRQ(GPIO_A_IRQn); //使能GPIOA中断 PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_GPIO_WAKE, Long_Delay); //使能外设唤醒功能,配置唤醒源为 GPIO 引脚,并设置长延时。 #endif #if 1 /* 配置唤醒源为 RTC */ RTC_TMRFunCfg(Period_1_S); // RTC定时模式配置 1s的周期 PFIC_EnableIRQ(RTC_IRQn); //使能RTC中断 PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_RTC_WAKE, Long_Delay); //使能外设唤醒功能,配置唤醒源为 RTC事件唤醒,并设置长延时。 #endif
2、四种低功耗模式
#if 0 PRINT("IDLE mode sleep \n"); //空闲模式 DelayMs(1); LowPower_Idle(); //低功耗-Idle模式,让 CPU 进入睡眠状态以降低功耗 PRINT("wake.. \n"); DelayMs(500); #endif #if 0 PRINT("Halt mode sleep \n"); //暂停挂起模式 DelayMs(2); LowPower_Halt(); //将系统置于 Halt 模式,这是一种更低功耗的模式 HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayMs(2); PRINT("wake.. \n"); DelayMs(500); #endif #if 1 PRINT("sleep mode sleep \n"); //睡眠模式 DelayMs(2); // 注意当主频为80M时,Sleep睡眠唤醒中断不可调用flash内代码。 LowPower_Sleep(RB_PWR_RAM30K | RB_PWR_RAM2K); //只保留30+2K SRAM 供电 HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流) DelayMs(5); PRINT("wake.. \n"); DelayMs(500); #endif #if 0 PRINT("shut down mode sleep \n"); //关机下电模式 DelayMs(2); LowPower_Shutdown(0); //全部断电,唤醒后复位 /* 此模式唤醒后会执行复位,所以下面代码不会运行, 注意要确保系统睡下去再唤醒才是唤醒复位,否则有可能变成IDLE等级唤醒 */ HSECFG_Current(HSE_RCur_100); // 降为额定电流(低功耗函数中提升了HSE偏置电流) PRINT("wake.. \n"); DelayMs(500); #endif
3、采用外部中断PA5作为唤醒睡眠
/********************************************************************* * @fn GPIOA_IRQHandler * * @brief GPIOA中断函数 * * @return none */ __INTERRUPT __HIGH_CODE void GPIOA_IRQHandler(void) //GPIOA中断处理函数 { GPIOA_ClearITFlagBit(GPIO_Pin_6 | GPIO_Pin_5); //中断标志位清除 }
4、采用RTC唤醒中断方式,1秒为周期唤醒
__INTERRUPT __HIGH_CODE void RTC_IRQHandler(void) //RTC中断处理函数,RTC闹钟唤醒中断 { uint16_t py; uint16_t pmon; uint16_t pd; uint16_t ph; uint16_t pm; uint16_t ps; RTC_GetTime(&py,&pmon,&pd,&ph,&pm,&ps); //获取当前时间 if(RTC_GetITFlag(RTC_TMR_EVENT)) //判断是否发生了 RTC 周期定时事件的中断(1秒) { printf("%d年%d月%d日%d时%d分%d秒\r\n",py,pmon,pd,ph,pm,ps); RTC_ClearITFlag(RTC_TMR_EVENT); //清除RTC中断标志 (RTC 周期定时事件) } }
5、各个模式下测试电流状态,包换睡眠和唤醒后电流值。
CH582系统睡眠模式低功耗测
|
||||
低功耗模式 |
空闲模式 |
暂停模式 |
睡眠模式 |
下电模式 |
GPIO未唤醒状态 | 2.45mA | 324.30uA | 3.13uA | 0.56uA |
GPIO唤醒 | 9.27mA | 9.00mA | 9.14mA | 5.45mA |
RTC未唤醒状态 | 2.45mA | 324.55uA | 3.11uA | 0.56uA |
RTC 1秒唤醒 | 9.03mA | 9.19mA | 9.07 mA | 5.42mA |