📄 power.c
字号:
/************************************ (C) 2005 485表项目 *****************************************
项 目: 485表项目
编译环境 : IARAVR 编译器 4.10A
模块名称 : Power.c
版 本 : V 1.0
建立时间 : 2008-5-3 21:49
修改时间 : 2008-5-3 23:00
作 者 : 郝瑜云
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
功能描述 : 电能处理子程序
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
修改 : 1.2005-11-5 :查出PowerOnReadPower读入PulseCouterBUG
******************************************************************************/
#include "Include.h"
/*
***************************************************************************************************
函数 : void PowerAddProg(void)
功能 : 电能寄存器累加子程序
注释: 根据费率号,有功累加标志,进行电能量累加运算,并置位写EEPROM 标志
注意: 按照脉冲常数_PULSE_CONST来计算电能量
***************************************************************************************************
1.电量增加BUG分析
1)程序返回堆栈不够用,导致程序的复位或部分功能缺失.
2)硬件复位口的虚焊连焊
3)手动复位.
4)小数位累加过程中的错误
*/
void PowerAddProg(void)
{
//-------------------------------------------------------------------------
// 掉电写电量
if(PowerVar.SavePow == 0xAA)
{
PowerVar.SavePow = 0;
if(PowerVar.PowerChange==0xAA)
{
PowerVar.PowerChange = 0; // 清除电能变化标志
EEPVar.WriteProtectAA = 0xAA; // 打开写保护
CopyRamToEEP(ADDRESS_INDEXE,&PowerVar.PowerEEPIndex,1); // 写入电能保存序号
CopyRamToEEP(ADDRESS_ZEROE ,&PowerVar.PowerZero, 1); // 写入小数位电量
CopyRamToEEP(ADDRESS_PULSEE,&PowerVar.PulseCouter, 1); // 写入脉冲数
EEPVar.WriteProtectAA = 0x55; // 写保护
}
SETBIT(ACSR,ACIE);
}
if(PowerVar.ActAdd==0xAA) // 电能满0.01累加输入有功电能
{
_CLI(); // 全局中断禁止
PowerVar.ActAdd = 0; // 清除累加标志位
if(++PowerVar.PowerZero>=100) // 累加电能小数位
{
PowerVar.PowerZero -= 100;
BuildPower();
HEX100Add(PowerVar.ActInPow+1,3); // 累加正向有功电能
EEPVar.WriteProtectAA = 0xAA; // 打开写保护
SavePower(); // 写电量
}
_SEI(); // 全局中断允许
SETBIT(TimeBits,EnDisplay); // 允许显示刷新 测试
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
}
/*
***************************************************************************************************
函数 : void BuildPower(void)
功能 : 组合电能小数位和整数位函数,用于通讯和显示调用
***************************************************************************************************
*/
void BuildPower(void)
{
INT8U indextmp;
if(PowerVar.PowerEEPIndex >= _POWER_BLOCK_MAX) // 判断INDEX是否在有效区域
{
PowerOnReadPower(); // INDEX无效(乱)重执行上电读电量
}
CopyEEPToRam((ADDRESS_9010E+(PowerVar.PowerEEPIndex*5)+4),&indextmp,1);
if(indextmp != PowerVar.PowerEEPIndex) // 判断上一份电量INDEX是否有效
{
LocateMaxPowerIndex(); // 判断最大值电量和INDEX
}
LoadPower();
PowerVar.ActInPow[0] = PowerVar.PowerZero; // 合并电能小数位
}
/*
***************************************************************************************************
函数 : void SavePower(void)
功能 : 保存电能等参数函数
***************************************************************************************************
*/
void SavePower(void)
{
INT8U lasttmp,i;
lasttmp = PowerVar.PowerEEPIndex;
if(++PowerVar.PowerEEPIndex>=_POWER_BLOCK_MAX) // 指向下一个存储单元
{
PowerVar.PowerEEPIndex = 0;
}
PowerVar.ActInPow[4] = PowerVar.PowerEEPIndex; // 记录INDEX
PowerVar.ActInPow[0] = DataAddCS(PowerVar.ActInPow+1,3)+0x33; // 计算电量校验和
CopyRamToEEP((ADDRESS_9010E+(PowerVar.PowerEEPIndex*5)),PowerVar.ActInPow,5); // 写入带校验电量
i = 0xAA; // 擦除上当前电量INDEX
CopyRamToEEP((ADDRESS_9010E+(lasttmp*5)+4),&i,1);
}
/*
***************************************************************************************************
函数 : void PowerOnReadPower(void)
功能 : 第一次上电读取电能等参数函数
***************************************************************************************************
2006-3-26 10:37: 读入小数位电量时增加判断上电复位标志
*/
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); // 假设掉电INDEX是有效数字,读出电量区INDEX
if(indextmp != PowerVar.PowerEEPIndex) // 两个INDEX不等,去INDEX错误处理
{
goto PowerEEPIndexErr;
}
else
{
goto LOAD_POWER; // INDEX有效,加载电量
}
}
PowerEEPIndexErr: // INDEX错误处理,在电量区找正确的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)) // 检测上电复位标志
// {
// CLRBIT(MCUSR,PORF);
CopyEEPToRam(ADDRESS_ZEROE, &PowerVar.PowerZero,1); // 读入小数位电量
// }
CopyEEPToRam(ADDRESS_PULSEE,&PowerVar.PulseCouter,1); // 读入脉冲数
}
/*
***************************************************************************************************
函数 : 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;
}
}
}
/*
***************************************************************************************************
函数 : void LoadPower(void)
功能 : 根据INDEX加载校验和正确的电量,若校验都错则取第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)) // 根据校验和检测数据有效性
{
return;
}
else
{
if(PowerVar.PowerEEPIndex==0)
{
PowerVar.PowerEEPIndex = _POWER_BLOCK_MAX-1;
}
else
{
PowerVar.PowerEEPIndex--;
}
}
}
CopyEEPToRam(ADDRESS_9010E,PowerVar.ActInPow,4); // 若所有电量无效则读入第一个存储单元
PowerVar.PowerEEPIndex = 0;
}
/*
***************************************************************************************************
函数 : void ReadPulseConst(void)
功能 : 读取并校验脉冲常数函数
***************************************************************************************************
*/
/*
void ReadPulseConst(void)
{
INT8U consttmp;
CopyEEPToRam(ADDRESS_C030E+1,&consttmp,1); // 读入脉冲常数
if(consttmp== 0) // 如果常数为0,默认为3200
{
PowerVar.PulseConst = 32;
}
else
{
BCDToHEX8(&consttmp,1);
if(PowerVar.PulseConst!=consttmp)
{
PowerVar.PulseConst = consttmp;
}
}
}
*/
/*
***************************************************************************************************
函数 : void ReadDispConst(void)
功能 : 读取显示条目函数
***************************************************************************************************
*/
void ReadDispConst(void)
{
INT8U consttmp[2];
CopyEEPToRam(ADDRESS_D400E,consttmp,2); // 读入显示范围和循显时间
PowerVar.DisplayCouter=0x01;//0x0C; //有功电量
if(consttmp[0]&0x08)PowerVar.DisplayCouter|=0x02; // 资产号
if(consttmp[1]&0x80)PowerVar.DisplayCouter|=0x04; // 常数
// if(((consttmp[0]&0x08)==1)&&((consttmp[1]&0x80)==1))PowerVar.DisplayCouter=0x0B;// 资产号+常数
CopyEEPToRam(ADDRESS_C113E,consttmp,1); // 读入循显时间
if(consttmp[0]!=0)
{
BCDToHEX8(consttmp,1);
Disp_Time=consttmp[0];
}
else Disp_Time=0x05;
}
/*
***************************************************************************************************
函数 : void ReadAdjustConst(void)
功能 : 读取并校验脉冲常数函数
***************************************************************************************************
*/
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相分频数
// 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相分频数
//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相分频数
//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;
}
/*
***************************************************************************************************
函 数 : 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 ****************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -