ZDBMS/code_app/LowPower.c

226 lines
6.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********************************************************************************
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(); //系统从低功耗唤醒
}