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

📄 emeter-foreground.c

📁 msp430F437三相电表DEMO(编译器 IAR 3.42A)
💻 C
📖 第 1 页 / 共 4 页
字号:
    {
        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 + -