低电压 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");
}

 

posted @ 2022-04-11 19:21  debugdabiaoge  阅读(1236)  评论(0编辑  收藏  举报