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

📄 emeter-setup.c

📁 msp430F437三相电表DEMO(编译器 IAR 3.42A)
💻 C
📖 第 1 页 / 共 3 页
字号:
    ADC12CTL0 |= ENC;

        #if defined(__MSP430_HAS_TA3__)
    /* Switch to the normal sampling rate. */
    TAR = 0;
    TACCR0 = SAMPLE_PERIOD - 1;
    TACCR1 = SAMPLE_PERIOD - 3;
    TACCR2 = SAMPLE_PERIOD - 4;
    TACCTL0 = CCIE;
    TACCTL1 = OUTMOD_3;
    TACTL = TACLR | MC_1 | TASSEL_1;
    /* Disable the interrupt routine which re-enables the ADC */
    TACCTL2 = 0;
        #endif
    #endif

    #if defined(__MSP430_HAS_SD16_3__)
        #if defined(__MSP430_HAS_TA3__)
    /* Disable the TIMER_A0 interrupt */
    TACTL = 0;
    TACCTL0 = 0;
        #endif
    _DINT();
    init_analog_front_end_normal();
    #endif

    samples_per_second = SAMPLES_PER_10_SECONDS/10;

    _EINT();

    #if defined(PWM_DITHERING_SUPPORT)
    /* Enable dithering, by enabling Timer B */
    TBR = 0;
    TBCTL = TBCLR | MC_1 | TBSSEL_2;
    #endif

    #if defined(DAC12_DITHERING_SUPPORT)
    DAC12_0CTL &= ~ENC;
    DAC12_1CTL &= ~ENC;
    DAC12_0CTL =
    DAC12_1CTL = DAC12CALON | DAC12IR | DAC12AMP_7 | DAC12LSEL_2;
    DAC12_0CTL |= ENC;
    DAC12_1CTL |= ENC; 
    DAC12_0DAT = 0x800;
    DAC12_1DAT = 0;
    #endif
    
    #if defined(IEC1107_SUPPORT)
    enable_ir_receiver();
    #endif

    operating_mode = OPERATING_MODE_NORMAL;
}

    #if defined(LIMP_MODE_SUPPORT)
void switch_to_limp_mode(void)
{
    /* Switch to minimum consumption, current measurement only mode */

    meter_status &= ~(STATUS_REVERSED | STATUS_PHASE_VOLTAGE_OK);
    clr_normal_indicator();
    clr_reverse_current_indicator();

        #if defined(__MSP430_HAS_ADC12__)
    /* Change the ADC reference to Vcc */
    _DINT();

    /* Must disable conversion while reprogramming the ADC */
    ADC12CTL0 &= ~ENC;

    /* Turn the Vref off and ADC on */
    ADC12CTL0 = MSC | REF2_5V | ADC12ON | SHT0_2 | SHT1_2;

            #if defined(SINGLE_PHASE)
    ADC12MCTL0 = SREF_0 | AGND_INPUT;
    ADC12MCTL1 = SREF_0 | NEUTRAL_CURRENT_INPUT;
    ADC12MCTL2 = SREF_0 | AGND_INPUT;
    ADC12MCTL3 = SREF_0 | LIVE_CURRENT_INPUT;
    ADC12MCTL4 = SREF_0 | AGND_INPUT;
                #if defined(BATTERY_MONITOR_SUPPORT)
    ADC12MCTL5 = SREF_0 | VOLTAGE_INPUT;
    ADC12MCTL6 = EOS | SREF_0 | BATTERY_INPUT;
                #else
    ADC12MCTL5 = EOS | SREF_0 | VOLTAGE_INPUT;
                #endif
    /* Skip the temperature, or the reference switches on! */
            #else
    ADC12MCTL0 = SREF_0 | LIVE_CURRENT_INPUT_1;
    ADC12MCTL1 = SREF_0 | AGND_INPUT;
    ADC12MCTL2 = SREF_0 | VOLTAGE_INPUT_1;
    ADC12MCTL3 = SREF_0 | LIVE_CURRENT_INPUT_2;
    ADC12MCTL4 = SREF_0 | AGND_INPUT;
    ADC12MCTL5 = SREF_0 | VOLTAGE_INPUT_2;
    ADC12MCTL6 = SREF_0 | LIVE_CURRENT_INPUT_3;
    ADC12MCTL7 = SREF_0 | AGND_INPUT;
                #if defined(NEUTRAL_CURRENT_INPUT)
    ADC12MCTL8 = SREF_0 | VOLTAGE_INPUT_3;
    ADC12MCTL9 = EOS | SREF_0 | NEUTRAL_CURRENT_INPUT;
                #else
    ADC12MCTL8 = EOS | SREF_0 | VOLTAGE_INPUT_3;
                #endif
    /* Skip the temperature, or the reference switches on! */ 
            #endif
    ADC12CTL0 |= ENC;

            #if defined(__MSP430_HAS_TA3__)
    /* Switch to a lower sampling rate. */
    TAR = 0;
    TACCR0 = (SAMPLE_PERIOD*LIMP_SAMPLING_RATIO) - 1;
    TACCR1 = (SAMPLE_PERIOD*LIMP_SAMPLING_RATIO) - 3;
    TACCR2 = (SAMPLE_PERIOD*LIMP_SAMPLING_RATIO) - 4;
    TACCTL0 = CCIE;
    TACCTL1 = OUTMOD_3;
    TACTL = TACLR | MC_1 | TASSEL_1;
    /* Enable the interrupt routine which re-enables the ADC */
    TACCTL2 = CCIE;
            #endif
        #endif

        #if defined(__MSP430_HAS_SD16_3__)
            #if defined(__MSP430_HAS_TA3__)
    /* Enable the TIMER_A0 interrupt */
    TACTL = TACLR | MC_1 | TASSEL_1;
    TACCTL0 = CCIE;
            #endif
    _DINT();
    init_analog_front_end_limp();
        #endif

    samples_per_second = LIMP_SAMPLES_PER_10_SECONDS/10;

        #if defined(IEC1107_SUPPORT)
    disable_ir_receiver();
        #endif

    _EINT();

        #if defined(PWM_DITHERING_SUPPORT)
    /* Disable dithering, by disabling Timer B */
    TBCTL = TBCLR | TBSSEL_2;
        #endif
    operating_mode = OPERATING_MODE_LIMP;
}
    #endif

    #if defined(POWER_DOWN_SUPPORT)
void switch_to_powerfail_mode(void)
{
    operating_mode = OPERATING_MODE_POWERFAIL;

    /* Note that a power down occured */
    meter_status |= POWER_DOWN;

    /* Turn off all the LEDs. */
    meter_status &= ~(STATUS_REVERSED | STATUS_EARTHED | STATUS_PHASE_VOLTAGE_OK);
    clr_normal_indicator();
    clr_reverse_current_indicator();
    clr_earthed_indicator();
    clr_total_energy_pulse_indicator();
    clr_total_reactive_energy_pulse_indicator();
    
    /* Make the EEPROM signals inputs, and rely on pullups. */
    disable_eeprom_port();

    /* Shut down the LCD */
    custom_lcd_sleep_handler();

        #if defined(__MSP430_HAS_TA3__)  &&  (defined(__MSP430_HAS_ADC12__)  ||  defined(__MSP430_HAS_SD16_3__))
    /* Disable the TIMER_A0 interrupt */
    TACTL = 0;
    TACCTL0 = 0;
    /* Disable the interrupt routine which re-enables the ADC */
    TACCTL2 = 0;
        #endif

        #if defined(__MSP430_HAS_ADC12__)
    /* Now the interrupts have stopped it should be safe to power
       down the ADC. */
    ADC12CTL0 &= ~ENC;
    ADC12CTL0 &= ~(REFON | REF2_5V | ADC12ON);
        #endif
        #if defined(__MSP430_HAS_SD16_3__)
    disable_analog_front_end();
        #endif
        #if defined(PWM_DITHERING_SUPPORT)
    /* Disable dithering, by disabling Timer B */
    TBCTL = TBCLR | TBSSEL_2;
        #endif
        #if defined(IEC1107_SUPPORT)  ||  defined(SERIAL_CALIBRATION_SUPPORT)  ||  defined(SERIAL_CALIBRATION_REF_SUPPORT)
    /* Disable the serial port. */
    U0ME &= ~(UTXE0 | URXE0);
            #if defined(IEC1107_SUPPORT)
    disable_ir_receiver();
            #endif
        #endif

        #if defined(BATTERY_MONITOR_SUPPORT)
    /* Battery sensing control pin */
    P3DIR &= ~(BIT1);
    P3OUT |= (BIT1);
        #endif

        #if defined(__MSP430_HAS_FLLPLUS__)  ||  defined(__MSP430_HAS_FLLPLUS_SMALL__)
    /* Slow the clock to 1MHz as quickly as possible. The FLL will not be active
       in LPM3, so switch it off now, and force the FLL's RC oscillator to
       about 1MHz. The exact frequency is not critical. */
    _BIS_SR(SCG0);                  /* switch off FLL locking */
    SCFI0 = FLLD_1;
    SCFQCTL = (32 - 1) | SCFQ_M;
    SCFI0 = 0x0;
    SCFI1 = 0x37;
        #endif
        #if defined(__MSP430_HAS_SVS__)
    /* At 1MHz it is safe to turn off the SVS, and rely on the brownout
       detector. Now the meter can survive on a very weak battery. */
    SVSCTL = 0;
        #endif
    custom_power_fail_handler();

    /* ******************** LOW POWER STATE ************************** */
    /* Go to LPM3 mode and exit only when power comes back on. The timer
       interrupt that ticks every second should be checking for power
       restored while we sit here. When it sees the unregulated supply
       at a healthy voltage, it will wake us up. */
    _BIS_SR(LPM3_bits);

    /* Waking up from power down mode */
        #if defined(__MSP430_HAS_SVS__)
    /* Before we go to high speed we need to make sure the supply voltage is 
       adequate. If there is an SVS we can use that. There should be no wait
       at this point, since we should only have been woken up if the supply
       is healthy. However, it seems better to be cautious. */
    SVSCTL |= (SVSON | 0x60);
    /* Wait for adequate voltage to run at full speed */
    while ((SVSCTL & SVSOP))
        /* dummy loop */;
    /* The voltage should now be OK to run the CPU at full speed. Now it should
       be OK to use the SVS as a reset source. */
    SVSCTL |= PORON;
        #endif

        #if defined(__MSP430_HAS_FLLPLUS__)  ||  defined(__MSP430_HAS_FLLPLUS_SMALL__)
    /* Speed up the clock to 8.388608MHz */
    SCFI0 = FN_3 | FLLD_4;
    SCFQCTL = 64 - 1;
    /* There seems no good reason to wait until the FLL has settled at this point. */
        #endif

    /* Take control of the EEPROM signals again. */
    enable_eeprom_port();

    /* Enable the serial port */
        #if defined(IEC1107_SUPPORT)  ||  defined(SERIAL_CALIBRATION_SUPPORT)  ||  defined(SERIAL_CALIBRATION_REF_SUPPORT)
            #if defined(SERIAL_CALIBRATION_REF_SUPPORT)
    U0ME |= (UTXE0 | URXE0);
            #elif defined(SERIAL_CALIBRATION_SUPPORT)
    U0ME |= URXE0;
            #else
    U0ME |= UTXE0;
            #endif
        #endif

        #if defined(__MSP430_HAS_TA3__)  &&  (defined(__MSP430_HAS_ADC12__)  || defined(__MSP430_HAS_SD16_3__))
    /* Enable the TIMER_A0 interrupt */
    TACTL = TACLR | MC_1 | TASSEL_1;
    TACCTL0 = CCIE;
        #endif

    kick_watchdog();

        #if defined(LOSE_FRACTIONAL_PULSE_AT_POWER_ON)
            #if defined(PER_PHASE_ENERGY_SUPPORT)
    phase->power_counter = 0;
            #endif
            #if defined(TOTAL_ENERGY_SUPPORT)
    total_power_counter = 0;
                #if TOTAL_ENERGY_PULSES_PER_KW_HOUR < 1000
    extra_total_power_counter = 0;
                #endif
            #endif
            #if defined(TOTAL_REACTIVE_ENERGY_SUPPORT)
    total_reactive_power_counter = 0;
                #if TOTAL_ENERGY_PULSES_PER_KW_HOUR < 1000
    extra_total_reactive_power_counter = 0;
                #endif
            #endif
        #endif

        #if defined(BATTERY_MONITOR_SUPPORT)
    if (battery_countdown)
    {
        battery_countdown = 1000;
        /* Battery sensing control pin */
        P3DIR |= (BIT1);
        P3OUT &= ~(BIT1);
    }
        #endif
    /* Come out of power down in limp mode, as we don't know
       if there is sufficent power available to driver the meter
       at full speed. We will soon switch to normal mode if a
       voltage signal is available. */
    /* Limp mode will fire up the ADC again. */
        #if defined(LIMP_MODE_SUPPORT)
    switch_to_limp_mode();
        #else
    switch_to_normal_mode();
        #endif
    custom_power_restore_handler();
}
    #endif
#else
void switch_to_normal_mode(void)
{
}

    #if defined(LIMP_MODE_SUPPORT)
void switch_to_limp_mode(void)
{
}
    #endif

    #if defined(POWER_DOWN_SUPPORT)
void switch_to_powerfail_mode(void)
{
}
    #endif
#endif

#if defined(__MSP430_HAS_TA3__)
int32_t assess_rtc_speed(void)
{
    int32_t period;
    uint16_t this_capture;
    uint16_t last_capture;
    uint16_t step;
    int32_t counter;
    int limit;

    /* The fast clock should be an exact multiple of the crystal clock, once the FLL has
        settled. If we capture many cycles of an accurate external 32768Hz clock, using
        timer A (or B), we can measure the speed difference between the MSP430's crystal
        and the external clock in a reasonable time. */
    /* The SM clock should be running at 244*32768Hz at this time. */
    _DINT();
    /* Change timer A to running fast, and sampling the external 32768Hz reference. */
    P2SEL |= BIT0;
    TACCR0 = 0xFFFF;
    TACCTL0 = CAP | CCIS_0 | CM_1;
    TACCTL2 = CAP | CCIS_0 | CM_1 | SCS;
    TACTL = TACLR | MC_2 | TASSEL_2;    /* start TIMER_A up mode, SMCLK as input clock */
    period = 0;
    last_capture = TACCR2;
    limit = -1;
    TACCTL2 &= ~CCIFG;
    for (counter = 0;  counter < 32768*5 + 1;  counter++)
    {
        limit = 1000;
        while (!(TACCTL2 & CCIFG))
        {
            if (--limit <= 0)
                break;
        }
        if (limit <= 0)
            break;
        TACCTL2 &= ~CCIFG;
        this_capture = TACCR2;
        step = this_capture - last_capture;
        last_capture = this_capture;
        /* Skip the first sample, as it will be meaningless */
        if (counter)
        {
    #if 0
            if (step < (244 - 5)  ||  step > (244 + 5))
            {
                limit = -2;
                break;
            }
    #endif
            period += step;
        }
        kick_watchdog();
    }
    if (limit <= 0)
        period = limit;
    #if defined(__MSP430_HAS_ADC12__)
    /* Change timer A back to controlling the ADC sampling interval, and the ADC on/off timing. */
    /* CCR0 determines the sample period */
    TACCR0 = SAMPLE_PERIOD - 1;
    TACCR1 = SAMPLE_PERIOD - 3;
    TACCR2 = SAMPLE_PERIOD - 4;
    TACCTL1 = OUTMOD_3;
    #endif
    TACTL = TACLR | MC_1 | TASSEL_1;
    TACCTL0 = CCIE;
    P2SEL &= ~BIT0;
    _EINT();
    return  period;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -