標(biāo)題:
海爾12位單片機(jī)寫的移動(dòng)電源程序
[打印本頁]
作者:
zzmm5520
時(shí)間:
2016-5-16 11:19
標(biāo)題:
海爾12位單片機(jī)寫的移動(dòng)電源程序
需要用海爾的單片機(jī)同學(xué)可以參考
0.png
(76.32 KB, 下載次數(shù): 123)
下載附件
2016-5-16 17:55 上傳
完整代碼下載:
移動(dòng)電源Demo程序.rar
(8.38 KB, 下載次數(shù): 98)
2016-5-16 11:18 上傳
點(diǎn)擊文件名下載附件
海爾單片機(jī)
下載積分: 黑幣 -5
/*
---------------------
電源--|VDD VSS|--地
PinCharge--|PA5/OSC1/KIN5 PA0/AIN0|--NC
PinChargeFull--|PA4/OSC2/KIN4 PA1/AIN1|--PinCurrent
PinHalt--|PA3/MRST/KIN3 PA2/AIN2|--PinBoostEN
PinLed1--|PB3/AIN7 PB0/AIN3|--PinSelMode
PinLed2--|PB2/AIN6 PB1/AIN4|--NC
PinLed3--|PA7/AIN5/KIN7 PA6|--PinKey
---------------------
*/
/*****************************************************************************
;* Title :
;*
;*
;*
;* Device : HR7P155-SOP14
;* OSC : 8Mhz( Internal 8Mhz )
;*
;* Compiler: IDE
;* Hardware:
;* Version : A00
;***************************************************************************/
/*********************************************
;* Include headfiles
;********************************************/
#include "Init.h"
/*********************************************
;* Private variables
;********************************************/
/**********************************************
;*
;* Function Name: main
;* Inputs: None
;* Returns: None
;* Description: the main process
;*
;**********************************************/
void main(void)
{
InitialMCU();
while(1)
{
CLRWDT();
RCEN = 1;
if(FlagSysClk1ms)
{
FlagSysClk1ms = 0;
KeyScan(); //按鍵掃描子程序
ADCurrentSample(); //電流采樣處理子程序
}
if(FlagSysClk20ms)
{
FlagSysClk20ms = 0;
GetSysStatus(); //狀態(tài)處理子程序
LowLoadCheck(); //輕負(fù)載、過流保護(hù)處理子程序
ControlCharge(); //充電控制子程序
}
if(FlagSysClk500ms)
{
FlagSysClk500ms = 0;
//for debug
//PowerBattaryQ = 2600; //blink
//PowerBattaryQ = 2700; //level1
//PowerBattaryQ = 2800; //level2
//PowerBattaryQ = 2850; //level3
//PowerBattaryQ = 3000; //level4
HandFlagProcess(); //功能模式處理子程序
DealDispData(); //顯示數(shù)據(jù)處理子程序 必須放在電量級(jí)別判斷之后
HaltProcess(); //休眠處理子程序
AdjustToBalance(); //電池電量級(jí)別平衡處理子程序
}
}
}
/**********************************************
;*
;* Function Name: interrupt service routine
;* Inputs: None
;* Returns: None
;* Description: the isr process
;*
;**********************************************/
void isr(void) interrupt
{
if (T8P2IE & T8P2IF)
{
T8P2IF = 0;
FlagSysClk1ms = 1;
CntSysClk20ms++;
//每20ms執(zhí)行一次
if(CntSysClk20ms >= 20)
{
FlagSysClk20ms = 1;
CntSysClk20ms = 0;
CntSysClk500ms++;
if(CntSysClk500ms >= 25)
{
FlagSysClk500ms = 1;
CntSysClk500ms = 0;
}
}
}
if(KIE & KIF)
{
PABuf = PA; //必須要讀一次電平才能清除KIF
KIF = 0;
}
}
/**********************************************
;*
;* Function Name: GetSysStatus routine
;* Inputs: None
;* Returns: None
;* Description: the GetSysStatus process
;*
;**********************************************/
#define CONST_NOCHARGE_CUR 6
void InitChargePWM(void)
{
T8P1P = 131; //周期132 * 1/8M * 2 = 33us
T8P1RL = 20; //初始占空比20 * 1/8M * 2 = 5us
T8P1C = 0x84; //PWM輸出模式,使能T8P1
T8P1OC = 0x01; //選擇PB0輸出PWM
}
void GetSysStatus(void)
{
if(PinCharge)
{
CntDischargeShort = 0;
CntChargeShort++;
if(CntChargeShort >= COUNT_CHARGE_SHORT) //防止拔掉適配器后顯示充滿狀態(tài),保證PinCharge引腳變?yōu)榈碗娖?br />
{
CntChargeShort = 0;
if(!FlagChargeDisp)
{
//充電處理程序
FlagEnterBlink = 0;
FlagDispPower = 0;
FlagChargeDisp = 1;
FlagCharging = 1;
FlagChargeFull = 0;
InitChargePWM();
CntDispCharge = 0;
}
}
}
else
{
CntChargeShort = 0;
CntDischargeShort++;
if(CntDischargeShort >= COUNT_CHARGE_SHORT)
{
CntDischargeShort = 0;
if(!FlagDispPower)
{
FlagChargeDisp = 0;
FlagDispPower = 1;
FlagCharging = 0;
FlagChargeFull = 0;
}
}
}
//充電狀態(tài)下,充電拔出判斷
if(FlagCharging && (!FlagChargeFull))
{
if(ChargeCur < CONST_NOCHARGE_CUR)
{
CntNoCharge++;
if(CntNoCharge >= 20)//150)
{
CntNoCharge = 0;
//充電拔出處理
FlagCharging = 0;
ClosePinChargePWM();
CntNoLoad = 0;
//邊充邊放時(shí),拔掉充電不能進(jìn)休眠
if(!FlagDischarge)
{
Sleep();
}
}
}
else
{
CntNoCharge = 0;
}
}
}
/**********************************************
;*
;* Function Name: LowLoadCheck routine
;* Inputs: None
;* Returns: None
;* Description: the LowLoadCheck process
;*
;**********************************************/
void LowLoadCheck(void)
{
//放電模式下過流、輕負(fù)載判斷
if((LoadCurrentVol >= LOAD_OVER_CUR_VALUE))
{
CntShort++;
if(CntShort >= COUNT_SHORT)
{
CntShort = 0;
//防止再次按鍵不能打開升壓
CntADSample = 0;
ADCurSum = 0;
LoadCurrentVol = 0;
PinBoostEN = 0;
FlagDischarge = 0;
}
}
else if(LoadCurrentVol >= NO_LOAD_VALUE)
{
CntShort = 0;
CntNoLoad = 0;
CntHaveLoad++;
if(CntHaveLoad >= COUNT_HAVE_LOAD)
{
CntHaveLoad = 0;
CntDispDelay = 0;
FlagLoad = 1;
}
}
else
{
CntShort = 0;
CntHaveLoad = 0;
CntNoLoad++;
//輕負(fù)載時(shí)去抖
if(CntNoLoad >= COUNT_LIGHT_LOAD)
{
FlagLoad = 0;
}
//無負(fù)載10S關(guān)閉升壓輸出,并休眠
if(CntNoLoad >= COUNT_NO_LOAD)
{
CntNoLoad = 0;
if(!FlagCharging)
{
Sleep();
}
}
}
}
/**********************************************
;*
;* Function Name: DisplaySub routine
;* Inputs: None
;* Returns: None
;* Description: the DisplaySub process
;*
;* 0 //放電模式(有負(fù)載)
;* 1 //放電無負(fù)載、充電拔出顯示處理
;* 2 //充電跑馬燈顯示處理
;* 3 //充電充滿顯示
;**********************************************/
void DisplaySub(u8 uMode)
{
//放電有負(fù)載、充電顯示處理
if(uMode == 1)
{
//充電充滿顯示
if(FlagChargeFull)
{
SetPinLed1();
SetPinLed2();
SetPinLed3();
SetPinLed4();
}
else
{
switch(PreLedLevel)
{
case 1:
CntDispCharge++;
switch(CntDispCharge)
{
case 1:
SetPinLed1();
break;
case 2:
SetPinLed2();
break;
case 3:
SetPinLed3();
break;
case 4:
SetPinLed4();
break;
case 5:
CntDispCharge = 0;
ClrAllLed();
break;
default:
break;
}
break;
case 2:
SetPinLed1();
CntDispCharge++;
switch(CntDispCharge)
{
case 1:
SetPinLed2();
break;
case 2:
SetPinLed3();
break;
case 3:
SetPinLed4();
break;
case 4:
CntDispCharge = 0;
ClrPinLed2();
ClrPinLed3();
ClrPinLed4();
break;
default:
break;
}
break;
case 3:
SetPinLed1();
SetPinLed2();
CntDispCharge++;
switch(CntDispCharge)
{
case 1:
SetPinLed3();
break;
case 2:
SetPinLed4();
break;
case 3:
CntDispCharge = 0;
ClrPinLed3();
ClrPinLed4();
break;
default:
break;
}
break;
case 4:
SetPinLed1();
SetPinLed2();
SetPinLed3();
CPLPinLed4();
break;
default:
PreLedLevel = NowLedLevel;
break;
}
}
}
//放電模式(有負(fù)載或無負(fù)載)
else if(uMode == 0)
{
if((FlagDischarge || (!FlagLoad)) && FlagEnterBlink)
{
CPLPinLed1();
ClrPinLed2();
ClrPinLed3();
ClrPinLed4();
}
else
{
switch(PreLedLevel)
{
case 1:
SetPinLed1();
ClrPinLed2();
ClrPinLed3();
ClrPinLed4();
break;
case 2:
SetPinLed1();
SetPinLed2();
ClrPinLed3();
ClrPinLed4();
break;
case 3:
SetPinLed1();
SetPinLed2();
SetPinLed3();
ClrPinLed4();
break;
case 4:
SetPinLed1();
SetPinLed2();
SetPinLed3();
SetPinLed4();
break;
default:
PreLedLevel = NowLedLevel;
break;
}
}
}
}
/**********************************************
;*
;* Function Name: DealDispData routine
;* Inputs: None
;* Returns: None
;* Description: the DealDispData process
;*
;* 0 //放電模式(有負(fù)載或無負(fù)載)
;* 1 //充電跑馬燈顯示處理
;**********************************************/
void DealDispData(void)
{
if(FlagShortLoad)
{
CntFlashErr++;
if(CntFlashErr >= 6)
{
CntFlashErr = 0;
FlagShortLoad = 0;
//短路3S后進(jìn)入休眠
Sleep();
}
else
{
CPLPinLed1();
CPLPinLed2();
CPLPinLed3();
CPLPinLed4();
}
}
//邊充邊放優(yōu)先顯示充電
else if(FlagCharging)
{
DisplaySub(1);
}
else if(FlagDischarge && (FlagLoad || FlagDispDelay))
{
DisplaySub(0); //放電有負(fù)載或無負(fù)載顯示處理
}
else
{
ClrAllLed(); //關(guān)閉顯示輸出
}
}
/**********************************************
;*
;* Function Name: KeyScan routine
;* Inputs: None
;* Returns: None
;* Description: the KeyScan process
;*
;**********************************************/
void FuncDischarge(void)
{
FlagDischarge = 1;
PinBoostEN = 1;
FlagDispDelay = 1;
CntDispDelay = 0;
CntNoLoad = 0;
}
/**********************************************
;*
;* Function Name: KeyScan routine
;* Inputs: None
;* Returns: None
;* Description: the KeyScan process
;*
;**********************************************/
void KeyScan(void)
{
if(!PinKey)
{
CntPressOn++;
if(CntPressOn >= KEY_SHORT)
{
CntPressOn = 0;
if(!FlagKeyPress)
{
FlagKeyPress = 1;
//單擊按鍵處理程序
FuncDischarge();
}
}
}
else
{
CntPressOn = 0;
FlagKeyPress = 0;
}
}
/**********************************************
;*
;* Function Name: ControlCharge routine
;* Inputs: None
;* Returns: None
;* Description: the ControlCharge process
;*
;**********************************************/
#define CONST_CHARGE_0A95 139//132
#define CONST_CHARGE_1A05 154//132
#define CONST_CHARGE_0A15 22//32
#define MAX_CHARGE_PWM 100
#define MIN_CHARGE_PWM 4
//充電恒流控制
void AdjustChargePWM(void)
{
//電流增加
if(ChargeCur < CONST_CHARGE_0A95)
{
if(T8P1RL < MAX_CHARGE_PWM)
{
T8P1RL++;
}
}
//電流減小
else if(ChargeCur > CONST_CHARGE_1A05)
{
if(T8P1RL > MIN_CHARGE_PWM)
{
T8P1RL--;
}
}
}
void ControlCharge(void)
{
if(FlagCharging && (!FlagChargeFull))
{
if(PowerBattaryQ < CONST_BAT_4V15)
{
AdjustChargePWM();
}
else if((PowerBattaryQ >= CONST_BAT_4V15))
{
//電壓增加
if(PowerBattaryQ < CONST_BAT_4V10)
{
if(T8P1RL < MAX_CHARGE_PWM)
{
T8P1RL++;
}
}
//電壓減小
else if(PowerBattaryQ > CONST_BAT_4V20)
{
if(T8P1RL > MIN_CHARGE_PWM)
{
T8P1RL--;
}
}
//連續(xù)5S延時(shí)滿足條件則認(rèn)為已充滿
if(ChargeCur < CONST_CHARGE_0A15)
{
CntFull++;
if(CntFull >= 250)
{
CntFull = 0;
FlagChargeFull = 1;
ClosePinChargePWM();
}
}
else
{
CntFull = 0;
}
}
}
}
/**********************************************
;*
;* Function Name: BatLevelCheck routine
;* Inputs: None
;* Returns: None
;* Description: the BatLevelCheck process
;*
;**********************************************/
void BatLevelCheck(void)
{
if(!FlagCharging)
{
//放電級(jí)別判定
if(PowerBattaryQ > DISCHARGE_VOL_LEVEL3)
{
NowLedLevel = 4;
}
else if(PowerBattaryQ > DISCHARGE_VOL_LEVEL2)
{
NowLedLevel = 3;
}
else if(PowerBattaryQ > DISCHARGE_VOL_LEVEL1)
{
NowLedLevel = 2;
}
else if(PowerBattaryQ > LED_BLINK_VOL)
{
NowLedLevel = 1;
}
}
//充電級(jí)別判定
else
{
if(PowerBattaryQ > CHARGE_VOL_LEVEL3)
{
NowLedLevel = 4;
}
else if(PowerBattaryQ > CHARGE_VOL_LEVEL2)
{
NowLedLevel = 3;
}
else if(PowerBattaryQ > CHARGE_VOL_LEVEL1)
{
NowLedLevel = 2;
}
else if(PowerBattaryQ > LED_BLINK_VOL)
{
NowLedLevel = 1;
}
}
//初始上電時(shí),將當(dāng)前電量級(jí)別賦給上次電量級(jí)別
if(FlagNowToPre)
{
FlagNowToPre = 0;
PreLedLevel = NowLedLevel;
}
}
/**********************************************
;*
;* Function Name: HandFlagProcess routine
;* Inputs: None
;* Returns: None
;* Description: the HandFlagProcess process
;*
;**********************************************/
void HandFlagProcess(void)
{
if(FlagDispDelay && (!FlagLoad))
{
CntDispDelay++;
if(CntDispDelay >= 6) //顯示電量時(shí)間為3S
{
CntDispDelay = 0;
FlagDispDelay = 0;
}
}
//電池電量檢測(cè)
BatLevelCheck();
// 電池電量盲區(qū)檢測(cè) 放電才判斷
if((PowerBattaryQ < LED_BLINK_VOL) && (!FlagCharging))
{
FlagEnterBlink = 1;
NowLedLevel = 1;
}
}
/**********************************************
;*
;* Function Name: AdjustToBalance routine
;* Inputs: None
;* Returns: None
;* Description: the AdjustToBalance process
;*
;**********************************************/
void AdjustToBalance(void)
{
if(PreLedLevel > NowLedLevel)
{
if(FlagLoad)
{
CntDelayLevel1++;
if(CntDelayLevel1 >= COUNT_DELAY_LEVEL)
{
CntDelayLevel1 = 0;
PreLedLevel -= 1;
}
}
}
else if(PreLedLevel < NowLedLevel)
{
if(FlagCharging)
{
CntDelayLevel2++;
if(CntDelayLevel2 >= COUNT_DELAY_LEVEL)
{
CntDelayLevel2 = 0;
PreLedLevel += 1;
CntDispCharge = 0; //跑馬燈顯示計(jì)數(shù)清零
}
}
}
else
{
CntDelayLevel1 = 0;
CntDelayLevel2 = 0;
}
}
/**********************************************
;*
;* Function Name: HaltProcess routine
;* Inputs: None
;* Returns: None
;* Description: the HaltProcess process
;*
;**********************************************/
void HaltProcess(void)
{
//當(dāng)電池電量小于關(guān)機(jī)電量時(shí)休眠
if(!FlagCharging)
{
if(PowerBattaryQ < BAT_OFF_VOL)
{
Sleep();
}
}
}
/**********************************************
;*
;* Function Name: GetADC routine
;* Inputs: u8 channel
;* Returns: u16 m_ADCValue
;* Description: the GetADC process
;*
;**********************************************/
u16 GetADC(u8 channel)
{
//ADCCH = 0xB8;
ADCCL = channel;
ADTRG = 1;
while (ADTRG)
{
;
}
m_ADCValue = (ADCRH << 8) + ADCRL;
return(m_ADCValue);
}
/**********************************************
;*
;* Function Name: ADCurrentSample routine
;* Inputs: None
;* Returns: None
;* Description: the ADCurrentSample process
;*
;**********************************************/
void ADCurrentSample(void)
{
CntADSample++;
if(CntADSample != 17)
{
BakLoadCur = GetADC(AD_CHANNEL_1);
ADCurSum += BakLoadCur;
ADChargeCurSum += GetADC(AD_CHANNEL_4);
if(FlagCharging)
{
if(BakLoadCur > m_ADCValue)
{
BakLoadCur = (BakLoadCur - m_ADCValue);
}
}
//短路1ms保護(hù)
if(BakLoadCur >= LOAD_SHORT_VALUE)
{
PinBoostEN = 0;
ClrAllLed();
FlagShortLoad = 1;
}
GetADC(AD_CHANNEL_0);
PABuf = (m_ADCValue >> 4);
ADBatterySum += PABuf;
//ADBatterySum += GetADC(AD_CHANNEL_0);
}
else
{
LoadCurrentVol = (ADCurSum >> 4);
ChargeCur = (ADChargeCurSum >> 4);
PowerBattaryQ = (ADBatterySum >> 4);
//充電時(shí)放電電流處理
if(FlagCharging)
{
if(LoadCurrentVol >= ChargeCur)
{
LoadCurrentVol = (LoadCurrentVol - ChargeCur);
}
}
CntADSample = 0;
ADCurSum = 0;
ADChargeCurSum = 0;
ADBatterySum = 0;
}
}
/**********************************************
;*
;* Function Name: Sleep routine
;* Inputs: None
;* Returns: None
;* Description: the Sleep process
;*
;**********************************************/
void Sleep(void)
{
if(FlagChargeFull) return;
ClrAllLed();
PinBoostEN = 0;
FlagDischarge = 0;
CntNoLoad = 0;
while(!SW_HS);
RCEN = 0;
ADEN = 0;//關(guān)閉ADC使能
IDLE();
while(!SW_HS); //等待高速時(shí)鐘穩(wěn)定
RCEN = 1; //打開看門狗
CLRWDT();
}
復(fù)制代碼
作者:
billy_jhgg
時(shí)間:
2018-5-10 10:40
感謝樓主分享,正需要呢,有原理圖就更好了
作者:
啊啊啊手術(shù)室
時(shí)間:
2018-7-7 23:42
大神,,邏輯非常清晰,
作者:
符小明
時(shí)間:
2018-7-13 14:55
大神學(xué)習(xí)了
作者:
符小明
時(shí)間:
2018-10-19 15:04
謝謝
作者:
Nicholas666
時(shí)間:
2018-10-30 16:32
感謝!看看有沒有參考價(jià)值!
作者:
luoj0902
時(shí)間:
2019-3-25 22:37
感謝!看看有沒有參考價(jià)值!
作者:
紫色的云
時(shí)間:
2019-5-17 09:44
有沒有參考原理圖看看
作者:
zhouyidong
時(shí)間:
2019-6-16 18:28
求原理圖
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1