📄 energy.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 + -