📄 emeter.c
字号:
/**
* Nominal Mains Frequency:
* e.g. 50Hz.
*/
set_parameter(mSET_NOMFREQ, defSET_NOMFREQ);
/**
* Phase Error Correction:
* Sets phase error for current 1/2 at nominal mains frequency for
* current transformer according to its specification
* The phase error of the shunt is zero.
*/
set_parameter(mSET_PHASECORR1, (int)s_parameters.pSET_PHASECORR1);
set_parameter(mSET_PHASECORR2, (int)s_parameters.pSET_PHASECORR2);
/** Adjustment parameters for the two currents:
* Current Transformer:
*
* There are two possibilties to adjust the two current
* values:
* -# Only one current value is scaled with a factor > 1
* to fit the others current's value. The factor
* for the later is set to 1.\n
* In this example current I1 would be scaled by 0.32/0.30 = 1.06667.
* (The RMS values at the maximum current are used to calculate the
* factor.)
* The current transformer's value is scaled to fit with
* shunt's value, because the shunt's values are bigger,
* 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, s_parameters.pSET_ADAPTI1); // = 1 * POW_2_14 = 16384
set_parameter(mSET_ADAPTI2, s_parameters.pSET_ADAPTI2); // = 1 * POW_2_14 = 16384
/** Adjustment parameters Gain settings: */
set_parameter(mSET_GAINCORR1, s_parameters.pSET_GAINCORR1);
set_parameter(mSET_GAINCORR2, s_parameters.pSET_GAINCORR2);
/** 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);
set_parameter(mSET_POFFSET1_LO, s_parameters.pSET_POFFSET1.w[0]);
set_parameter(mSET_POFFSET1_HI, s_parameters.pSET_POFFSET1.w[1]);
set_parameter(mSET_POFFSET2_LO, s_parameters.pSET_POFFSET2.w[0]);
set_parameter(mSET_POFFSET2_HI, s_parameters.pSET_POFFSET2.w[1]);
/** 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);
/** 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;
_EINT();
} // End of start_measurement()
//====================================================================
//
// * Starts calibration.
// *
//
void start_calibration(void)
{
volatile unsigned int timeout;
// /\ Prevent 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)) ;
}
MBCTL = 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;
MBCTL = IN0IE;
_EINT();
} // End of start_measurement()
//====================================================================
void set_esp_active(void)
{
// Restart measurement (set Embedded Signal Processing into "Measurement" mode)
SD16CTL |= SD16REFON; // Switch Reference on
ESPCTL &= ~(0x08 + ESPSUSP); // Set ESP into Active Mode
MBCTL= IN0IE; // Enable Mailbox Interrupts
// Startmeasurement (set Embedded Signal Processing into "Measurement" mode)
// ensure that it is not in measurement or calibration mode,
if ((RET0 & 0x8000) == 0)
{
// Set Embedded Signal Processing into "Idle" mode
MBOUT1= modeMEASURE; // modeMEASURE;
MBOUT0= mSET_MODE;
}
OP_Mode = measure;
#ifdef TIMERA_PULSE_OUTPUT
Init_TimerA(); // Start TimerA
#endif
SVSCTL = 0x70; // set SVS to 2.65 V to detect voltage drops below save operating area
}
//====================================================================
void set_esp_idle(void)
{
// 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 |= 0x08 + ESPSUSP; // Set ESP into Suspend Mode
// incl. Bug Fix for Suspend 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();
MBCTL &= ~(IN0IFG + IN0IE); // Clear any Pending MB interrupt and disable
// ESP interrupt
SD16CTL &= ~SD16REFON; // Switch Reference off
OP_Mode = idle;
#ifdef withDisplay
DisplayIDLE();
//LCD_OFF; // Switch LCD off
#endif // withDisplay
P1OUT |= 0x03; // set P1.0 + P1.1 -> LED off
#ifdef TIMERA_PULSE_OUTPUT
TACTL = TACLR | MC_0 | TASSEL_1; // Stop TimerA
TACCTL0 &= ~CCIFG; // Clear Pending ISR for CCR0
#endif
SVSCTL = 0x00; // switch SVS off
} // End of idle_esp()
//====================================================================
/**
* 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_MSP430
void esp_isr(void) __interrupt[ESP430_VECTOR]
#endif
#ifdef __TI_COMPILER_VERSION__
__interrupt void esp_isr(void);
ESP430_ISR(esp_isr)
__interrupt void esp_isr(void)
#endif
{
unsigned int msg_data = MBIN1;
unsigned int msg = MBIN0;
// 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 "Measure" mode
msg_data = 0; // prevent that the other functions in the ISR are executed
set_parameter(mSET_EVENT, defSET_EVENT );
// Start measurement (set Embedded Signal Processing into "Measurement" mode)
MBOUT1= modeMEASURE; //ESP_MEASURE;
MBOUT0= mSET_MODE;
}
} // 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
{
wfs1 = WAVEFSV1;
wfs2 = WAVEFSI1;
wfs3 = WAVEFSI2;
/*
if (TX_Mode == 1)
{
while ((U0IFG&UTXIFG0)==0); // wait till TX buf empty
TXBUF0=(wfs1>>8) & 0xFF; // transmit ch
while ((U0IFG&UTXIFG0)==0); // wait till TX buf empty
TXBUF0=(wfs1) & 0xFF; // transmit ch
while ((U0IFG&UTXIFG0)==0); // wait till TX buf empty
TXBUF0=(wfs2>>8) & 0xFF; // transmit ch
while ((U0IFG&UTXIFG0)==0); // wait till TX buf empty
TXBUF0=(wfs2) & 0xFF; // transmit ch
while ((U0IFG&UTXIFG0)==0); // wait till TX buf empty
TXBUF0=0xa5; // transmit ch
}
*/
}
//
// * Get Energy and create Pulses
//
#ifdef TIMERA_PULSE_OUTPUT
if ((msg_data & ILREACHEDFG)) //
{
P_reading ++;
}
#else
if (uiIntLevelRepeatCount == (defSET_INTRPTLEVL_REPEAT/2))
{
#ifndef INVERT_PULSE
P1OUT &= ~BIT1; // Clear Bit which may has been set in last ISR call
#else
P1OUT |= BIT1;
#endif
}
if ((msg_data & ILREACHEDFG)) //
{
uiIntLevelRepeatCount --;
if (uiIntLevelRepeatCount == 0)
{
P1OUT ^= BIT1; // Toggle P1.1
uiIntLevelRepeatCount = defSET_INTRPTLEVL_REPEAT;
}
}
#endif // TIMERA_PULSE_OUTPUT
if (msg_data & ZXTRFG)
{
ZXLDFGedge = 1;
}
if ((msg_data & ZXLDFG) && ZXLDFGedge)
{
ZXLDFGedge = 0;
}
/*
// DO NOT USE THIS FLAG AS IT IS NOT WORKING OK IN THIS VERSION !!!
if (msg_data & NEGENFG) // Negativ Energy measured ?
{
// P1OUT |= 0x01; // set P1.0
}
else
{
// P1OUT &= ~0x01; // clear P1.0
}
*/
/**
* Accumulates the active energy depending on the tampering flag so
* that always the "worst case" energy is calculated.
*/
if ((msg_data & ENRDYFG))
{
static unsigned char temp_count = defTemp_repeat;
if ((ACTENERGY1_HI & 0x8000) > 0 ) {// Negativ Energy measured ?
negenfg = 1; // set global neg. Energy Flag
// P1OUT |= 0x01; // set P1.0
}else {
// P1OUT &= ~0x01; // clear P1.0
negenfg = 0; // clear global neg. Energy Flag
}
#if I2SENSOR != NONE // Tampering (I1 << I2 or I2 >> I1)?
if (!(msg_data & I2GTI1FG) ) {// I1 > I2?
energy.w[0] = ACTENERGY1_LO;
energy.w[1] = ACTENERGY1_HI;
} else {// I1 < I2!
energy.w[0] = ACTENERGY2_LO;
energy.w[1] = ACTENERGY2_HI;
}
#else
energy.w[0] = ACTENERGY1_LO;
energy.w[1] = ACTENERGY1_HI;
#endif
if (msg_data & NEGENFG) // Negativ Energy measured ?
total_energy -= (float)energy.l;
else
total_energy += (float)energy.l;
//total_energy += (float)energy.l;
//
// * The seconds are counted based on the ESP430CE1 energy ready interrupts.
//
temp_count--;
if ((temp_count == 0) && (defTemp_repeat != 0)) {
//
// * Every minute a temperature measurement is requested.
//
temp_count = defTemp_repeat;
sys_status |= RequestTemp; // set mark that a Temp. Measurement is requested
}
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;
sys_status |= NewTemp;
}
}
//====================================================================
/**
* Interrupt service routine for SD16 (Dummy).
*
*/
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ < 200
interrupt[SD16_VECTOR] void SD16_isr(void)
#else
#pragma vector=SD16_VECTOR
__interrupt void SD16_isr( void )
#endif
#endif
#ifdef __CROSSWORKS_MSP430
void SD16_isr(void) __interrupt[SD16_VECTOR]
#endif
#ifdef __TI_COMPILER_VERSION__
__interrupt void SD16_isr(void);
SD16_ISR(SD16_isr)
__interrupt void SD16_isr(void)
#endif
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -