低电压 BAT唤醒 CH582 CH573 CH579
芯片支持BAT唤醒
以CH582 BAT低压为例(分高精度低压检测和一般电压监测,高精度监测功耗高)
一般电压监测操作示例:
重点是调用的时候,这个函数里面是关闭了电压监控的
LowPower_Sleep(RB_PWR_RAM30K | RB_PWR_RAM2K); //只保留30+2K SRAM 供电 //睡眠函数
所有使用时需要把电压监控关闭的代码屏蔽掉(R8_BAT_DET_CTRL = 0; // 关闭电压监控)
__HIGH_CODE void LowPower_Sleep(uint8_t rm) { uint8_t x32Kpw, x32Mpw; uint16_t DCDCState; x32Kpw = R8_XT32K_TUNE; x32Mpw = R8_XT32M_TUNE; x32Mpw = (x32Mpw & 0xfc) | 0x03; // 150%额定电流 if(R16_RTC_CNT_32K > 0x3fff) { // 超过500ms x32Kpw = (x32Kpw & 0xfc) | 0x01; // LSE驱动电流降低到额定电流 } R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; SAFEOPERATE; // R8_BAT_DET_CTRL = 0; // 关闭电压监控 注意屏蔽这一行 R8_XT32K_TUNE = x32Kpw; R8_XT32M_TUNE = x32Mpw; R8_SAFE_ACCESS_SIG = 0; PFIC->SCTLR |= (1 << 2); //deep sleep DCDCState = R16_POWER_PLAN & (RB_PWR_DCDC_EN | RB_PWR_DCDC_PRE); DCDCState |= RB_PWR_PLAN_EN | RB_PWR_MUST_0010 | RB_PWR_CORE | rm; __nop(); R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; SAFEOPERATE; R8_SLP_POWER_CTRL |= RB_RAM_RET_LV; R8_PLL_CONFIG |= (1 << 5); R16_POWER_PLAN = DCDCState; __WFI(); __nop(); __nop(); R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG1; R8_SAFE_ACCESS_SIG = SAFE_ACCESS_SIG2; SAFEOPERATE; R8_PLL_CONFIG &= ~(1 << 5); R8_SAFE_ACCESS_SIG = 0; }
main 函数里面
PowerMonitor(ENABLE,LPLevel_2V5); //使能电压监控,一般精度 // PFIC_EnableIRQ(NMI_IRQn); // PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_BAT_WAKE, Long_Delay); PFIC_EnableIRQ(WDOG_BAT_IRQn);//一般精度使用这个中断 PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_BAT_WAKE, Long_Delay); //设置唤醒使能 while(1) { #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 PRINT("pong.. \n"); }
中断函数
__INTERRUPT __HIGH_CODE void WDOG_BAT_IRQHandler(void) { SetSysClock(CLK_SOURCE_PLL_60MHz); DelayMs(5); PRINT("WDOG_BAT_IRQHandler\n"); while(R8_BAT_STATUS&RB_BAT_STAT_LOW)//等电压恢复 { PRINT("WDOG_BAT low.. \n"); } }
高精度电压监测
PowerMonitor(ENABLE,HALevel_2V5); //设置高精度触发 PFIC_EnableIRQ(NMI_IRQn);//使能NMI中断 PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_BAT_WAKE, Long_Delay);//设置BAT唤醒 // PFIC_EnableIRQ(WDOG_BAT_IRQn); // PWR_PeriphWakeUpCfg(ENABLE, RB_SLP_BAT_WAKE, Long_Delay); while(1) { #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 PRINT("pong.. \n"); }
NMI中断处理函数
__INTERRUPT __HIGH_CODE void NMI_Handler(void) { SetSysClock(CLK_SOURCE_PLL_60MHz); DelayMs(5); PRINT("R8_BAT_STATUS=%x. \n",R8_BAT_STATUS); while(R8_BAT_STATUS&RB_BAT_STAT_LOWER) //等电压恢复 { PRINT("BAT low.. \n"); } PRINT("BAT normal.. \n"); }