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

📄 measure.c

📁 本代码为电子式单相多费率电能表的源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <Reg936.h> 
#include <Meter_def.h>
#include <General.h>
#include <var.h>

//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
//函数定义
//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
void Resume(void);
void Measure(void);
void Ery_Proc(uchar revp,uchar fee);
void ReadPosSaveEry(void);
void PosErySaveProcess(void);
void ReadRevSaveEry(void);
void RevErySaveProcess(void);
void CreateRealTimeEry(void);
void PowerDownProcess(void);
bit  Write24C64(uchar idata *ptr,uchar Addr1,uchar Addr2,uchar DataLen);
bit  Read24C64(uchar idata *ptr,uchar Addr1,uchar Addr2,uchar DataLen);
			  
//**********************************************************
//名称: Resume()
//功能: 上电电量数据恢复,电表运行状态检测
//说明: 
//**********************************************************
void Resume(void)
{
  uchar i,j,*ptr;
  
  ePowerDownCheckFlag = DISABLE; //关闭掉电检测
  //////////////////////////////////////////////////////////
  //剩余脉冲数据恢复,电量小数数据恢复
  //////////////////////////////////////////////////////////
  for(i=0;i<4;i++)
  {
    Read24C64(CommVariant,0x00,0x00+i*4,4);
    ptr = &Energy.PulseTmp1[0]+i*4;
    if(CommVariant[3]!=~SumCHK(CommVariant,3)) //数据出错,清零处理
    {
      ArrayInit(ptr,3);
      *(ptr+3) = 0xFF;
    }
    else //数据正确,写到内存
    {
      for(j=0;j<4;j++)
        *(ptr+j) = CommVariant[j];
    }
  }
  
  //////////////////////////////////////////////////////////
  //正反向(峰、平、谷)整数数据恢复
  //由电量清零命令来实现电量从零开始计量
  ////////////////////////////////////////////////////////// 
  
  //////////////////////////////////////////////////////////
  //恢复RTC缓存指针
  //////////////////////////////////////////////////////////
  Read24C64(CommVariant,0x00,0x17,1);
  RTCBackPtr = CommVariant[0];

  //////////////////////////////////////////////////////////
  //恢复正反向整数电量保存指针
  //////////////////////////////////////////////////////////
  Read24C64(PosErySavePtr,0x06,0xFE,2);
  Read24C64(RevErySavePtr,0x06,0x7E,2);
  
  //////////////////////////////////////////////////////////
  //电表在新进状态时,连续运行36小时后自动切换至运行状态
  //////////////////////////////////////////////////////////
  Read24C64(CommVariant,0x00,0xEE,2);
  CommVariant[0] &= 0x03;
  if(CommVariant[0]==0x00)  isNewState = 0x80;
  else  isNewState = 0x00;
  
  ePowerDownCheckFlag = ENABLE; //打开掉电检测
  //////////////////////////////////////////////////////////
  PowerDownProcess(); //掉电检测处理程序
  //////////////////////////////////////////////////////////
}		  	  

//**********************************************************
//名称:Measure()
//功能:
//说明:安徽表为三费率表(峰、平、谷),正反向分别计量
//**********************************************************
void Measure(void)
{
  Watchdog_feed(); //喂狗
  
  ///////////////////////////////////////////////
  ePowerDownCheckFlag = DISABLE; //关闭掉电检测
  ///////////////////////////////////////////////
  
  ErySaveFlag = 0; //(正/反向)整数电量保存标志
  ErySaveCode = 0; //(正/反向)整数电量保存编号
  Ery_Proc(1,0); //正峰
  Ery_Proc(1,1); //正平
  Ery_Proc(1,2); //正谷
  PosErySaveProcess();
  
  ErySaveFlag = 0; //(正/反向)整数电量保存标志
  ErySaveCode = 0; //(正/反向)整数电量保存编号
  Ery_Proc(0,0); //反峰
  Ery_Proc(0,1); //反平
  Ery_Proc(0,2); //反谷
  RevErySaveProcess();
  
  //////////////////////////////////////////////
  ePowerDownCheckFlag = ENABLE; //打开掉电检测
  //////////////////////////////////////////////
  
  PowerDownProcess(); //掉电检测处理程序
}

//***********************************************************************
//名称: void Ery_Proc(uchar revp,uchar fee)
//功能: 电能计量处理
//说明: revp: 0--反向; 1--正向 ;
//      fee : 0--峰  ; 1--平   ; 2--谷  ;
//***********************************************************************
void Ery_Proc(uchar revp,uchar fee)
{
  uchar tFee,*plsPtr,*eryPtr;

  tFee = fee; //峰、平、谷
  if(revp==0) //反向
  {
    plsPtr = &Energy.PulseTmp2[0];
    eryPtr = &Energy.EryTmp2[0];
  }
  else
  {
    plsPtr = &Energy.PulseTmp1[0];
    eryPtr = &Energy.EryTmp1[0];
  }
  //////////////////////////////////////////////////////////////////////
  //计量说明:正反向电量分别累计
  //////////////////////////////////////////////////////////////////////
  if(plsPtr[tFee]>=CONST) //有脉冲需要本次处理
  { 
    EX1 = 0;
    plsPtr[tFee] -= CONST;
    *(plsPtr+3) = ~( *(plsPtr+0)+*(plsPtr+1)+*(plsPtr+2) ); //(正/反)向(峰、平、谷)脉冲校验
    EX1 = 1;
    eryPtr[tFee]++;
    *(eryPtr+3) = ~( *(eryPtr+0)+*(eryPtr+1)+*(eryPtr+2) ); //(正/反)向(峰、平、谷)小数电量校验
  }
  
  if(eryPtr[tFee]>=100) //电量大于1kWh
  {
    eryPtr[tFee] -= 100; //
    ErySaveFlag = 1;  //(正/反向)整数电量保存标志
    ErySaveCode |= 0x01<<tFee; //(正/反向)整数电量保存编号
    //nErySaveCode: 0x01  0x02  0x04
    //fee:           峰    平    谷
    *(eryPtr+3) = ~( *(eryPtr+0)+*(eryPtr+1)+*(eryPtr+2) ); //(正/反)向(峰、平、谷)小数电量校验
  }
  
}

//***********************************************************************
//名称: PosErySaveProcess()
//功能: 正向电能保存
//说明: 
//***********************************************************************
void PosErySaveProcess(void)
{
  uchar i;
  
  if(ErySaveFlag==1) //整数电量保存标志
  {
    //ErySaveFlag = 0; //整数电量保存标志
    ReadPosSaveEry();   //读取正向整数电量
    //整数电量+1
    for(i=0;i<3;i++)
    {
      if((ErySaveCode>>i)&0x01)  BCDINC(&CommVariant[16+i*4+4+1],3);
    }
    CommVariant[32] = ~SumCHK(&CommVariant[16],16);
    //ErySaveCode = 0; //整数电量保存编号
    //保存整数电量保存指针
    PosErySavePtr[0]++;
    PosErySavePtr[0] &= 0x03; //总共4个备份
    PosErySavePtr[1] = ~PosErySavePtr[0];
    Write24C64(PosErySavePtr,0x06,0xFE,2);
    //保存整数电量
    Write24C64(&CommVariant[16],0x06,0x80+PosErySavePtr[0]*0x20,17);
  }

}

//***********************************************************************
//名称: ReadPosSaveEry()
//功能: 读取正向(峰、平、谷)整数电量
//说明: 
//***********************************************************************
void ReadPosSaveEry(void)
{
  uchar i,Sum;

  //读取整数电量保存指针
  if(PosErySavePtr[1]!=~PosErySavePtr[0]) //内存指针出错
  {
    Read24C64(PosErySavePtr,0x06,0xFE,2);
    if(PosErySavePtr[1]!=~PosErySavePtr[0]) //Eeprom指针出错
    {
      PosErySavePtr[0] = 0x00;
    }
  }
  //读取整数电量
  for(i=0;i<4;i++)
  {
    PosErySavePtr[0] &= 0x03; //总共4个备份
    Read24C64(&CommVariant[16],0x06,0x80+PosErySavePtr[0]*0x20,17);
    Sum = ~SumCHK(&CommVariant[16],16);
    if(Sum!=CommVariant[32])
    {
      PosErySavePtr[0]++;
    }
    ////////////////////////////////////////////////////////////////
    else if(!BCDCHK(&CommVariant[16+4],16-4)) //保证BCD码加法正确
    {
      PosErySavePtr[0]++;
    }
    ////////////////////////////////////////////////////////////////
    else  break;
  }
  
  //恢复整数电量保存指针
  PosErySavePtr[0] &= 0x03;
  PosErySavePtr[1] = ~PosErySavePtr[0];
}

//***********************************************************************
//名称: RevErySaveProcess()
//功能: 反向电能保存
//说明: 
//***********************************************************************
void RevErySaveProcess(void)
{
  uchar i;
  
  if(ErySaveFlag==1) //整数电量保存标志
  {
    //ErySaveFlag = 0; //整数电量保存标志
    ReadRevSaveEry();   //读取反向整数电量
    //整数电量+1
    for(i=0;i<3;i++)
    {
      if((ErySaveCode>>i)&0x01)  BCDINC(&CommVariant[32+i*4+4+1],3);
    }
    CommVariant[48] = ~SumCHK(&CommVariant[32],16);
    //ErySaveCode = 0; //整数电量保存编号
    //保存整数电量保存指针
    RevErySavePtr[0]++;
    RevErySavePtr[0] &= 0x03; //总共4个备份
    RevErySavePtr[1] = ~RevErySavePtr[0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -