📄 emeter.c
字号:
* so the current transformer's values are multiplied with
* a factor > 1 - otherwise the shunt's values would be
* multiplied with a factor < 1 and this would result
* in degraded accuracy.
* -# Both currents are scaled with a factor > 1 to use the maximum FSR
* (Full Scale Range) at the maximum current Imax.\n
* In this example current I1 would be scaled by 0.44/0.30 = 1.46667
* and current I2 would be scaled by 0.44/0.32 = 1.25.
* (The RMS values at the maximum current are used to calculate the
* factor. VFSR(Peak) = 0.625 (see datasheet) => VFSR(RMS) = 0.44)
*/
set_parameter(mSET_ADAPTI1, defSET_ADAPTI1); // = 1 * POW_2_14 = 16384
set_parameter(mSET_ADAPTI2, defSET_ADAPTI2); // = 1 * POW_2_14 = 16384
/** \par Adjustment parameters Offset settings: */
set_parameter(mSET_V1OFFSET, s_parameters.pSET_V1OFFSET);
set_parameter(mSET_I1OFFSET, s_parameters.pSET_I1OFFSET);
set_parameter(mSET_I2OFFSET, s_parameters.pSET_I2OFFSET);
/** \par Adjustment parameters start up currents: */
set_parameter(mSET_STARTCURR_INT, s_parameters.pSET_STARTCURR_INT);
set_parameter(mSET_STARTCURR_FRAC, s_parameters.pSET_STARTCURR_FRAC);
/** \par Adjustment parameters for DC Removal Periods: */
set_parameter(mSET_DCREMPER, defSET_DCREMPER);
} // End of init_esp_parameter()
//====================================================================
/**
* Starts energy measurement.
*
*/
void start_measurement(void)
{
// Set event message request flags:
set_parameter(mSET_EVENT, defSET_EVENT );
total_energy = 0;
MBCTL= IN0IE;
// Start measurement (set Embedded Signal Processing into "Measurement" mode)
MBOUT1= modeMEASURE; //ESP_MEASURE;
MBOUT0= mSET_MODE;
OP_Mode = measure;
} // End of start_measurement()
//====================================================================
//
// * Starts calibration.
// *
//
void start_calibration(void)
{
volatile unsigned int timeout;
// /\ Prevend variable from being "optimized".
//
// * ensure that it is not in measurement or calibration mode,
//
if ((RET0 & 0x8000) != 0)
{
// Set Embedded Signal Processing into "Idle" mode
MBOUT1= modeIDLE; // ESP_IDLE;
MBOUT0= mSET_MODE;
timeout= 0xffff;
while (((RET0 & 0x8000) != 0) && (timeout-- > 0)) ;
}
total_energy= 0;
// Set event message request flags:
set_parameter(mSET_EVENT,
CALRDYME); // Interrupt on "Calibration values ready"
set_parameter(mSET_CALCYCLCNT, CalCyclCnt); // = set requested cycles for measurement
// Start measurement (set Embedded Signal Processing into "Calibration" mode)
set_parameter(mSET_MODE, modeCALIBRATION);
OP_Mode = calibration;
} // End of start_measurement()
//====================================================================
/**
* Interrupt service routine for messages sent by ESP430CE1.
*
*/
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ < 200
interrupt[ESP430_VECTOR] void esp_isr(void)
#else
#pragma vector=ESP430_VECTOR
__interrupt void esp_isr( void )
#endif
#endif
#ifdef __CROSSWORKS__
void esp_isr(void) __interrupt[ESP430_VECTOR]
#endif
{
unsigned int msg_data = MBIN1;
unsigned int msg = MBIN0;
#ifdef ExtIntLevel
unsigned int i = def_togglerepeat;
#endif
P1OUT |= 0x01; // set P1.0
if (msg == mEVENT)
{
//
// * Get the Calibration data
//
if ((msg_data & CALRDYFG) == CALRDYFG) // Calibration data available
{
if ( OP_Mode == calibration)
{
energy.w[0] = ACTENERGY1_LO;
energy.w[1] = ACTENERGY1_HI;
#ifdef withUARTComm
TX_Mode = tx_cal;
#endif // withUARTComm
OP_Mode = done;
// Set Embedded Signal Processing into "Idle" mode
// MBOUT1= modeIDLE; // ESP_IDLE;
MBOUT1= modeMEASURE; //ESP_MEASURE;
MBOUT0= mSET_MODE;
msg_data = 0; // prevent that the other functions in the ISR are executed
}
} // End of if ((msg_data & CALRDY)
msg_data = msg_data & defSET_EVENT ; //mask with event request mask
//
// * Get the WFS
//
// if ((msg_data & WFSRDYFG)) // New Waveform Samples available
// WFS could always be copied
{
wfs1 = WAVEFSV1;
wfs2 = WAVEFSI1;
wfs3 = WAVEFSI2;
}
//
// * Get Energy and create Pulses
//
#ifndef ExtIntLevel
if ((msg_data & ILREACHEDFG)) //
{
static unsigned int i = defSET_INTRPTLEVL_REPEAT;
i--;
if (i == 0)
{
P1OUT ^= 0x02; // toggle P1.1
i = defSET_INTRPTLEVL_REPEAT;
}
}
#else
if (msg_data & ZXTRFG)
{
ZXLDFGedge = 1;
if (sumenergy >= s_parameters.pSET_TOGGLELEVEL)
{
sumenergy -= s_parameters.pSET_TOGGLELEVEL;
i--;
if (i == 0)
{
P1OUT ^= 0x02; // toggle P1.1
i = s_parameters.pSET_TOGGLELEVEL;
}
}
}
if ((msg_data & ZXLDFG) && ZXLDFGedge)
{
ZXLDFGedge = 0;
tempenergy.w[0] = ACTENSPER1_LO;
tempenergy.w[1] = ACTENSPER1_HI;
sumenergy += tempenergy.l;
if (tempenergy.l > maxenergy) {maxenergy = tempenergy.l;};
if (sumenergy >= s_parameters.pSET_TOGGLELEVEL)
{
sumenergy -= s_parameters.pSET_TOGGLELEVEL;
i--;
if (i == 0)
{
P1OUT ^= 0x02; // toggle P1.1
i = def_togglerepeat;
}
}
}
#endif
/**
* Accumulates the active energy depending on the tampering flag so
* that always the "worst case" energy is calculated.
*/
if ((msg_data & ENRDYFG)) // Tampering (I1 << I2 or I2 >> I1)?
// if ((msg_data & ILREACHED) == ILREACHED) // Tampering (I1 << I2 or I2 >> I1)?
{
unsigned int i;
unsigned int * a = (unsigned int *) RET0_;
unsigned int * b = (unsigned int *) &savedRET[0];
static unsigned char temp_count = Temp_repeat;
for (i=0; i != ((RET31_ - RET0_)/2); i++)
{
*b++ = *a++;
}
if (!(msg_data & I2GTI1FG) ) // I1 > I2?
{
energy.w[0] = RET8;
energy.w[1] = RET9;
} else // I1 < I2!
{
energy.w[0] = ACTENERGY1_LO;
energy.w[1] = ACTENERGY1_HI;
}
total_energy += (float)energy.l;
//
// * The seconds are counted based on the ESP430CE1 energy ready interrupts.
//
temp_count--;
if (temp_count == 0)
{
//
// * Every minute a temperature measurement is requested.
//
temp_count = Temp_repeat;
MBOUT0= mTEMP;
}
sys_status |= NewValues; // set mark that new samples are available
if (OP_Mode != idle) LPM3_EXIT; // back to active mode after ISR
} // End of if ((msg_data & ENRDY)
} // End of if (MBIN0 == mEVENT)
if (msg == mTEMPRDY)
{
//
// * The temperature is saved as soon as it is delivered by the ESP430.
//
temperature= msg_data;
}
// Test if S1 was pressed
if (P2IFG & 0x04)
{
P2IFG &= ~0x04; //clear flag
#ifdef withDisplay
DisplayNextData(); //next display mode
#endif // withDisplay
}
// Test if S2 was pressed
if (P2IFG & 0x08)
{
P2IFG &= ~0x08; //clear flag
// Stop measurement (set Embedded Signal Processing into "Idle" mode)
// Set Embedded Signal Processing into "Idle" mode
MBOUT1= modeIDLE; // ESP_IDLE;
MBOUT0= mSET_MODE;
while ((RET0 & 0x8000) != 0); // Wait for Idle mode
// Shut donw ESP (set Embedded Signal Processing into "Suspend" mode)
// ensure that it is not in measurement or calibration mode,
if ((RET0 & 0x8000) == 0)
{
ESPCTL |= ESPSUSP; // Set ESP into Suspend Mode
// ESPCTL = 0; // Set ESP into Off Mode
}
// wait 10 clock till proper access to the SD16 is possilbe (9 clock are required)
_NOP();_NOP();_NOP();_NOP();_NOP();
_NOP();_NOP();_NOP();_NOP();_NOP();
SD16CTL &= ~SD16REFON; // Switch Reference off
OP_Mode = idle;
DisplayIDLE();
//LCD_OFF; // Switch LCD off
P2IE |= 0x08; //enable interrupt
_BIS_SR_IRQ(LPM3_bits); // not back to active mode after ISR
}
P1OUT &= ~0x01; // clear P1.0
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -