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

📄 energy_module.c

📁 一个电表的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//if Active power is positive,VAR is accumulated as it is;
//if Active power is negative,the sign of the VAR is reversed for the accumulation.
//This accumulation mode affects both the VAR registers and the VARCF output.
#define SAVARM          0x04

//1-Enables positive only accumulation of Active power in energy register and pulse output
#define POAM            0x02
//1-Enables absolute value accumulation of Active power in energy register and pulse output
#define ABSAM           0x01


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------

#define IF_CF2          0x80    //Logic one indicates that a pulse of CF2 has been issued.
#define IF_CF1          0x40    //Logic one indicates that a pulse of CF1 has been issued.
#define IF_CYCEND       0x04    //Indicates the end of the energy accumulation over an integer number


#define IE_CF2          0x80    //1-a CF2 pulse issued creates a pending ADE interrupt
#define IE_CF1          0x40    //1-a CF1 pulse issued creates a pending ADE interrupt
#define IE_CYCEND       0x04    //1-the CYCEND flag set creates a pending ADE interrupt


//-------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
     一、 初始参数设计依据:

      1、 ADE7169芯片能量计量的固有数据:电压、电流通道最大输入值:0.5V ,在满刻度输入时最高输出频率为 CFmax=21.1KHz
      2、 设计要求:标称电压(220V)设计为满刻度的60%左右,标称电流(Ib)设计为满刻度的15%以内。最大可作6~7倍表计。
      3、 参数选择:
         a)、电压采样的电阻分压比取1000:1,则电压满刻度百分比:V%FullScale=(220*1.414*1/1000)/0.5=62.23%
         b)、电流采样的分流器300微欧,电流通道增益(IGain)设计为16倍,标称电流设计为10(40)A,则电流满刻度百分比:I%FullScale=(Ib*1.414*(300/1000000)*16)/0.5=13.576%
         C)、标称电流10(40)A,脉冲常数取1600imp/KWh。
      4、 标称电流Ib=10A 时,脉冲输出频率 CFib=(220*10*1600/1000)/3600= 0.9778Hz
      5、 高频脉冲常数计算:CFden=(CFmax * V%FullScale * I%FullScale)/CFib = (21100*62.23% * 13.576%)/0.9778 = 1823 = 0x071E

     二、校表

      1、误差校正:(有功、无功、视在功率精度校准)
         a)、原来误差增益寄存器清零
         b)、校表台加标称Ib电流
         c)、读得校表台的误差error
         d)、计算误差增益寄存器值并写入之。公式:{(1/(1+%error)-1)* 2^12} 。

      2、相位校正(在误差校正的基础上完成)
         a)、原来相位校正寄存器置0x40
         b)、校表台加相位差60度(感性0.5)标称Ib电流
         c)、读得校表台的误差error
         d)、计算相位校正偏移量并写入寄存器。公式:{(asin(%error) /(2*pi*F*1.22*10^(-6)))+ 0x40}。 pi=3.141592,F=50Hz

      3、小信号偏移补偿 (在误差校正的基础上完成)
         a)、原来偏移补偿寄存器清零
         b)、校表台加相位差0度标称Ib1%电流
         c)、读得校表台的误差error
         d)、计算偏移补偿量并写入寄存器。公式:{%error * CF计算*(CF高频常数/(1+WGain/2^12))*(1/819.2KHz)*2^33}。
             CF计算=在小电流和电压情况下算得的脉冲频率
             CF高频常数=设置高频脉冲常数
             WGain=完成校正时的误差增益寄存器值



*/
 /*
__code const unsigned char EnergyStartUp[]=       //第一次上电时能量计量模块初始化数据,数据长度:28byte。e2prom首地址:eCF1DEN
   { 0x01,0x04, 0x01,0x04,\
     0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,\
     0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00,0x00,\
     0x40, 0x00 ,0x00, 0x00, 0x2B,0x05, 0x10,0x08};
 */

 //==========================================================================================================================================================================


 __idata struct{
  unsigned char VGain;          //电压转换常数
  unsigned char IGain;          //电流转换常数
 };


 __idata unsigned int Vrms;            //电压有效值
 __idata unsigned int Irms;            //电流有效值



//---------------------------------------------------------------------------------------------------------------------------------

//       初始化计量模块

void  EnergyModuleInit(void)
{
  unsigned char loop,err,j,tempdata[4];
  unsigned int i;

  IEIP2_bit.EADE = 0;                  //关闭功率模块中断
  loop=3;
  while (loop--)
  {                                                           //Config the mode registers
     err  = WriteEnergyReg1(MODE1,  (ENCF1OUT | ENCF2OUT));                         // CF1,CF2引脚输出使能
     err |= WriteEnergyReg1(MODE2,  (ZXRMS|CF1_WATT|CF2_VAR|FREQSEL));              // 有效值由电压过零同步,CF1有功脉冲输出,CF2无功脉冲输出,输出线电压频率
     err |= WriteEnergyReg1(WAVEMODE, (WAV1_Current|WAV2_Voltag|WAV_Clk));           // 电流电压曲线记录定义
     err |= WriteEnergyReg1(NLMODE,  (VANOLOAD_OFF|VANOLOAD_OFF|APNOLOAD_OFF));     // 电流、有功、无功、视在均不设置阀值
     err |= WriteEnergyReg1(CALMODE,  SEL_ICH_A);                                   // 指定电流通道为:A通道
     err |= WriteEnergyReg1(GAIN,     (PGA2_X1|PGA1_X16));                          // 电压通道增益x1,电流通道增益x16(用于分流器采样)
     err |= WriteEnergyReg1(ACCMODE,  (ABSVARM | ABSAM));                           // 有功无功均选择绝对值累加
     err |= WriteEnergyReg2(LINCYC,   0xB8,0x0B);                                   // 取3000个周期累加能量作瞬时功率(即1分钟平均功率)

     ClearWatchDog();               //喂狗


     for (i=eIBGAIN,j=IBGAIN;i< eIBGAIN+16;)                                //    参数
     {
       err |= ReadE2prom_Api(i,(unsigned int)(&tempdata[0])+xRAM_Adr,2);     //读E2PROM中的校表参数,地址1CH~23H
       err |= WriteEnergyReg2(j,tempdata[0],tempdata[1]);
       j++;
       i+=2;
     }

     err |= ReadE2prom_Api(i,(unsigned int)(&tempdata[0])+xRAM_Adr,4);      //读E2PROM中的校表参数 ,地址24H~26H ,10H
     err |= WriteEnergyReg1(WDIV,tempdata[0]);
     err |= WriteEnergyReg1(VARDIV,tempdata[1]);
     err |= WriteEnergyReg1(VADIV,tempdata[2]);
     err |= WriteEnergyReg1(PHCAL,tempdata[3]);                             //相位补偿

     err |= ReadE2prom_Api(eCF1DEN,(unsigned int)(&tempdata[0])+xRAM_Adr,4);      //读E2PROM中的校表参数 ,地址28H,2AH
     err |= WriteEnergyReg2(CF1DEN,tempdata[0],tempdata[1]);
     err |= WriteEnergyReg2(CF2DEN,tempdata[2],tempdata[3]);                      //高频脉冲常数

     err |= ReadE2prom_Api(i,(unsigned int)(&VGain)+iRAM_Adr,2);           //读E2PROM中的校表参数 ,电流电压增益

     if (err == ErrorFalse)
       break;
  }

  if (err == ErrorTrue)
  {
    Energy_ERR =1;
  }

  MIRQSTH = 0;                         //清状态标志
  MIRQSTM = 0;
  MIRQSTL = 0;

  MIRQENL = 0;
  MIRQENM = IE_CF2|IE_CF1;             //CF1,CF2产生中断
  MIRQENH = IE_CYCEND;                 //一个功率计数周期到中断

  IEIP2_bit.EADE = 1;                  //允许功率模块中断
}


//---------------------------------------------------------------------------------------------------------------------------------
  //       计量中断处理程序 (累加脉冲)

  #pragma vector = 0x4b
__interrupt void ADE_ISR(void)
{

    if(MIRQSTM_bit.CF1)
    {
        //CF1(有功)脉冲计数       //todo: Count CF1 for Active Energy
        MIRQSTM_bit.CF1 = 0;
        CF1Count++;
    }
    if(MIRQSTM_bit.CF2)
    {
        //CF2(无功)脉冲计数          //todo: Count CF2 for Reactive Energy
        MIRQSTM_bit.CF2=0;
        CF2Count++;
     //   G_LED ^= 1;
    }
    if(MIRQSTH_bit.CYCEND)
    {
       // 功率计算周期到
      MIRQSTH_bit.CYCEND=0;            //todo: Set Linecyc End Flag
      PowerMeasure =1;
//     G_LED ^= 1;
    }
}
//---------------------------------------------------------------------------------------------------------------------------------

void EnergyADD( unsigned long __idata * Data)
{
  *Data = BCD32Inc(*Data);      //总电量+0.01kwh
  if ((DQ_Fl>MAX_Fn)| (!DQ_Fl))
  {
    *(Data+3) = BCD32Inc(*(Data+3));    //费率电量+0.01kwh ,费率不正确,费率电量累加到平电量中
  }
  else
  {
    *(Data+DQ_Fl) = BCD32Inc(*(Data+DQ_Fl));  //费率电量+0.01kwh
  }
}


//---------------------------------------------------------------------------------------------------------------------------------


void EnergyModule(void)
{

  if  (MIRQSTH_bit.RESET)
  {
     MIRQSTH_bit.RESET=0;
     EnergyModuleInit();            //能量模块已复位,初始化模块
  }
  else

  {
     if (CF1Count > CF_const)
     {                                         //  三相表时可以考虑正反向计量
        IE_bit.EA = 0;
        CF1Count -= CF_const;
        EnergyADD(rPKwhPwr_Dtr);       // rPKwhPwr_Dtr[0]=BCD32Inc(rPKwhPwr_Dtr[0]);              //有功总电量、费率电量+0.01kwh
        IE_bit.EA =1;

     }

     if (CF2Count >  CF_const)
     {                                         //  三相表时可以考虑正反向、四象限计量
        IE_bit.EA = 0;
        CF2Count -= CF_const;
        EnergyADD(rPKvarhPwr_Dtr);      //rPKvarhPwr_Dtr[0]=BCD32Inc(rPKvarhPwr_Dtr[0]);   // EnergyADD(rPKvarhPwr_Dtr);            //无功总电量、费率电量+0.01kvarh
        IE_bit.EA =1;
      }

     if  (PowerMeasure)                                //有功、无功功率处理
     {
        PowerMeasure=0;
        //此处添加有功、无功功率处理。
     }

     TempChar[3]=0;
     GetEnergySFR(VRMS,Temp8L,Temp8M,Temp8H);                //读电压有效值
     Vrms = (unsigned int)((Temp32*(124+VGain))>>16);        //含一位小数(Vconst扩大10倍)124
     Vrms = Hex16BCD(Vrms);                                  //bin转换成BCD码

     TempChar[3]=0;
     GetEnergySFR(IRMS,Temp8L,Temp8M,Temp8H);                //读电流有效值
     Irms = (unsigned int)((Temp32*(124+IGain))>>16);      //含二位小数(Iconst扩大100倍)
     Irms = Hex16BCD(Irms);                                  //bin转换成BCD码

     if (PowerMeasure)
     {
        PowerMeasure =0;

        //此处添加平均功率处理
     }
  }
}



//======================================================================================================
#endif


⌨️ 快捷键说明

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