基于MSP430单片机的智能电表
基于MSP430单片机的智能电表.zip
(96.77 KB)
#include "msp430x41x.h"
#include "string.h"
#include "Def.h"
#include "EepromAddr.h"
#include "CommID.h"
#include "Main.h"
#include "Tariff.c"
#include "Temperature.c"
#include "Lcd.c"
#include "I2C.c"
#include "Comm.C"
#include "Timer.C"
void port_ini( void )
{
P1OUT = P1T485;
P1DIR = TX | P1T485;
P1IES &=~P1IMPIN;
P1IES |= P1DISPLAY;
P1IE |= P1IMPIN | P1DISPLAY;
P1IFG = 0;
P1SEL = 0;
P2DIR = 0;
P2IES |= (P2UNCOVER | P2POWERCHECK | 0x20);
P2IE |= (P2UNCOVER | P2POWERCHECK | 0x20);
P6DIR = (P6E485 | P6LEDRATE2 | P6LEDRATE3 | P6LEDRATE4);
P6OUT = (P6E485 | P6LEDRATE2 | P6LEDRATE3 | P6LEDRATE4);
}
void start_wdt( void )
{
WDTCTL = WDT_ARST_1000; // Start WDT
IFG1 &=WDTIFG;
IE1 |=WDTIE;
}
/*
void search_fee( void )
{
bTmp=tar_que( &NowClk1, &TarList );
if( bTmp>3 ) bTmp=1;
}
*/
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
FLL_CTL0 |= XCAP14PF;
// 让 AD7416 进入掉电模式。
vars.tmpPtr[0] = 0x01;
w_I2C_bytes(vars.tmpPtr,0x9E,0x01,1);
new_e2prom_ini();
clk_ini(); // --
re_clk_ini();
lcd_ini();
port_ini();
vars.MetStatus=0;
vars.MetStatus=BATTEST(vars.MetStatus);
TimeA_ini();
vars.cFlag=0;
vars.rt_Bit = 0;
vars.lByte = 0;
rx_cap_reseat();
start_wdt();
_EINT(); // Enable interrupts
while(1)
{
if ( vars.Int_ID&ComInt ) // communication interrupt
{
ProcComm();
vars.Int_ID &=~ComInt;
}
if ( vars.Int_ID&BtInt ) // basic timer interrupt
{
ProcSec();
vars.Int_ID &=~BtInt;
}
if((vars.Int_ID&E2Int)&&!(vars.E2PROM_SAVE&E2BUSY))
{
vars.E2PROM_SAVE |= E2BUSY;
E2_Save();
vars.E2PROM_SAVE &=~E2BUSY;
vars.Int_ID &=~E2Int;
}
_NOP();
LPM3;
_NOP();
}
}
interrupt[BASICTIMER_VECTOR] void Basic_timer (void)
{
IFG1 &=WDTIFG;
WDTCTL = WDT_ARST_1000; // Clear WDT
if ( vars.bt_int>=63 )
{
vars.bt_int=0;
}
else vars.bt_int++;
// 以下程序为内部软件时钟温度补偿:
if(vars.Flags & Temp_F)
{
vars.Flags &=~ Temp_F;
if ( vars.bt_int>=63 ) vars.bt_int=0;
else vars.bt_int++;
}
//
if ( vars.bt_int==0 || vars.bt_int==32 ) vars.Int_ID |=BtInt;
if(vars.Int_ID!=0) LPM3_EXIT; // wake CPU
}
interrupt[TIMERA0_VECTOR] void TA0_timer (void)
{
if((vars.timer0status&comovertime)==comovertime)
{
// vars.rt_Bit = 0;
// vars.lByte = 0;
rx_cap_reseat();
vars.timer0status &=~comovertime;
}
if(vars.timer0status==0) CCTL0 &=~CCIE;
}
interrupt[TIMERA1_VECTOR] void TA1_timer (void)
{
if ((TAIV|0x02)==0x02)
{
if( (vars.ComFlags & rtflag)==rtflag )
{
ComFlagRAM |= sym_Comm;
tx_prt(vars.rtByte[vars.lByte]);
}
else
{
switch(vars.rt_Bit) // 32.768k XT
{
case 0:
CCTL0 &=~CCIE;
CCTL1 &= ~(CAP+CM1);
CCR1 =TAR+14;break;
case 3:CCR1=CCR1+28;break;
case 6:CCR1=CCR1+28;break;
case 9:CCR1=CCR1+28;break;
default:CCR1=CCR1+27;break;
}
vars.cFlag=0; // 清超时计时.
if (vars.rt_Bit==1)
{
if ((P1IN&RX)==RX) goto looperr; // error return(9)
else
{
vars.hByte = 0;
vars.csByte = 0;
goto loop0;
}
}
if ((vars.rt_Bit>1)&&(vars.rt_Bit<=10)) // 7 or 8 bit: now 8 bit
{
if ((P1IN&RX)==RX)
{
vars.hByte |= 0x200; // 7 or 8 bit
vars.csByte++;
}
vars.hByte >>=1;
goto loop0;
}
if (vars.rt_Bit>10) // 7 or 8 bit
{
// COMIFGS[0] |=RB_L; // 字节结束,超时计时开始中。
vars.timer0status |= comovertime;
CCR0 =TAR+0x8000;
CCTL0 |= CCIE;
vars.hByte &=0xFF; // 7 or 8 bit
if ((vars.csByte&1)==0) goto loop1;
else goto looperr;
}
loop0:
vars.rt_Bit++;
goto loopend;
loop1:
if((vars.lByte==0)&&(vars.hByte!=0x68)) goto looperr;
ComFlagRAM |= sym_Comm;
vars.rt_Bit = 0;
vars.rtByte[vars.lByte]=vars.hByte;
if ( vars.lByte == vars.rtByte[9]+11 )
{
vars.lByte=0;
CCTL0 &=~CCIE;
// rtByte[rtByte[9]+11]=0;
vars.Int_ID |= ComInt;
}
else
{
vars.lByte++;
if(vars.lByte>42) goto looperr;
}
rx_cap_start(); // communication start
goto loopend;
looperr:
vars.rt_Bit = 0;
vars.lByte = 0;
rx_cap_reseat(); // communication reseat
loopend:
_NOP();
}
}
if (TAIV|0x04)
{
CCTL2 &=~CCIFG;
CCR2 =TAR+0x8000;
if( !(P1IN&P1DISPLAY) )
{
//
if ( vars.LcdCtl.Switch==1 )
{
vars.LcdCtl.Mode ^= 1;
}
else vars.LcdCtl.Switch++;
//
//LcdCtl.Mode ^= 1;
}
else { CCTL2 &=~CCIE; vars.LcdCtl.Switch = 0; }
}
}
interrupt[PORT1_VECTOR] void p1_int (void)
{
if( (P1IFG&P1DISPLAY)!=0 )
{
P1IFG &=~P1DISPLAY;
CCR2 =TAR+0xFFF0;
CCTL2 |= CCIE;
vars.LcdCtl.SecCtr=0;
if( vars.LcdCtl.PagePtr<23 ) vars.LcdCtl.PagePtr++;
else vars.LcdCtl.PagePtr=0;
vars.Int_ID |= KeyInt;
}
if( (P1IFG&P1REVP)!=0 )
{
vars.CurrentRe.nTime[0]=vars.NowClk1.nMinute;
vars.CurrentRe.nTime[1]=vars.NowClk1.nHour;
vars.CurrentRe.nTime[2]=vars.NowClk1.nDay;
vars.CurrentRe.nTime[3]=vars.NowClk1.nMonth;
vars.E2PROM_SAVE |= UnCover_S;
vars.Int_ID |=E2Int;
P1IFG &=~P1REVP;
}
if( (P1IFG&P1IMPIN)!=0 )
{
P1IFG &=~P1IMPIN;
if (vars.PulseNum>=vars.MetConst)
{
vars.PulseNum=1;
if((vars.Tariff.EC[0][0]&0x0F)>=9) // 电量增加 0.1,保存
{
r_I2C_bytes(&vars.Tariff.EC[0][0],I2C_24CXX_P0,CuECTotal,4);
vars.Tariff.EC[0][0] &= 0xF0;
vars.Tariff.EC[0][0] += 0x09;
vars.E2PROM_SAVE |= EC_S;
vars.Int_ID |=E2Int;
}
if(P1IN&P1REVP) _BCD4INC((BYTE *)&vars.ECReAll[0]);
_BCD4INC((BYTE *)&vars.Tariff.EC[0][0]);
_BCD4INC((BYTE *)&vars.Tariff.EC[vars.bTmp+1][0]); // [vars.bTmp+1]
}
else _BCD1INC((BYTE *)&vars.PulseNum);
}
P1IFG =0;
_NOP();
}
interrupt[PORT2_VECTOR] void p2_int (void)/////////////////////////////////////////开盖记录
{
if( P2IFG&P2UNCOVER )
{
P2IFG &=~P2UNCOVER;
vars.UnCover.nTime[1][0]=vars.UnCover.nTime[0][0];
vars.UnCover.nTime[1][1]=vars.UnCover.nTime[0][1];
vars.UnCover.nTime[1][2]=vars.UnCover.nTime[0][2];
vars.UnCover.nTime[1][3]=vars.UnCover.nTime[0][3];
vars.UnCover.nTime[0][0]=vars.NowClk1.nMinute;
vars.UnCover.nTime[0][1]=vars.NowClk1.nHour;
vars.UnCover.nTime[0][2]=vars.NowClk1.nDay;
vars.UnCover.nTime[0][3]=vars.NowClk1.nMonth;
vars.UnCover.nTimes++;
_NOP();
vars.E2PROM_SAVE |= UnCover_S;
vars.Int_ID |=E2Int;
}
if( P2IFG&P2POWERCHECK )
{
P2IFG &=~P2POWERCHECK;
vars.E2PROM_SAVE |= EC_S;
vars.E2PROM_SAVE |= PulseNum_S;
vars.Int_ID |=E2Int;
}
P2IFG =0;
_NOP();
}
|