📄 emeter-foreground.c
字号:
{
if (phase->current.leading < 0)
p = -p;
}
return p;
}
#endif
#if defined(__AQCOMPILER__) || defined(__IAR_SYSTEMS_ICC__)
void main(void)
#else
int main(int argc, char *argv[])
#endif
{
#if !defined(SINGLE_PHASE)
int ch;
static struct phase_parms_s *phase;
static struct phase_nv_parms_s const *phase_nv;
#endif
static long int x;
#if !defined(__MSP430__)
if (start_host_environment(argc, argv) < 0)
exit(2);
#endif
system_setup();
#if defined(PHASE_CORRECTION_SUPPORT) && !defined(DYNAMIC_PHASE_CORRECTION_SUPPORT)
#if !defined(SINGLE_PHASE)
for (ch = 0; ch < NUM_PHASES; ch++)
{
phase = &chan[ch];
phase_nv = &nv_parms.seg_a.s.chan[ch];
#endif
#if defined(__MSP430_HAS_ADC12__) || defined(__MSP430_HAS_ADC10__)
phase->current.in_phase_phase_correction_step[0] = 2 - (phase_nv->current.phase_correction[0] + 128)/256;
phase->current.in_phase_fir_beta[0] = fir_coeffs[((phase_nv->current.phase_correction[0] + 128)%256) >> 1][0];
phase->current.in_phase_fir_gain[0] = fir_coeffs[((phase_nv->current.phase_correction[0] + 128)%256) >> 1][1];
#if GAIN_STAGES > 1
phase->current.in_phase_phase_correction_step[1] = 2 - (phase_nv->current.phase_correction[1] + 128)/256;
phase->current.in_phase_fir_beta[1] = fir_coeffs[((phase_nv->current.phase_correction[1] + 128)%256) >> 1][0];
phase->current.in_phase_fir_gain[1] = fir_coeffs[((phase_nv->current.phase_correction[1] + 128)%256) >> 1][1];
#endif
#else
phase->current.in_phase_phase_correction_step[0] = 2 - phase_nv->current.phase_correction/256;
SD16PRE_NEUTRAL = phase_nv->neutral.phase_correction%256;
SD16PRE_LIVE = phase_nv->current.phase_correction%256;
#endif
#if !defined(SINGLE_PHASE)
}
#endif
#endif
#if defined(MULTI_RATE_SUPPORT)
tariff_initialise();
#endif
for (;;)
{
kick_watchdog();
#if !defined(__MSP430__)
/* In the host environment we need to simulate interrupts here */
adc_interrupt();
#endif
#if !defined(SINGLE_PHASE)
phase = chan;
phase_nv = nv_parms.seg_a.s.chan;
for (ch = 0; ch < NUM_PHASES; ch++)
{
#endif
/* Unless we are in normal operating mode, we should wait to be
woken by a significant event from the interrupt routines. */
#if defined(__MSP430__)
if (operating_mode != OPERATING_MODE_NORMAL)
_BIS_SR(LPM0_bits);
#endif
#if defined(POWER_DOWN_SUPPORT)
if (operating_mode == OPERATING_MODE_POWERFAIL)
switch_to_powerfail_mode();
#endif
#if defined(LIMP_MODE_SUPPORT) && defined(IEC1107_SUPPORT)
if (nv_parms.seg_a.s.meter_uncalibrated)
enable_ir_receiver();
#endif
if ((phase->status & NEW_LOG))
{
/* The background activity has informed us that it is time to
perform a block processing operation. */
phase->status &= ~NEW_LOG;
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD))
{
/* The meter is suffering magnetic tampering, so continuously
charge for a great deal of electricity. */
x = phase->V_rms*MAGNETIC_INTERFERENCE_CURRENT/(10*100);
}
else
#endif
if (operating_mode == OPERATING_MODE_NORMAL)
{
/* We can only do real power assessment in full operating mode */
#if !defined(SINGLE_PHASE)
x = power(phase, phase_nv);
#if defined(PRECALCULATED_PARAMETER_SUPPORT)
#if defined(IRMS_SUPPORT)
phase->I_rms = current(phase, phase_nv, ch);
#endif
#if defined(VRMS_SUPPORT)
phase->V_rms = voltage(phase, phase_nv);
#endif
#endif
#else
x = power();
#if defined(PRECALCULATED_PARAMETER_SUPPORT)
#if defined(IRMS_SUPPORT)
phase->I_rms = current();
#endif
#if defined(VRMS_SUPPORT)
phase->V_rms = voltage();
#endif
#endif
#endif
}
#if defined(LIMP_MODE_SUPPORT)
else if (operating_mode == OPERATING_MODE_LIMP)
{
/* In limp mode we must assess estimated power from only the measured current. */
/* We cannot properly determine current reversal in this mode. Also, current
imbalance is really just a measure of which lead is still connected.
Just treat both the imbalance and reversal conditions as OK */
#if !defined(SINGLE_PHASE)
x = current(phase, phase_nv, ch);
#if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(VRMS_SUPPORT)
phase->V_rms = voltage(phase, phase_nv);
#endif
#else
x = current();
#if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(VRMS_SUPPORT)
phase->V_rms = voltage();
#endif
#endif
#if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(IRMS_SUPPORT)
phase->I_rms = x;
#endif
x = x*MAINS_NOMINAL_VOLTAGE/10;
}
#endif
if (labs(x) < RESIDUAL_POWER_CUTOFF || (phase->status & V_OVERRANGE))
{
x = 0;
#if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(IRMS_SUPPORT)
/* Avoid displaying a residual current, which is nothing more
than integrated noise. */
//phase->I_rms = 0;
#endif
/* Turn off the LEDs, regardless of the internal state of the
reverse and imbalance assessments. */
#if defined(PHASE_REVERSED_DETECTION_SUPPORT)
meter_status &= ~STATUS_REVERSED;
clr_reverse_current_indicator();
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
meter_status &= ~STATUS_EARTHED;
clr_earthed_indicator();
#endif
}
else
{
if (operating_mode == OPERATING_MODE_NORMAL)
{
#if defined(PHASE_REVERSED_DETECTION_SUPPORT) && defined(PHASE_REVERSED_IS_TAMPERING)
if ((phase->status & PHASE_REVERSED))
{
meter_status |= STATUS_REVERSED;
set_reverse_current_indicator();
}
else
{
meter_status &= ~STATUS_REVERSED;
clr_reverse_current_indicator();
}
#endif
#if defined(POWER_BALANCE_DETECTION_SUPPORT)
if ((phase->status & PHASE_UNBALANCED))
{
meter_status |= STATUS_EARTHED;
set_earthed_indicator();
}
else
{
meter_status &= ~STATUS_EARTHED;
clr_earthed_indicator();
}
#endif
}
#if defined(LIMP_MODE_SUPPORT)
else
{
#if PHASE_REVERSED_DETECTION_SUPPORT
/* We cannot tell forward from reverse current in limp mode,
so just say it is not reversed. */
meter_status &= ~STATUS_REVERSED;
clr_reverse_current_indicator();
#endif
#if POWER_BALANCE_DETECTION_SUPPORT
/* We are definitely in the unbalanced state, but only light
the LED if we have persistence checked, and the current
is sufficient to sustain operation. */
if ((phase->status & PHASE_UNBALANCED) && phase->I_rms >= LIMP_MODE_MINIMUM_CURRENT)
{
meter_status |= STATUS_EARTHED;
set_earthed_indicator();
}
else
{
meter_status &= ~STATUS_EARTHED;
clr_earthed_indicator();
}
#endif
/* Only run the IR interface if we are sure there is enough power from the
supply to support the additional current drain. If we have not yet been
calibrated we had better keep the IR port running so we can complete the
calibration. */
#if defined(LIMP_MODE_SUPPORT) && defined(IEC1107_SUPPORT)
if (phase->I_rms >= LIMP_MODE_MINIMUM_CURRENT_FOR_IR
||
nv_parms.seg_a.s.meter_uncalibrated)
{
enable_ir_receiver();
}
else
{
disable_ir_receiver();
}
#endif
}
#endif
}
//x /= 10;
#if defined(SINGLE_PHASE) && defined(TOTAL_ENERGY_SUPPORT)
total_power = x;
#else
//if (ch == 2)
total_power += (x - phase->power);
#endif
#if defined(PHASE_REVERSED_DETECTION_SUPPORT) && defined(PHASE_REVERSED_IS_GENERATION)
#endif
phase->power = x;
#if defined(PRECALCULATED_PARAMETER_SUPPORT)
#if REACTIVE_POWER_SUPPORT
#if defined(SINGLE_PHASE)
phase->reactive_power = reactive_power();
#else
phase->reactive_power = reactive_power(phase, phase_nv);
#endif
#if defined(SINGLE_PHASE) && defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
total_reactive_power = phase->reactive_power;
#endif
#endif
#if defined(VA_POWER_SUPPORT)
#if defined(SINGLE_PHASE)
phase->VA_power = VA_power();
#else
phase->VA_power = VA_power(phase, phase_nv);
#endif
#endif
#if defined(POWER_FACTOR_SUPPORT)
/* The power factor should be calculated last */
#if defined(SINGLE_PHASE)
phase->power_factor = power_factor();
#else
phase->power_factor = power_factor(phase, phase_nv);
#endif
#endif
#endif
#if defined(PER_PHASE_ENERGY_SUPPORT)
phase->energy_counter += x*phase->sample_count_logged;
while (phase->energy_counter > ENERGY_WATT_HOUR_THRESHOLD)
{
phase->energy_counter -= ENERGY_WATT_HOUR_THRESHOLD;
phase->consumed_energy++;
}
#endif
#if defined(PRECALCULATED_PARAMETER_SUPPORT) && defined(MAINS_FREQUENCY_SUPPORT)
#if defined(SINGLE_PHASE)
phase->frequency = frequency();
#else
phase->frequency = frequency(phase);
#endif
#endif
#if defined(MAGNETIC_INTERFERENCE_SUPPORT)
#if !defined(SINGLE_PHASE)
if (ch == 0)
#endif
{
if ((meter_status & STATUS_HIGH_MAGNETIC_FIELD))
{
if (phase->sample_count_logged/magnetic_sensor_count_logged < MAGNETIC_INTERFERENCE_SAMPLE_RATIO)
{
if (--magnetic_interference_persistence <= -MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK)
{
meter_status &= ~STATUS_HIGH_MAGNETIC_FIELD;
magnetic_interference_persistence = 0;
}
}
else
{
magnetic_interference_persistence = 0;
}
}
else
{
if (phase->sample_count_logged/magnetic_sensor_count_logged >= MAGNETIC_INTERFERENCE_SAMPLE_RATIO)
{
if (++magnetic_interference_persistence >= MAGNETIC_INTERFERENCE_PERSISTENCE_CHECK)
{
meter_status |= STATUS_HIGH_MAGNETIC_FIELD;
magnetic_interference_persistence = 0;
}
}
else
{
magnetic_interference_persistence = 0;
}
}
}
#endif
}
#if defined(LIMP_MODE_SUPPORT)
/* The voltage channel DC estimate will never move very much when the
meter is operating normally. If it does move, there must be some
tampering, such as a diode between the grid and the meter. */
if (operating_mode == OPERATING_MODE_NORMAL)
{
if (phase->V_rms < LIMP_MODE_VOLTAGE_THRESHOLD*100
||
phase->V_dc_estimate[0] > UPPER_TAMPER_V_DC_ESTIMATE
||
phase->V_dc_estimate[0] < LOWER_TAMPER_V_DC_ESTIMATE)
{
switch_to_limp_mode();
}
}
else if (operating_mode == OPERATING_MODE_LIMP)
{
if (phase->V_rms >= NORMAL_MODE_VOLTAGE_THRESHOLD*100
&&
phase->V_dc_estimate[1] <= UPPER_LIMP_TAMPER_V_DC_ESTIMATE
&&
phase->V_dc_estimate[1] >= LOWER_LIMP_TAMPER_V_DC_ESTIMATE)
{
/* The LCD might need to be revived */
#if defined(__MSP430__)
LCDawaken();
#else
/* Tell the world we are ready to start */
#endif
switch_to_normal_mode();
}
}
#endif
#if !defined(SINGLE_PHASE)
phase++;
phase_nv++;
}
#endif
#if !defined(SINGLE_PHASE) && defined(NEUTRAL_MONITOR_SUPPORT) && defined(IRMS_SUPPORT)
if ((neutral.status & NEW_LOG))
{
/* The background activity has informed us that it is time to
perform a block processing operation. */
neutral.status &= ~NEW_LOG;
neutral.I_rms = neutral_current();
}
#endif
#if defined(MULTI_RATE_SUPPORT)
tariff_management();
#endif
/* Do display and other housekeeping here */
if ((meter_status & TICKER))
{
/* Two seconds have passed */
/* We have a 2 second tick */
meter_status &= ~TICKER;
#if defined(__MSP430__) && defined(BASIC_LCD_SUPPORT)
/* Update the display, cycling through the phases */
update_display();
#endif
custom_2second_handler();
#if (defined(RTC_SUPPORT) || defined(CUSTOM_RTC_SUPPORT)) && defined(CORRECTED_RTC_SUPPORT)
correct_rtc();
#endif
}
custom_keypad_handler();
custom_mainloop_handler();
}
#if !defined(__AQCOMPILER__) && !defined(__IAR_SYSTEMS_ICC__)
return 0;
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -