【需求描述】
汽车电子类产品(如BCM)一般要求正常工作电压为9~16V,CAN总线活跃电压范围为7~18V。有些负载如门锁、转向灯则不限制9~16V。
【设计思路】
STEP1:
板载CAN transceiver(如TJA1043)工作电压范围为[4.5 5.5]V,典型值为5V。
板载5VLDO(如TPS7B69xx)稳定输出5V的输入电压范围为[5.8 40V]。
STEP2:
车载蓄电池规格为12V。
STEP3:
结合需求与硬件特性,可作出电压状态划分图如下。
其中模式Low与Normal之间的滞洄区间(0.5V/200ms)是指:当电压从高于9V变化到低于8.5V时,电压低于8.5V持续时间多于200ms,电源模式从Normal模式切换到Low模式;当电压从低于9V变化到高于9V时,电压高于9V持续时间多于200ms,电源模式从Low模式切换到Normal模式。
设计滞洄区间的目的:防止干扰造成的电压变化执行到负载上。
【编码实现】
appPowerManage.c
/*****************************************
* prototype : scan voltage mode
* input : none
* output : none
* return : voltage mode
*****************************************/
U8 pmmSysCheck_SystermVoltageScan(void)
{
U16 pmmSystermVoltTemp;
U8 pmmSystermVoltModeNew;
pmmSystermVoltTemp = Adh_GetLogicalValue(ADH_KL30_DUT);
if ((pmmSystermVoltTemp >= sysVoltageCfgPara.sysLowVoltThreshold)
&&(pmmSystermVoltTemp <= sysVoltageCfgPara.sysHighVoltThreshold) )
{
pmmSystermVoltModeNew = PMM_SYS_VOL_NORMAL;
}
else if(pmmSystermVoltTemp > sysVoltageCfgPara.sysHighVoltThreshold)
{
if( pmmSystermVoltTemp < (sysVoltageCfgPara.sysHighVoltThreshold + SYS_VOLT_BACK_Threshold) )
{
pmmSystermVoltModeNew = PMM_SYS_VOL_HIGH_HYST;
}
else if( pmmSystermVoltTemp <= (sysVoltageCfgPara.sysOverVoltThreshold - SYS_VOLT_BACK_Threshold) )
{
pmmSystermVoltModeNew = PMM_SYS_VOL_HIGH;
}
else if(pmmSystermVoltTemp < sysVoltageCfgPara.sysOverVoltThreshold)
{
pmmSystermVoltModeNew = PMM_SYS_VOL_OVER_HYST;
}
else
{
pmmSystermVoltModeNew = PMM_SYS_VOL_OVER;
}
}
else
{
if( pmmSystermVoltTemp > (sysVoltageCfgPara.sysLowVoltThreshold - SYS_VOLT_BACK_Threshold) )
{
pmmSystermVoltModeNew = PMM_SYS_VOL_LOW_HYST;
}
else if( pmmSystermVoltTemp >= (sysVoltageCfgPara.sysStopVoltThreshold + SYS_VOLT_BACK_Threshold) )
{
pmmSystermVoltModeNew = PMM_SYS_VOL_LOW;
}
else if(pmmSystermVoltTemp > sysVoltageCfgPara.sysStopVoltThreshold)
{
pmmSystermVoltModeNew = PMM_SYS_VOL_STOP_HYST;
}
else
{
pmmSystermVoltModeNew = PMM_SYS_VOL_STOP;
}
}
return pmmSystermVoltModeNew;
}
/*****************************************
* prototype : classify voltage mode
* input : none
* output : none
* return : voltage mode
*****************************************/
U8 pmmSysCheck_SystermVoltageModeGet(void)
{
U8 SystermVoltModeTemp;
static U8 SystermVoltModeLast = PMM_SYS_VOL_NORMAL;
SystermVoltModeTemp = pmmSysCheck_SystermVoltageScan();
if(SystermVoltModeTemp == PMM_SYS_VOL_OVER_HYST)
{
if(SystermVoltModeLast == PMM_SYS_VOL_OVER )
{
SystermVoltModeTemp = PMM_SYS_VOL_OVER;
}
else
{
SystermVoltModeTemp = PMM_SYS_VOL_HIGH;
}
}
else if(SystermVoltModeTemp == PMM_SYS_VOL_HIGH_HYST)
{
if( (SystermVoltModeLast == PMM_SYS_VOL_HIGH) || (SystermVoltModeLast == PMM_SYS_VOL_OVER) )
{
SystermVoltModeTemp = PMM_SYS_VOL_HIGH;
}
else
{
SystermVoltModeTemp = PMM_SYS_VOL_NORMAL;
}
}
else if(SystermVoltModeTemp == PMM_SYS_VOL_LOW_HYST)
{
if( (SystermVoltModeLast == PMM_SYS_VOL_LOW)||(SystermVoltModeLast == PMM_SYS_VOL_STOP) )
{
SystermVoltModeTemp = PMM_SYS_VOL_LOW;
}
else
{
SystermVoltModeTemp = PMM_SYS_VOL_NORMAL;
}
}
else if(SystermVoltModeTemp == PMM_SYS_VOL_STOP_HYST)
{
if(SystermVoltModeLast == PMM_SYS_VOL_STOP )
{
SystermVoltModeTemp = PMM_SYS_VOL_STOP;
}
else
{
SystermVoltModeTemp = PMM_SYS_VOL_LOW;
}
}
else
{
;
}
SystermVoltModeLast = SystermVoltModeTemp;
return SystermVoltModeTemp;
}
/*****************************************
* prototype : voltage mode change debounce
* input : none
* output : none
* return : none
*****************************************/
void pmmSysCheck_SystermVoltageModeHandle(void)
{
U8 SystermVoltModeNew;
static U8 SystermVoltModeOld = PMM_SYS_VOL_UNKNOW;
static U8 SystermVoltDounceCnt = 0;
SystermVoltModeNew = pmmSysCheck_SystermVoltageModeGet();
if(SystermVoltModeNew != SystermVoltModeOld)
{
SystermVoltModeOld = SystermVoltModeNew;
SystermVoltDounceCnt = 0;
}
else
{
if(g_inSystemVoltageModeSts != SystermVoltModeOld)
{
SystermVoltDounceCnt++;
if(SystermVoltDounceCnt >= PMM_SYS_VOLTAGE_DEBOUNCE_COUNT)
{
g_inSystemVoltageModeSts = SystermVoltModeOld;
SystermVoltDounceCnt = 0;
}
}
}
}
appPowerManage_Private.h
enum
{
PMM_SYS_VOL_NORMAL = 0,
PMM_SYS_VOL_STOP,
PMM_SYS_VOL_LOW,
PMM_SYS_VOL_HIGH,
PMM_SYS_VOL_OVER,
PMM_SYS_VOL_INVALID,
PMM_SYS_VOL_STOP_HYST,
PMM_SYS_VOL_LOW_HYST,
PMM_SYS_VOL_HIGH_HYST,
PMM_SYS_VOL_OVER_HYST,
PMM_SYS_VOL_UNKNOW = 0xffu
};
typedef struct
{
U16 sysLowVoltThreshold;
U16 sysHighVoltThreshold;
U16 sysOverVoltThreshold;
U16 sysStopVoltThreshold;
}sysVoltageCfgType;
#define SYS_VOLT_BACK_Threshold (500u)
#define PMM_SYS_VOLTAGE_DEBOUNCE_COUNT (10u) //20ms*10=200ms
const sysVoltageCfgType sysVoltageCfgPara =
{
8500,
16500,
18000,
6000,
};