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

📄 energy.c

📁 8051试验程序 基础教材
💻 C
字号:
/*
-02/27/2006: Petre M.
  -this file contains functions used to measure active,
    reactive and apparent energies

*/

#include "ioADE7169F16.h"
#include "extern_declarations.h"
#include "EEPROM_locations.h"
#include "default_val.h"

//this function intializes the registers used in energy measurement
void Setup_Energy(void) {

  //erase eventual ADE interrupts triggered previously
  MIRQSTL = 0;
  MIRQSTM = 0;
  MIRQSTH = 0;

  /*0=don't reset the energy measurement registers to their reset values
     0=enable the zero crossing low pass filter
      0=disable the digital integrator used with di/dt sensor
       0=CH1, CH2 ADCs not swaped
        0=disable power down for voltage and current ADCs
         1=disable frequency output for CF2
          0=enable frequency output for CF1
           0=enable HPFs in voltage and current channels
  */

  Write_ADE_SFR(0x00, 0x04, MODE1);

  /*01=CF2 proportional to reactive power
      00=CF1 proportional to active power
        0=does not matter because of the settings above for CF1 and CF2
         1=update RMS values synchronously with the zero crossings
          0=PER_FREQ register holds a period measurement
           1=obligatory to 1
  */
  Write_ADE_SFR(0x00, 0x45, MODE2);

  /*000=waveform source 2 is current
       001=waveform source 1 is voltage
          11=waveform samples output data rate is the smallest 3.2ksps
  */
  Write_ADE_SFR(0x00, 0x07, WAVMODE);

  /*0=reserved
     1=Irms no load threshold detection is enabled
      01=apparent power no-load threshold enabled with a threshold=0.03% of FS
        01=reactive power no-load threshold enabled with a threshold=0.015% of FS
          01=active power no-load threshold enabled with a threshold=0.015% of FS
  */
  Write_ADE_SFR(0x00, 0x55, NLMODE);

  Write_ADE_SFR(0x00, 0x00, ACCMODE);

  //read GAIN value from EEPROM
  Tx_CTRL_byte(Nr_Bytes_1, GAIN_val,(unsigned char __idata  *)&Temporary[0]);
  Write_ADE_SFR(0x00, Temporary[0], GAIN);

  /*00=reserved
      01=current channel connected to IA
        0=leave voltage channel alone (not shorted to ground)
         0=leave current channel alone (not shorted to ground)
          00=reserved
  */
  Write_ADE_SFR(0x00, 0x10, CALMODE);

  //LINCYC=20, i.e. the line accumulation of energy is done every 20
  //half periods of the input signal (i.e. this means 0.2sec at 50Hz)
  Write_ADE_SFR(0x00, 0x14, LINCYC);

  //WDIV=0
  Write_ADE_SFR(0x00, 0x00, WDIV);

  //CF1NUM=0
  Write_ADE_SFR(0x00, 0x00, CF1NUM);

  Tx_CTRL_byte(Nr_Bytes_2, CF1DEN_val,(unsigned char __idata  *)&Temporary[0]);
  Write_ADE_SFR(Temporary[1], Temporary[0], CF1DEN);

  Tx_CTRL_byte(Nr_Bytes_2, WGAIN_val,(unsigned char __idata  *)&Temporary[0]);
  Write_ADE_SFR(Temporary[1], Temporary[0], WGAIN);

  Tx_CTRL_byte(Nr_Bytes_1, PHCAL_val,(unsigned char __idata  *)&Temporary[0]);
  Write_ADE_SFR(0x00, Temporary[0], PHCAL);

  Tx_CTRL_byte(Nr_Bytes_2, WATTOS_val,(unsigned char __idata  *)&Temporary[0]);
  Write_ADE_SFR(Temporary[1], Temporary[0], WATTOS);


  //bit6 of IPSME =0. This means the status bits of ADE interrupts is
  //cleared when a 0 is written over the bit
  IPSME = IPSME & NBit6;

  //set ADE interrupt with LOW priority
  IP_bit.PADE = 0;

  //enable CF1 interrupts
  MIRQENM_bit.CF1 = 1;

  //enable interrupt when the line energy accumulation ends
/////  MIRQENH_bit.CYCEND = 1;

  //enable CF2 interrupts
//  MIRQENM_bit.CF2 = 1;

  //generate an interrupt at the end of LINCYC half line periods
//  MIRQENH_bit.CYCEN = 1;

  //enable Energy Metering Interrupt
  IEIP2_bit.EADE = 1;

  return;
}

//this function is called during the ADE interrupt
void ADE_Interrupt(void) {

  //if CF1 interrupt has been generated
  if (MIRQSTM_bit.CF1) {

    //Active_Energy.B0 counts the CF impulses
    Active_Energy.B0=Active_Energy.B0+1;

    //clear the status bit that has generated the interrupt
    MIRQSTM_bit.CF1 = 0;
  }
/*
  //if CF2 interrupt has been generated
  if (MIRQSTM_bit.CF2) {

    //CF2_Frac counts from 0 to limit_counter in a circular fashion
    CF2_Frac++;
    if (CF2_Frac==limit_counter)
      CF2_Frac=0;

    if (CF2_Frac!=(limit_counter-1)) {
      //increment New_CF2_Counter only if CF2_Frac!=limit_counter
      New_CF2_Counter = New_CF2_Counter + 1;
    }

    //clear the status bit that has generated the interrupt
    MIRQSTM_bit.CF2 = 0;
  }
*/

  return;
}

//this function reads from EEPROM all energy values
//The program waits until the data is stored in IRAM
void Reload_from_EEPROM(void) {

  //read the active energy from EEPROM
  Active_Energy_read();

  //the Date is reloaded from EEPROM
  Calendar_read();

  //the ratios used to compute Irms and Vrms are loaded from EEPROM
  Irms_threshold_read();

  Vrms_threshold_read();

  return;
}

//this function reads the active energy from EEPROM
void Active_Energy_read(void) {

  Tx_CTRL_byte(Nr_Bytes_5, Day_Ac_Energy,&Active_Energy.B0);
  return;
}

//this function reads the active energy from EEPROM
void Active_Energy_write(void) {

  Tx_byte(Nr_Bytes_5,Day_Ac_Energy,&Active_Energy.B0);

  return;
}



//this function stores the energies every month when
//ordered during Midnight_management routine
void Monthly_Energy_Storage(void) {

  //test if a monthly storage has been ordered
  if (Low_Priority_Command[0] & Bit5) {

    //start the storage of the bytes representing the
    //energies at EEPROM_address address into EEPROM
    //To ease the program, we use the functions that wait to finish the communication
    Tx_byte(Nr_Bytes_5, Monthly_Ac_Energy,&Active_Energy.B0);

    //read back one byte to be sure we don't turn off the processor before
    //the EEPROM writing ends
    Tx_CTRL_byte(Nr_Bytes_1, EEPROM_Fault_Days,&Fault_Days);

    //cancel the monthly storage command
    Clear_flag(NBit5, &Low_Priority_Command[0]);
  }
  return;
}


⌨️ 快捷键说明

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