CH579/CH573/CH583 支持多种功耗模式,实际上常用的无非就是RAM保持和RTC运行以及是否广播之间的各种组合罢了
由于CH57x/58x只有一个RTC且只有一个触发值中断可以设置,而用BLE等做休眠时候,协议栈会用到这个值去自行控制睡眠唤醒,这时候我们通常不能直接调用睡眠函数.
CH57x/58x的BLE是通过其“TMOS”操作系统实现,需要休眠时候,每次协议栈需要睡多久TMOS都是知道的,比如下个event是什么时候(蓝牙事件也是tmos的event)然后把要睡多久传递给休眠函数,休眠函数去设置一个RTC的触发中断,然后就进行休眠了(RTC在跑,RAM保持),直到RTC或者其他中断唤醒MCU
通过TMOS管理(RAM保持,rtc运行 休眠时候CH577/578/579=2uA,CH573/571=6uA,CH581/582/583=3uA,唤醒后芯片继续运行,可以做到蓝牙不断连 )
工程的全局宏里面加上HAL_SLEEP=TRUE 即可
- BLE下休眠强烈建议使用
- RF_PHY下强烈建议使用
- 只当普通mcu,不用无线,也可以用
- 这时候的平均功耗,根据由蓝牙的广播间隔/连接间隔,以及用户自己的任务运行的频繁程度所决定
关机模式(唤醒会导致复位, 电流<1uA,rtc唤醒可选,开rtc要加上rtc的功耗,按键可唤醒,唤醒后重启)
这种方式,通常适用那些产品需要长时间保持极低的功耗, 比如几十分钟,甚至几天只工作几分钟,
直接调用下面函数,就会关掉ram 电源并休眠
这里务必注意,rtc寄存器内容shutdown后会保持的,如果这里关掉了,在代码开始运行的时候,一定要手动再开启,而不是用芯片的上电默认值,切记!
//以下代码 在ch579 上运行
GPIOB_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
//开启上升沿中断
GPIOB_ITModeCfg(GPIO_Pin_8,GPIO_ITMode_FallEdge);
//使能gpio 唤醒
PWR_PeriphWakeUpCfg( ENABLE, RB_SLP_GPIO_WAKE );
//开启GPIO中断
NVIC_EnableIRQ( GPIO_IRQn );
//关掉内外32768.0
R8_SAFE_ACCESS_SIG = 0x57;
R8_SAFE_ACCESS_SIG = 0xa8;
R8_CK32K_CONFIG = 0;
R8_SAFE_ACCESS_SIG = 0;
//关机
LowPower_Shutdown( 0 );
//这里也要加上,shutdown 是需要一定的过程的,短时间内唤醒,会接着运行,所以这里需要处理继续运行的情况我们可以在下面加个手动复位(官网新的例程已经加上)
高级使用 程序中动态屏蔽BLE的休眠:
可以在下面这个代码中添加一个全局变量做标识,如果标识有效,直接 return 0即可,这样就可以做到动态使能低功耗模式与否了.
static volatile bool block_sleep = false;
void ch57x_block_sleep_request(void) {
block_sleep = true;
}
void ch57x_block_sleep_release(void) {
block_sleep = false;
}
u32 CH57X_LowPower( u32 time ) {
if( true == block_sleep) {
return 0;
}
<...>
};
注意事项:
- 沁恒mcu的gpio 都没有内部断开模式,上电后的默认状态是浮空输入的,所以休眠时候所有的IO都需要有确定的电平,对于不同的封装的芯片,引脚少的只是部分gpio没有引出来,实际上这些没有引出来IO也是需要初始化为确定的电平.
- 对于模拟引脚,有专门的寄存器,可以把对应IO的数字部分断开,否者功耗可能会降不下去
- 休眠后SWD会被禁用,swd的一且操作都会失效.
- 对于ch577/ch578/ch579 在休眠模式下(2uA的那种),前面16KB的ram 会断电,如果启用了低功耗,休眠模式下这部分RAM会丢失数据,使用时候格外注意.