⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 power.c

📁 本代码以AVR单片机为主控制器
💻 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 + -