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

📄 emeter-rtc.c

📁 msp430F437三相电表DEMO(编译器 IAR 3.42A)
💻 C
字号:
//--------------------------------------------------------------------------
//
//  Software for MSP430 based e-meters.
//
//  You may not use the Program in non-TI devices.
//
//  File: emeter-rtc.c
//
//  Steve Underwood <steve-underwood@ti.com>
//  Texas Instruments Hong Kong Ltd.
//
//  $Id$
//
/*! \file emeter-structs.h */
//
//--------------------------------------------------------------------------
#include <stdint.h>
#include <stdlib.h>
#if !defined(__MSP430__)
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#endif
#if defined(__GNUC__)
#include <signal.h>
#endif
#if defined(__MSP430__)
#include <io.h>
#endif
#include <emeter-toolkit.h>
#include "emeter.h"
#include "emeter-structs.h"

#if !defined(NULL)
#define NULL    (void *) 0
#endif

/* We need a small seconds counter, so we can do things like a display update every 2 seconds. */
uint8_t seconds;

#if defined(__MSP430__)
    #if defined(__MSP430_HAS_BT__)  ||  defined(__MSP430_HAS_BT_RTC__)
ISR(BASICTIMER, one_second_ticker)
    #else
ISR(WDT, one_second_ticker)
    #endif
{
    #if defined(POWER_DOWN_SUPPORT)  &&  defined(POWER_UP_BY_SUPPLY_SENSING)
        #if defined(__MSP430_HAS_COMPA__)  ||  (defined(POWER_GOOD_SENSE)  &&  defined(POWER_GOOD_THRESHOLD_HIGH))
    int i;
    int j;
        #endif
    #endif

    kick_watchdog();
    #if defined(RTC_SUPPORT)
        #if defined(CORRECTED_RTC_SUPPORT)
    /* Allow for RTC correction. */
    if ((meter_status & SKIP_A_SECOND))
        meter_status &= ~SKIP_A_SECOND;
    else
        rtc_bumper();
        #else
    rtc_bumper();
        #endif
    #endif
    #if defined(CUSTOM_RTC_SUPPORT)
    if ((meter_status & SKIP_A_SECOND))
        meter_status &= ~SKIP_A_SECOND;
    else
        custom_rtc();
    #endif
    if (++seconds & 1)
        meter_status |= TICKER;  /* Kick every 2 seconds */
    #if defined(RF_LINK_SUPPORT)
    if (operating_mode == OPERATING_MODE_POWERFAIL  &&  rf_timeout >= 0)
    {
        if (++rf_timeout == 5)
        {
            rf_timeout = 0;
            /* Enable the USART */
            U0ME |= (UTXE0 | URXE0);
        #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;
        #endif
        #if defined(custom_rf_sniffer)
            if (rf_timeout = custom_rf_sniffer())
            {
                /* We need to set up timer A to call back when the message exchange time
                   comes round */
                /* Use timer A to time the period until the real messages are exchanged. */
                TAR = 0;
                TACCR0 = 55*rf_timeout;
                TACCTL0 = 0;
                TACTL = TACLR | MC_1 | ID_2 | TASSEL_1;
                /* Stop the 5 second scans until the timed response is complete */
                rf_timeout = -1;
            }
        #endif
            /* Disable the USART */
            U0ME &= ~(UTXE0 | URXE0);
        #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
        }
    }
    #endif

    #if defined(POWER_DOWN_SUPPORT)
        #if defined(POWER_UP_BY_VOLTAGE_PULSES)
    /* One method to detect power being restored is to look
       for pulses on an input pin, caused by the voltage signal. */
    if (meter_status & POWER_DOWN)
    {
        pd_pin_debounce <<= 1;
        if (power_up_voltage_pulse())
            pd_pin_debounce |= 1;
            #if defined(__MSP430__)
        if ((pd_pin_debounce & 0xF) == 0xF)
            _BIC_SR_IRQ(LPM3_bits);
            #endif
    }
    else
    {
            #if defined(__MSP430__)
        _BIC_SR_IRQ(LPM0_bits);
            #endif
    }
        #endif
        #if defined(POWER_UP_BY_SUPPLY_SENSING)
    /* If the meter has a limp mode, where it can be powered from the live
       or neutral only, getting wakeup voltage pulses is not so easy. Current
       pulses are not much easier. Here we look for the pre-regulator power
       supply voltage being of an adequate level. We use comparator A as the
       sensor, and only switch it on for the minimum possible time. */
            #if defined(__MSP430_HAS_COMPA__)
                #if defined(__MSP430__)
    if (operating_mode == OPERATING_MODE_POWERFAIL)
    {
        /* Select the lower comparator threshold for going to the LCD on, but other
           functions off, condition. Current consumption should be low enough to not
           be too significant for reasonable periods. */
        CACTL1 = CAREF_1 | CAON;
        /* We are required to start quickly, so we cannot do much
           debouncing here */
        power_down_debounce = POWER_RESTORE_DEBOUNCE;
        i = CACTL2 & CAOUT;
        while (--power_down_debounce >= 0)
        {
            j = CACTL2 & CAOUT;
            if (i != j)
            {
                i = j;
                power_down_debounce = POWER_RESTORE_DEBOUNCE;
            }
        }
        if (!j)
        {
            /* This appears to be a real power-up. We have reached 4.2V. This
               should be OK for running the internal LCD controller, as it only
               takes a few uA. For a small LCD, as little as 2uA. */
            operating_mode = OPERATING_MODE_LCD_ONLY;
                    #if defined(BASIC_LCD_SUPPORT)
            display_power_4v2_message();
                    #endif
            custom_lcd_wakeup_handler();
        }
        power_down_debounce = 0;
        CACTL1 &= ~(CAON);
    }
    else if (operating_mode == OPERATING_MODE_LCD_ONLY)
    {
        /* Select the higher comparator threshold for power restored. That should
           mean that if the MCU is woken up, it can definitely run for a while at
           full speed, just from the charge on the main capacitor. */
        CACTL1 = CAREF_2 | CAON;
        /* We are required to start quickly, so we cannot do much
           debouncing here. */
        power_down_debounce = POWER_RESTORE_DEBOUNCE;
        i = CACTL2 & CAOUT;
        while (--power_down_debounce >= 0)
        {
            j = CACTL2 & CAOUT;
            if (i != j)
            {
                i = j;
                power_down_debounce = POWER_RESTORE_DEBOUNCE;
            }
        }
        if (!j)
        {
            /* This appears to be a real power-up. */
                    #if defined(BASIC_LCD_SUPPORT)
            display_power_normal_message();
                    #endif
            _BIC_SR_IRQ(LPM3_bits);
        }
        else
        {
            /* The power hasn't reached the high water mark. See if it has
               dropped back below the low water mark. */
            CACTL1 = CAREF_1 | CAON;
            /* We are required to start quickly, so we cannot do much
               debouncing here. */
            power_down_debounce = POWER_RESTORE_DEBOUNCE;
            i = CACTL2 & CAOUT;
            while (--power_down_debounce >= 0)
            {
                j = CACTL2 & CAOUT;
                if (i != j)
                {
                    i = j;
                    power_down_debounce = POWER_RESTORE_DEBOUNCE;
                }
            }
            if (j)
            {
                /* This appears to be a real power drop. */
                operating_mode = OPERATING_MODE_POWERFAIL;
                custom_lcd_sleep_handler();
            }
        }
        power_down_debounce = 0;
        CACTL1 &= ~(CAON);
    }
                #endif
            #else
    /* Use an I/O pin to sense the power falling */
                #if defined(__MSP430__)
    if (operating_mode == OPERATING_MODE_POWERFAIL)
    {
        /* Select the higher comparator threshold for starting up. This ensures we should have
           enough energy in the capacitors to keep the meter running until it works out what to
           do next. */
        POWER_GOOD_THRESHOLD_HIGH;
        /* We are required to start quickly, so we cannot do much
           debouncing here */
        power_down_debounce = POWER_RESTORE_DEBOUNCE;
        i = POWER_GOOD_SENSE;
        while (--power_down_debounce >= 0)
        {
            j = POWER_GOOD_SENSE;
            if (i != j)
            {
                i = j;
                power_down_debounce = POWER_RESTORE_DEBOUNCE;
            }
        }
        if (j)
        {
            /* This appears to be a real power-up. */
                    #if defined(BASIC_LCD_SUPPORT)
            display_power_normal_message();
                    #endif
            custom_lcd_wakeup_handler();
            _BIC_SR_IRQ(LPM3_bits);
        }
        power_down_debounce = 0;
    }
                #endif
            #endif
        #endif
        #if defined(LIMP_MODE_SUPPORT)
    if (operating_mode == OPERATING_MODE_LIMP)
    {
        /* We need to kick things, to give the foreground activities a chance
           to do their work. */
        _BIC_SR_IRQ(LPM0_bits);
    }
        #endif
    #endif
    kick_watchdog();
}
#endif

⌨️ 快捷键说明

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