1. 程式人生 > 其它 >低電壓 BAT喚醒 CH582 CH573 CH579

低電壓 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");
}