?? power.c
字號:
/************************************ (C) 2005 485表項(xiàng)目 *****************************************
項(xiàng) 目: 485表項(xiàng)目
編譯環(huán)境 : IARAVR 編譯器 4.10A
模塊名稱 : Power.c
版 本 : V 1.0
建立時(shí)間 : 2008-5-3 21:49
修改時(shí)間 : 2008-5-3 23:00
作 者 : 郝瑜云
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
功能描述 : 電能處理子程序
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
修改 : 1.2005-11-5 :查出PowerOnReadPower讀入PulseCouterBUG
******************************************************************************/
#include "Include.h"
/*
***************************************************************************************************
函數(shù) : void PowerAddProg(void)
功能 : 電能寄存器累加子程序
注釋: 根據(jù)費(fèi)率號,有功累加標(biāo)志,進(jìn)行電能量累加運(yùn)算,并置位寫EEPROM 標(biāo)志
注意: 按照脈沖常數(shù)_PULSE_CONST來計(jì)算電能量
***************************************************************************************************
1.電量增加BUG分析
1)程序返回堆棧不夠用,導(dǎo)致程序的復(fù)位或部分功能缺失.
2)硬件復(fù)位口的虛焊連焊
3)手動復(fù)位.
4)小數(shù)位累加過程中的錯(cuò)誤
*/
void PowerAddProg(void)
{
//-------------------------------------------------------------------------
// 掉電寫電量
if(PowerVar.SavePow == 0xAA)
{
PowerVar.SavePow = 0;
if(PowerVar.PowerChange==0xAA)
{
PowerVar.PowerChange = 0; // 清除電能變化標(biāo)志
EEPVar.WriteProtectAA = 0xAA; // 打開寫保護(hù)
CopyRamToEEP(ADDRESS_INDEXE,&PowerVar.PowerEEPIndex,1); // 寫入電能保存序號
CopyRamToEEP(ADDRESS_ZEROE ,&PowerVar.PowerZero, 1); // 寫入小數(shù)位電量
CopyRamToEEP(ADDRESS_PULSEE,&PowerVar.PulseCouter, 1); // 寫入脈沖數(shù)
EEPVar.WriteProtectAA = 0x55; // 寫保護(hù)
}
SETBIT(ACSR,ACIE);
}
if(PowerVar.ActAdd==0xAA) // 電能滿0.01累加輸入有功電能
{
_CLI(); // 全局中斷禁止
PowerVar.ActAdd = 0; // 清除累加標(biāo)志位
if(++PowerVar.PowerZero>=100) // 累加電能小數(shù)位
{
PowerVar.PowerZero -= 100;
BuildPower();
HEX100Add(PowerVar.ActInPow+1,3); // 累加正向有功電能
EEPVar.WriteProtectAA = 0xAA; // 打開寫保護(hù)
SavePower(); // 寫電量
}
_SEI(); // 全局中斷允許
SETBIT(TimeBits,EnDisplay); // 允許顯示刷新 測試
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
}
/*
***************************************************************************************************
函數(shù) : void BuildPower(void)
功能 : 組合電能小數(shù)位和整數(shù)位函數(shù),用于通訊和顯示調(diào)用
***************************************************************************************************
*/
void BuildPower(void)
{
INT8U indextmp;
if(PowerVar.PowerEEPIndex >= _POWER_BLOCK_MAX) // 判斷INDEX是否在有效區(qū)域
{
PowerOnReadPower(); // INDEX無效(亂)重執(zhí)行上電讀電量
}
CopyEEPToRam((ADDRESS_9010E+(PowerVar.PowerEEPIndex*5)+4),&indextmp,1);
if(indextmp != PowerVar.PowerEEPIndex) // 判斷上一份電量INDEX是否有效
{
LocateMaxPowerIndex(); // 判斷最大值電量和INDEX
}
LoadPower();
PowerVar.ActInPow[0] = PowerVar.PowerZero; // 合并電能小數(shù)位
}
/*
***************************************************************************************************
函數(shù) : void SavePower(void)
功能 : 保存電能等參數(shù)函數(shù)
***************************************************************************************************
*/
void SavePower(void)
{
INT8U lasttmp,i;
lasttmp = PowerVar.PowerEEPIndex;
if(++PowerVar.PowerEEPIndex>=_POWER_BLOCK_MAX) // 指向下一個(gè)存儲單元
{
PowerVar.PowerEEPIndex = 0;
}
PowerVar.ActInPow[4] = PowerVar.PowerEEPIndex; // 記錄INDEX
PowerVar.ActInPow[0] = DataAddCS(PowerVar.ActInPow+1,3)+0x33; // 計(jì)算電量校驗(yàn)和
CopyRamToEEP((ADDRESS_9010E+(PowerVar.PowerEEPIndex*5)),PowerVar.ActInPow,5); // 寫入帶校驗(yàn)電量
i = 0xAA; // 擦除上當(dāng)前電量INDEX
CopyRamToEEP((ADDRESS_9010E+(lasttmp*5)+4),&i,1);
}
/*
***************************************************************************************************
函數(shù) : void PowerOnReadPower(void)
功能 : 第一次上電讀取電能等參數(shù)函數(shù)
***************************************************************************************************
2006-3-26 10:37: 讀入小數(shù)位電量時(shí)增加判斷上電復(fù)位標(biāo)志
*/
void PowerOnReadPower(void)
{
INT8U i,indextmp;
CopyEEPToRam(ADDRESS_INDEXE,&PowerVar.PowerEEPIndex,1); // 讀出掉電電能保存序號
if(PowerVar.PowerEEPIndex>=_POWER_BLOCK_MAX) // 檢測序號有效性
{
goto PowerEEPIndexErr;
}
else
{
CopyEEPToRam((ADDRESS_9010E+(PowerVar.PowerEEPIndex*5)+4),&indextmp,1); // 假設(shè)掉電INDEX是有效數(shù)字,讀出電量區(qū)INDEX
if(indextmp != PowerVar.PowerEEPIndex) // 兩個(gè)INDEX不等,去INDEX錯(cuò)誤處理
{
goto PowerEEPIndexErr;
}
else
{
goto LOAD_POWER; // INDEX有效,加載電量
}
}
PowerEEPIndexErr: // INDEX錯(cuò)誤處理,在電量區(qū)找正確的INDEX
for(i=0;i<_POWER_BLOCK_MAX;i++)
{
CopyEEPToRam((ADDRESS_9010E + (i*5) + 4),&PowerVar.PowerEEPIndex,1);
if(PowerVar.PowerEEPIndex == i)
{
goto LOAD_POWER;
}
}
LocateMaxPowerIndex(); // 若找不到正確的INDEX,則查找最大值電量的INDEX
//-------------------------------------------------------------------------
LOAD_POWER:
LoadPower();
// if(CHKBIT(MCUSR,PORF)) // 檢測上電復(fù)位標(biāo)志
// {
// CLRBIT(MCUSR,PORF);
CopyEEPToRam(ADDRESS_ZEROE, &PowerVar.PowerZero,1); // 讀入小數(shù)位電量
// }
CopyEEPToRam(ADDRESS_PULSEE,&PowerVar.PulseCouter,1); // 讀入脈沖數(shù)
}
/*
***************************************************************************************************
函數(shù) : void LocateMaxPowerIndex(void)
功能 : 定位最大值電量的INDEX
***************************************************************************************************
*/
void LocateMaxPowerIndex(void)
{
INT8U indextmp;
INT32U newlong,lastlong;
newlong = 0;
lastlong = 0;
for(indextmp=0;indextmp<_POWER_BLOCK_MAX;indextmp++) // 定位最大值電量INDEX
{
CopyEEPToRam((ADDRESS_9010E+(indextmp*5)+1),(INT8U *)&newlong,3);
if(newlong >= lastlong)
{
PowerVar.PowerEEPIndex = indextmp;
lastlong = newlong;
}
}
}
/*
***************************************************************************************************
函數(shù) : void LoadPower(void)
功能 : 根據(jù)INDEX加載校驗(yàn)和正確的電量,若校驗(yàn)都錯(cuò)則取第1份電量
***************************************************************************************************
*/
void LoadPower(void)
{
INT8U i;
for(i=0;i<_POWER_BLOCK_MAX;i++)
{
CopyEEPToRam((ADDRESS_9010E+(PowerVar.PowerEEPIndex*5)),PowerVar.ActInPow,5);
if(PowerVar.ActInPow[0] == (INT8U)(DataAddCS(PowerVar.ActInPow+1,3)+0x33)) // 根據(jù)校驗(yàn)和檢測數(shù)據(jù)有效性
{
return;
}
else
{
if(PowerVar.PowerEEPIndex==0)
{
PowerVar.PowerEEPIndex = _POWER_BLOCK_MAX-1;
}
else
{
PowerVar.PowerEEPIndex--;
}
}
}
CopyEEPToRam(ADDRESS_9010E,PowerVar.ActInPow,4); // 若所有電量無效則讀入第一個(gè)存儲單元
PowerVar.PowerEEPIndex = 0;
}
/*
***************************************************************************************************
函數(shù) : void ReadPulseConst(void)
功能 : 讀取并校驗(yàn)脈沖常數(shù)函數(shù)
***************************************************************************************************
*/
/*
void ReadPulseConst(void)
{
INT8U consttmp;
CopyEEPToRam(ADDRESS_C030E+1,&consttmp,1); // 讀入脈沖常數(shù)
if(consttmp== 0) // 如果常數(shù)為0,默認(rèn)為3200
{
PowerVar.PulseConst = 32;
}
else
{
BCDToHEX8(&consttmp,1);
if(PowerVar.PulseConst!=consttmp)
{
PowerVar.PulseConst = consttmp;
}
}
}
*/
/*
***************************************************************************************************
函數(shù) : void ReadDispConst(void)
功能 : 讀取顯示條目函數(shù)
***************************************************************************************************
*/
void ReadDispConst(void)
{
INT8U consttmp[2];
CopyEEPToRam(ADDRESS_D400E,consttmp,2); // 讀入顯示范圍和循顯時(shí)間
PowerVar.DisplayCouter=0x01;//0x0C; //有功電量
if(consttmp[0]&0x08)PowerVar.DisplayCouter|=0x02; // 資產(chǎn)號
if(consttmp[1]&0x80)PowerVar.DisplayCouter|=0x04; // 常數(shù)
// if(((consttmp[0]&0x08)==1)&&((consttmp[1]&0x80)==1))PowerVar.DisplayCouter=0x0B;// 資產(chǎn)號+常數(shù)
CopyEEPToRam(ADDRESS_C113E,consttmp,1); // 讀入循顯時(shí)間
if(consttmp[0]!=0)
{
BCDToHEX8(consttmp,1);
Disp_Time=consttmp[0];
}
else Disp_Time=0x05;
}
/*
***************************************************************************************************
函數(shù) : void ReadAdjustConst(void)
功能 : 讀取并校驗(yàn)脈沖常數(shù)函數(shù)
***************************************************************************************************
*/
void ReadAdjustConst(void)
{
//float temp;
INT8U consttmp[6];
mIICReadPage( consttmp,0x06, 0xA0, 0x00);
//i=DataAddCS(consttmp,6);
// if(i!=consttmp[6])mIICReadPage( consttmp,0x07, 0xA0, 0x08);
// CopyEEPToRam(ADDRESS_A,consttmp,2); // 讀入A相分頻數(shù)
// temp =consttmp[0]*256+consttmp[1];
// temp=(65535.0-temp)/45;
AdjustVar.AdjustConst_A =(0xFFFF-(consttmp[0]*256+consttmp[1]))/45;
if((AdjustVar.AdjustConst_A)<100)AdjustVar.AdjustConst_A=100;
//-------------------------------------------
// CopyEEPToRam(ADDRESS_B,consttmp,2); // 讀入B相分頻數(shù)
//temp =consttmp[2]*256+consttmp[3];
//temp=(65535.0-temp)/45.0+0.5;
AdjustVar.AdjustConst_B =(0xFFFF-(consttmp[2]*256+consttmp[3]))/45;
if((AdjustVar.AdjustConst_B)<100)AdjustVar.AdjustConst_B=100;
//--------------------------------------------
// CopyEEPToRam(ADDRESS_C,consttmp,2); // 讀入C相分頻數(shù)
//temp =consttmp[4]*256+consttmp[5];
//temp=(65535.0-temp)/45.0+0.5;
AdjustVar.AdjustConst_C =(0xFFFF-(consttmp[4]*256+consttmp[5]))/45;
if((AdjustVar.AdjustConst_C)<100)AdjustVar.AdjustConst_C=100;
// AdjustVar.AdjustConst_C=400;
}
/*
***************************************************************************************************
函 數(shù) : void CheckREVP(void)
功 能 : 檢測反向電平子程序
注 釋 : 電平無反向
***************************************************************************************************
*/
void CheckREVP(void)
{
if(CheckPin(PIND,1,IO_REVP_A))SETBIT(PulseBits,RevPFlag);
else if(CheckPin(PIND,1,IO_REVP_B))SETBIT(PulseBits,RevPFlag);
else if(CheckPin(PIND,1,IO_REVP_C))SETBIT(PulseBits,RevPFlag);
else CLRBIT(PulseBits,RevPFlag);
}
/********************************************* END OF SUB ****************************************/
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -