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