/******************************************************************************** Copyright (C), Sinowealth Electronic. Ltd. Author: Sino Version: V0.0 Date: 2020/04/26 History: V2.0 2020/04/26 Preliminary ********************************************************************************/ #include "Main.h" BOOL bSleepFlg; //系统进入IDLE标志 BOOL bPDFlg; BOOL bWakeupFlg; BOOL bPCEnterPDFlg; //PC通知系统进入SLEEP标志 U8 xdata ucSleepTimerCnt; U8 xdata ucPDTimerCnt; U8 xdata ucResetFlag; /************************************************************************************************* * 函数名: WakeUpProcess * 参 数: 无 * 返回值: 无 * 描 述: 从Sleep模式唤醒,可通过电流检测和按键唤醒 *************************************************************************************************/ void WakeUpProcess(void) { if(bWakeupFlg) { bWakeupFlg = 0; if(bSleepFlg) { McuClockSet(MCU_CLK_24MHz); IrqEn(); bSleepFlg = 0; ucSleepTimerCnt = 0; Delay1ms(1); #if (UART0_DEFINE != 0) IrqUart0En(); //开启uart0中断 #endif IrqTimer3En(); //开启Timer3中断 McuTwiEn(); //开启MCU Twi模块 AfeAlarmDis(AFE_ALARM_SC | AFE_ALARM_OV | AFE_ALARM_CD); AfeTempADCEn(); //开启AFE温度采集 AfeWDTEn(); //开启AFE WDT } ucSleepTimerCnt = 0; ucPDTimerCnt = 0; ucUart0TimeoutCnt = 0; ucUart1TimeoutCnt = 0; ucUart2TimeoutCnt = 0; } } /************************************************************************************************* * 函数名: SystemIntoPD * 参 数: 无 * 返回值: 无 * 描 述: 系统进入掉电模式 *************************************************************************************************/ void SystemIntoPD(void) { while(1) { McuWDTClear(); //清除看门狗 IrqDis(); //关闭中断源 // LEDAllOff(); //关闭LED显示 BlueToothPowerDis(); //关闭蓝牙模块 AFEMosCtl(0); //关闭MOS驱动 AFEEnterPD(); //关闭3.3V电源 } } /************************************************************************************************* * 函数名: SystemIntoSleep * 参 数: 无 * 返回值: 无 * 描 述: 低功耗处理,进入IDLE或者PD *************************************************************************************************/ void SystemIntoSleep(void) { // LEDAllOff(); //关闭LED显示 BlueToothPowerDis(); //关闭蓝牙模块 bLedDisBleFlg = 0; AfeWDTDis(); //关闭AFE WDT AfeTempADCDis(); //关闭AFE温度采集 AfeAlarmEn(AFE_ALARM_SC | AFE_ALARM_OV | AFE_ALARM_CD); //开启SC,OV,CD的Alarm功能 McuTwiDis(); //关闭MCU Twi模块降低功耗 McuPWM2Dis(); //关闭MCU PWM模块 if(bDSGMOS) //DSG开启时,直接输出高电平 { IO_DSG_PWM = 1; } else { IO_DSG_PWM = 0; } Delay1ms(1); IrqDis(); //关闭总中断源 #if (UART0_DEFINE != 0) IrqUart0Dis(); #endif #if (UART1_DEFINE != 0) IrqUart1Dis(); #endif #if (UART2_DEFINE != 0) IrqUart2Dis(); #endif IrqTimer3Dis(); //关闭Timer3中断 IrqINT4FlgClr(); //保留外部中断4,清标志 McuClockSet(MCU_CLK_128KHz); //设置系统时钟为128KHz IrqEn(); McuIntoPD(); //MCU进入PD,可通过外部按键或ALARM唤醒。由于在系统进sleep后可能没有关DSG MOS,可能因为持续的小电流而将电芯耗空,但是,AFE内部预留FUSE,在VDD电压低于4V时会关闭LDO,使V33断电。 } /************************************************************************************************* * 函数名: LowPowerCheck * 参 数: 无 * 返回值: 无 * 描 述: 检测是否进入IDLE或者PD *************************************************************************************************/ void LowPowerCheck(void) { if(bPCEnterPDFlg && (bUart0SndAckFlg||bUart1SndAckFlg||bUart2SndAckFlg)) //上位机发送名字强制进入PD { bPCEnterPDFlg = 0; bPDFlg = 1; } else if(bCTO) //发生断线后,延时进入PD { if(++ucPDTimerCnt >= E2ucLowPowerDeley) { ucPDTimerCnt = E2ucLowPowerDeley; bPDFlg = 1; } } else if(!bLedDisFlg) //LED显示关闭后开始检测进入低功耗 { if(!bCHGING && !bDSGING) //非充非放状态 { if(bUV) //发生欠压保护后,延时进入PD { if(++ucPDTimerCnt >= E2ucLowPowerDeley) { ucPDTimerCnt = E2ucLowPowerDeley; bPDFlg = 1; } } else //未发生欠压保护,且未发生其他保护,则延时进入IDLE { ucPDTimerCnt = 0; if(!(bOTC | bUTC | bOV | bOCC | bOTD | bUTD | bUV | bOCD1 | bOCD2 | bAFE_SC | bLedDisBleFlg)) { if(++ucSleepTimerCnt >= E2ucLowPowerDeley) { ucSleepTimerCnt = E2ucLowPowerDeley; bSleepFlg = 1; } } else { ucSleepTimerCnt = 0; } } } else { ucSleepTimerCnt = 0; ucPDTimerCnt = 0; } } else { ucSleepTimerCnt = 0; ucPDTimerCnt = 0; } } /************************************************************************************************* * 函数名: LowPowerProcess * 参 数: 无 * 返回值: 无 * 描 述: 低功耗处理,进入IDLE或者PD *************************************************************************************************/ void LowPowerProcess(void) { if(!bSleepFlg && !bPDFlg) { IrqDis(); if(!(bKeyFlg | bCaliFlg | bMcuFlashWrFlg | bWakeupFlg | bISPFlg | bTimer50msFlg | bTimer1sFlg) && (ucResetFlag!=0x12)) { IrqEn(); McuIntoIdle(); } IrqEn(); } else if(bPDFlg) { bMcuFlashWrFlg = 1; McuFlashProcess(); SystemIntoPD(); } else if(bSleepFlg) { SystemIntoSleep(); } WakeUpProcess(); //系统从低功耗唤醒 }