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

📄 main.c

📁 单相复费率MSP430硬件时钟参考代码,MSP413设计方案
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
        TotleTimeOfMiuns++;
        if(TotleTimeOfMiuns>=60)
        {
            SaveTimeOfMiuns();
        }
    }
    // 如果当前为正向,则强制保存反向累计时间
    else
    {
        SaveTimeOfMiuns();
    }
    // 刷新费率属性(关中断时间应尽量短)
    ptcnt=(unsigned char)((PowerAttribute&ATTRIBUTE_OF_PLUS_MINUS)|temp);
    _DINT();
    PowerAttribute=(unsigned char)ptcnt;
    _EINT();
}

//掉电及低压检测
void BreakOrLowPowerTest(unsigned char tstPin)
{
    if(P1IN&tstPin)
    {
        BreakOrLowPowerFlag&=~(tstPin);
    }
    else//检测到掉电或低压
    {
        if(!(BreakOrLowPowerFlag&tstPin))
        {
            //保存掉电或低压标志
            BreakOrLowPowerFlag|=tstPin;

            // 如果掉电,则进行数据保存
            if(BreakOrLowPowerFlag&BRK_PWR_TST)
            {
                // 保存RAM中的脉冲数据到Flash
                PowerDataStore();
                // 保存反向累计时间
                SaveTimeOfMiuns();
            }
            
            //保存最后一次掉电或低压时间
            _save_time_to_e2prom_(ADDRESS_OF_LAST_BREAK_POWER_TIME+(tstPin>>7)*6);
        }
        if(BreakOrLowPowerFlag&BRK_PWR_TST)
        {
            // 强制把电流方向转为正向
            _DINT();
            PowerAttribute=(unsigned char)(PowerAttribute&0x03);
            _EINT();
        }
    }
}

void ProgramEnableTest(void)
{
    if(PROG_EN_IN&PROG_EN)
        LcdDisplayChoose&=~0x1000;
    else
        LcdDisplayChoose|=0x1000;
}

void OnUserkey(void)
{
    if(P2IN&USERKEY0)
    {
        if(LcdDispPageUpOrDown>=0x50)
        {
            LcdDispPageUpOrDown=USERKEY_SELECT;
            LcdSelectPage();
        }
    }
    else
    {
        LcdDispPageUpOrDown=USERKEY_VIEW;
        LcdViewPage();
    }
}

// 电表基本初始化
void DeviceBasicInit(void)
{
#ifdef _HARDWARE_RTC
    unsigned char on_off;
#endif

    _DINT();
    //WDTCTL=WDTPW+WDTHOLD;
    WDTCTL=WDTPW+WDTSSEL+WDTCNTCL;

    // Basic Timer初始化相关
    IE2|=BTIE;               // Enable BT interrupt
    FLL_CTL0|=XCAP18PF;      // Configure load caps
    FLL_CTL1|=FLL_DIV_8;
    BTCTL=BT_ADLY_125+BT_fLCD_DIV128;

    // Init Port 1
    // Including:RS_D(1.0),RS_R(1.1),IR_IN(1.2),BELL(1.3),PROG_EN(1.4),RTC_OUT(P1.5),PWR_F0(P1.6),PWR_F1(P1.7)
    P1DIR=(RS485_TX+BELL+RTC_FREQ);
    P1SEL|=BIT5;
    P1OUT|=(RS485_TX+BELL);
    P1IES|=(RS485_RX+IR_RX);

    // Init Port 2
    // Including:IR_OUT(2.0),POWER_PULSE(2.1),LCD_LIGHT(2.5),USERKEY0(2.2),STA_UP(2.3)
    P2DIR=(IR_TX+LCD_LIGHT);
    P2OUT|=(IR_TX+LCD_LIGHT);
    P2IES=0;
    P2IE|=(USERKEY0+POWER_PULSE);
    
    // Init Port 6
    // Including:WDT(P6.0),P6_1(6.1),P6_2(6.2),E2PROM_WP(6.3),RS485_EN(6.4),POWER_DIRECTION(6.5),I2C_SDA(6.6),I2C_SCL(6.7)
    P6DIR=(P6_1+P6_2+RS485_EN+E2PROM_WP+I2C_SCL+I2C_SDA+WDT);
    P6OUT|=(P6_1+P6_2+I2C_SCL+I2C_SDA+E2PROM_WP+RS485_EN);

    // 延时几秒钟,等待RTC状态稳定
    BellOn();
    
#ifdef _HARDWARE_RTC
    RenewSystemTime();
#endif
    
    DefaultInit();

    ReadPPC();

    // 电表事件初始化
    SetSystemEvent(EVENT_01_SECOND|EVENT_01_MINUTE);

    // 读取显示配置信息
    ResetLcdDisplay();

#ifdef _SUPPORT_RELAY
    // 继电器状态初始化
    E2promRead(ADDRESS_OF_RELAY_STATE,&on_off,1);
    if((on_off!=RELAY_OPEN)&&(on_off!=RELAY_CLOSE))
    {
        on_off=RELAY_CLOSE;
    }
    RelayCtrl(on_off);
#endif

#ifdef _HARDWARE_RTC
    // RTC初始化
    on_off=0x23;// 24小时进制,秒输出
    RealtimeOper(0xE0,&on_off,1);
    // Init Pulse Mode,output 1 Hz
    on_off=0x20;//掉电电压:2.1V;
    RealtimeOper(0xF0,&on_off,1);
#endif
    // LCD初始化
    LCDCTL=0x5F;
    BTCTL|=BTFRFQ1;
    P5SEL=0xFC;
}

void main(void)
{
    DeviceBasicInit();
    _bcd_short_add1_and_write_e2prom_(ADDRESS_OF_CPU_RESET_CNT);
    // 强制存储,为了避免复位而引起的校验错误
    PowerDataStore();

    for(;;)
    {
        ClrWDT();
        if(SystemIndication&EVENT_SERIAL_PORT)
        {
            if(!Rx_FrameInfo())
            {
                LCDMEM[LCD_ADDRESS_OF_TONGXIN]|=LCD_OF_TONXIN;
                Parse_RxFrame();
            }
            UartReInit();
            ClearSystemEvent(EVENT_SERIAL_PORT);
        }

        ClrWDT();
        if(SystemIndication&EVENT_KEY_DOWN)
        {
            Delay(6000);    // 此延时为了滤波(30ms)
            if(!(LcdDispPageUpOrDown&USERKEY_JUST))
            {
                if(P2IN&USERKEY0)
                {
                    LcdLightOn(15);
                    TimerCounter[1]=15;
                    TimerProc[1]=ResetLcdDisplay;
                    LcdDispPageUpOrDown|=USERKEY_JUST;
                }
            }
            Delay(5000);
            ClearSystemEvent(EVENT_KEY_DOWN);
        }

        ClrWDT();
        if(SystemIndication&EVENT_KEY_DETECT)
        {
            OnUserkey();
            ClearSystemEvent(EVENT_KEY_DETECT);
        }

        ClrWDT();
        if(SystemIndication&EVENT_POWERMINUS)
        {
            // 记录反向起始时间
            _save_time_to_e2prom_(ADDRESS_OF_START_TIME_MINUS);
            ClearSystemEvent(EVENT_POWERMINUS);
        }

        ClrWDT();
        if(SystemIndication&EVENT_01_SECOND)
        {
            PowerPulseCalculate();
#ifdef _HARDWARE_RTC
            GetSystemTime();
#else
            SecondUp();
#endif
            ProgramEnableTest();
            RedundancyTimerProc();
            UartReInit();

            ClrWDT();
            if(SystemIndication&EVENT_01_MINUTE)
            {
                BreakOrLowPowerTest(BRK_PWR_TST);
#if _SUPPORT_LOW_POWER_DETECT
                BreakOrLowPowerTest(LOW_PWR_TST);
#endif
                ExesAttributeDetect();
                MonthSpanDetect();
                ClearSystemEvent(EVENT_01_MINUTE);
            }

            DisplayRefresh();
            ClearSystemEvent(EVENT_01_SECOND);
        }

        ClrWDT();
        // 剔除无用位
        ClearSystemEvent(EVENT_REVERSED);
        if(!SystemIndication) _BIS_SR(LPM3_bits);
    }
}

#pragma vector=BASICTIMER_VECTOR
__interrupt void BasicTimer(void)
{
    SystemTimeTick++;
    if(SystemTimeTick>=8)
    {
        SystemTimeTick=0;
#ifndef _HARDWARE_RTC
        g_time[SPACE_OF_SECOND]++;
#endif
        SystemIndication|=EVENT_01_SECOND;
        _BIC_SR_IRQ(LPM3_bits);
    }
    if(LcdDispPageUpOrDown&USERKEY_JUST)
    {
        LcdDispPageUpOrDown+=0x10;
        SystemIndication|=EVENT_KEY_DETECT;
        _BIC_SR_IRQ(LPM3_bits);
    }
    if(UartRxByteTime++==2) 
    {
        UartBitCount=0;
        UartState=UART_RXD_OVERTIME_ERR;
    }
}

#pragma vector=PORT2_VECTOR
__interrupt void Port2(void)
{
    if(POWER_PULSE_IFG&POWER_PULSE)
    {
        _NOP();
        _NOP();
	 if(POWER_PULSE_IN&POWER_PULSE)
	 {
            PowerPulseCounter++;
            // 电流方向确认()
            if(POWER_DIRECTION_IN&POWER_DIRECTION)
            {
                // 如果之前电流方向为正向
                if(!(PowerAttribute&ATTRIBUTE_OF_PLUS_MINUS))
                    SystemIndication|=EVENT_POWERMINUS;
                // 刷新为反向
                PowerAttribute=(unsigned char)((PowerAttribute|ATTRIBUTE_OF_PLUS_MINUS)&0x07);
            }
            else
            {
                // 刷新为正向
                PowerAttribute=(unsigned char)(PowerAttribute&0x03);
            }
	 }
        // 清中断标志
        P2IFG=0;
    }
    else
    {
        // 置按键事件
        SystemIndication|=EVENT_KEY_DOWN;
        // 除脉冲中断,其他中断标志全清
        P2IFG&=POWER_PULSE;
        _BIC_SR_IRQ(LPM3_bits);
    }
}

void DefaultInit(void)
{
    unsigned char data[8];
    
    E2promRead(ADDRESS_OF_DEVICE_STATUS_MAIN,data,1);
    if(data[0]!=DEVICE_OK)
    {
        // 清零脉冲计数
        ClearPowerPulseDataInRam();
        //清反向累计时间
        //TotleTimeOfMiuns=0;

        // 写软件版本号(2004-11-11)
        data[4] = 0x04; data[3] = 0x11; data[2] = 0x11;
        // 写硬件版本号(2004-09-09)
        data[7] = 0x04; data[6] = 0x09; data[5] = 0x09;
        // 初始化状态及版本号
        data[0]=DEVICE_OK;
        E2promWrite(ADDRESS_OF_DEVICE_STATUS_MAIN,data,8);
    }
}

⌨️ 快捷键说明

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