📄 main.c
字号:
//********************************************************************************
//Please confirm the PCB Version, then define the EMETER_VERSION corresponded with
//the PCB in the head file "SystemDefine.h"
//ZhaoZhendong
//LSD Science & Technology Co.,Ltd.
//January 2007
//Built with IAR Embedded Workbench Version: 3.42A
//********************************************************************************
#include "SystemDefine.h"
#include "HardwareDefine.h"
#include "DataType.h"
#include "DataDefine.h"
#include "Display.h"
#include "I2C.h"
#include "Comm.h"
#include "Main.h"
#include "General.c"
#include "Temperature.c"
#include "I2C.c"
#include "Tariff.c"
#include "Display.c"
#include "Timer.c"
#include "Comm.c"
#include "EC.c"
void ProcKey(void)
{
DM.Tsk.Req.Disp=1;
DM.Tsk.Req.Key =0;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
FLL_CTL0 |= XCAP18PF;
//SCFI0 |= FN_2;
//SCFQCTL = 74;
//for (unsigned int i = 0; i < 10000; i++)
//_NOP();
//****************************************************************
//****************************************************************
#ifdef OSC_FAULT_DETECT
IFG1 &= ~OFIFG;
IE1 |= OFIE;
#endif
#if EMETER_VERSION == 1
P1OUT = RS485_TX_BIT;
P1DIR = IR_TX_BIT | RS485_TX_BIT | BIT0;
P1IES = KEY_DOWN_BIT;
P1IE |= CF_BIT | KEY_DOWN_BIT;
P1IFG = 0;
P1SEL = BATTCHECK_BIT;
#elif EMETER_VERSION == 2
P1OUT = RS485_TX_BIT;
#ifdef EXTERN_CLOCK
P1DIR = IR_TX_BIT | RS485_TX_BIT | BIT0;
#else
P1DIR = IR_TX_BIT | RS485_TX_BIT | EX_CLOCK_BIT | BIT0 ;
#endif
P1IES = POWERCHECK_BIT | KEY_DOWN_BIT;
P1IE = POWERCHECK_BIT | KEY_DOWN_BIT;
P1IFG = 0;
P1SEL = BATTCHECK_BIT;
#ifdef ACLK_OUT
P1DIR |= BIT5;
P1SEL |= BIT5;
#endif
#else
#endif
//****************************************************************
//****************************************************************
#if EMETER_VERSION == 1
P2OUT = 0;
P2DIR = BIT3+BIT4+BIT5+BIT6+BIT7;
P2IES |= (KEY_UNCOVER_BIT | POWERCHECK_BIT | 0x20);
P2IE |= (KEY_UNCOVER_BIT | POWERCHECK_BIT | 0x20);
P2IFG = 0;
#elif EMETER_VERSION == 2
P2OUT = 0;
P2DIR = BIT1+BIT2+BIT5+BIT6+BIT7;
P2IES = (KEY_UNCOVER_BIT | CF_BIT);
P2IFG = 0;
P2IE = (KEY_UNCOVER_BIT | CF_BIT | REVP_BIT);
#else
#endif
//****************************************************************
//****************************************************************
P3OUT = 0;
P3DIR = BIT0+BIT1;
//****************************************************************
//****************************************************************
P5SEL = 0xFC;
//****************************************************************
//****************************************************************
#if EMETER_VERSION == 1
P6DIR = (RS485_CON_BIT | LED_RED_BIT | LED_YELLOW_BIT | LED_GREEN_BIT);
P6OUT = (RS485_CON_BIT | LED_RED_BIT | LED_YELLOW_BIT | LED_GREEN_BIT);
#elif EMETER_VERSION == 2
P6OUT = (I2C_SCL_BIT | I2C_SDA_BIT | I2C_WP_BIT
| RS485_CON_BIT | LED_RED_BIT | LED_YELLOW_BIT | LED_GREEN_BIT);
P6DIR = (I2C_SCL_BIT | I2C_SDA_BIT | I2C_WP_BIT
| RS485_CON_BIT | LED_RED_BIT | LED_YELLOW_BIT | LED_GREEN_BIT);
#else
#endif
//****************************************************************
// 让 AD7416 进入掉电模式
DM.Reg.b[0]=1;
SetI2CData(DM.Reg.b,0x9E,0x01,1);
if(SM.CfgChk!=ChkSum((unsigned char*)&SM.Cfg, sizeof(CFGGRP)))
{
if(E2ToRAM(0,E2PInfo[0].Addr)==0)
{
DataClr(0);
}
// *****************************
SM.cul_t = 0;
//SM.E2Flgs &= 0x0F07;
SM.E2Flgs = 0;
SM.PagePtr = 0x01;
SM.TmpOption=1;
SM.bt_int = 0;
SM.SecCtr=0;
SM.Temp = 0;
// *****************************
SM.E2Flgs |= S_E2CFGGRP;
DM.Tsk.Req.I2C=1;
}
if(SM.CMonChk!=ChkSum(SM.CMon.Fee[0], sizeof(CMONBLK)))
{
if(E2ToRAM(1,E2PInfo[1].Addr)==0)
{
DataClr(1);
SM.E2Flgs |= S_E2KWH_0_1;
}
else SM.E2Flgs |= R_E2KWH_0_1;
SM.E2Flgs |= S_E2CMONGRP;
DM.Tsk.Req.I2C=1;
}
if((KEY_DOWN_IN & KEY_DOWN_BIT)==0 && (KEY_PROG_IN & KEY_PROG_BIT)==0 )
{
DataClr(0);
DataClr(1);
SM.E2Flgs |= S_E2CFGGRP;
SM.E2Flgs |= S_E2CMONGRP;
SM.E2Flgs |= S_E2KWH_0_1;
DM.Tsk.Req.I2C=1;
DataClr(2);
for(unsigned char i=0; i<10; i++)
{
E2P_Wb( SM.LMon.Fee[0],E2PG2,LMonAddr[i],sizeof(LMONBLK)+2 );
E2P_Wb( SM.LMon.Fee[0],E2PG3,LMonAddr[i],sizeof(LMONBLK)+2 );
}
}
ClkInit();
if( SM.ClkChk!=ChkSum((unsigned char *)&SM.Clk,sizeof(RTC)) )
ClkRest();
//#ifndef DATA_IN_LCDMEM
LcdInit();
//#endif
DM.RS.ComBit = 0;
DM.RS.ComPtr = 0;
TimeAInit();
RXRst();
#if Second_Counter >= 2
WDTCTL = WDT_ARST_1000; // Start WDT
#endif
_EINT();
while(1)
{
if( DM.Tsk.Req.Key ==1 ) ProcKey();
if( DM.Tsk.Req.Com ==1 ) ProcCom();
if( DM.Tsk.Req.EC ==1 ) ProcEC();
if( DM.Tsk.Req.Half==1 ) ProcHalf();
if( DM.Tsk.Req.Sec ==1 ) ProcSec();
if( DM.Tsk.Req.Min ==1 ) ProcMin();
if( DM.Tsk.Req.Hour==1 ) ProcHour();
if((DM.Tsk.Req.I2C ==1) &&!(SM.E2Flgs&E2BUSY)) ProcE2P();
if( DM.Tsk.Req.Disp==1 ) Display();
if(((*((unsigned int*)&DM.Tsk.Req))&0x1ff)==0) LPM3;
_NOP();
}
}
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=BASICTIMER_VECTOR
__interrupt void Basic_timer(void)
#else
interrupt[BASICTIMER_VECTOR] void Basic_timer(void)
#endif
#else
interrupt[BASICTIMER_VECTOR] void Basic_timer(void)
#endif
{
if ( SM.bt_int >= Second_Div ) SM.bt_int=0;
else SM.bt_int++;
// 以下程序为内部软件时钟温度补偿:
#ifdef TEMP_COMPENSATE
if (DM.Flgs & F_Temp)
{
if ( SM.bt_int>=Second_Div ) SM.bt_int=0;
else SM.bt_int++;
DM.Flgs &=~F_Temp;
}
#endif
if( SM.bt_int== Second_Half ) DM.Tsk.Req.Half=1;
if( SM.bt_int==0 ) DM.Tsk.Req.Sec=1;
#ifdef OSC_FAULT_DETECT
#ifdef DISPLAY_CHANGED
if(SM.Cfg.LcdCtl.Mode&0x0c) SM.Cfg.LcdCtl.Mode--;
#else
if(SM.Cfg.LcdCtl.Mode[0]&0x0c) SM.Cfg.LcdCtl.Mode[0]=SM.Cfg.LcdCtl.Mode[0]-0x04;
#endif
#endif
if(((*((unsigned int*)&DM.Tsk.Req))&0x1ff)!=0) LPM3_EXIT;
}
//*********************************************************
// 100.006103515625ms 中断一次;
// 1. 处理通讯超时;
// 2. 按键定时;
//*********************************************************
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=TIMERA0_VECTOR
__interrupt void Int_TimerA0(void)
#else
interrupt[TIMERA0_VECTOR] void Int_TimerA0(void)
#endif
#else
interrupt[TIMERA0_VECTOR] void Int_TimerA0(void)
#endif
{
unsigned char i;
CCR0 += 3277;
if(DM.RS.ComTmr!=0)
{
DM.RS.ComTmr--;
if(DM.RS.ComTmr==0) RXRst();
}
#ifndef DATA_IN_LCDMEM
if(DM.KeyTmr!=0)
#else
if(DM1.KeyTmr!=0)
#endif
{
if(KEY_DOWN_IN&KEY_DOWN_BIT)
{
DM.Tsk.Req.Key=1;
SM.SecCtr=0;
if ( SM.PagePtr<KeyMaxPages ) SM.PagePtr++;
else SM.PagePtr=0;
if( DspInfo[SM.PagePtr].DspID&0x80 ) // 上上月
{
i=(DspInfo[SM.PagePtr].DspID&0x10)>>4;
GetI2CData( DM.Reg.b,E2PG2,ECPtr,1 );
E2ToRAM(2,LMonAddr[DM.Reg.b[0]>=i?DM.Reg.b[0]-i:DM.Reg.b[0]+10-i]);
}
#ifndef DATA_IN_LCDMEM
DM.KeyTmr=0;
#else
DM1.KeyTmr=0;
#endif
LPM3_EXIT; //Added by ZhaoZhendng 2005.12.25
}
else
{
#ifndef DATA_IN_LCDMEM
DM.KeyTmr--;
#else
DM1.KeyTmr--;
#endif
#ifndef DATA_IN_LCDMEM
if(DM.KeyTmr==0)
#else
if(DM1.KeyTmr==0)
#endif
{
#ifdef DISPLAY_CHANGED
SM.Cfg.LcdCtl.Mode ^= 1; //Added by ZhaoZhendng 2005.12.25
#else
SM.Cfg.LcdCtl.Mode[0] ^= 1; //Added by ZhaoZhendng 2005.12.25
#endif
}
}
}
}
const unsigned char RComOffset[]=
{
14,27,27,28,27,27,28,27,27,28,27,27,250
};
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=TIMERA1_VECTOR
__interrupt void Int_TimerA1(void)
#else
interrupt[TIMERA1_VECTOR] void Int_TimerA1(void)
#endif
#else
interrupt[TIMERA1_VECTOR] void Int_TimerA1(void)
#endif
{
switch(__even_in_range(TAIV, 10))
{
case 0:{}break;
case 2:
{
#ifndef DATA_IN_LCDMEM
if( DM.Flgs & F_RS )
#else
if( DM1.Flgs & F_RS )
#endif
{
ComFlagRAM |= D_Comm;
ProcSend();
}
else
{
if(DM.RS.ComBit==0)
{
CCTL1 &= ~(CAP+CM1);
CCR1 =TAR+14;
}
else CCR1=CCR1+RComOffset[DM.RS.ComBit];
if (DM.RS.ComBit==1)
{
if ((RS485_IR_RX_IN&RS485_IR_RX_BIT)==RS485_IR_RX_BIT)
{
goto looperr;
}
else
{
DM.RS.hByte = 0;
DM.RS.ByteCS = 0;
goto loop0;
}
}
if ((DM.RS.ComBit>1)&&(DM.RS.ComBit<=10)) // 7 or 8 bit: now 8 bit
{
if ((RS485_IR_RX_IN&RS485_IR_RX_BIT)==RS485_IR_RX_BIT)
{
DM.RS.hByte |= 0x200; // 7 or 8 bit
DM.RS.ByteCS++;
}
DM.RS.hByte >>=1;
goto loop0;
}
if (DM.RS.ComBit>10) // 7 or 8 bit
{
DM.RS.ComTmr=6; // 启动500ms的接收超时
DM.RS.hByte &=0xFF; // 7 or 8 bit
if ((DM.RS.ByteCS&1)==0) goto loop1;
else goto looperr;
}
loop0:
DM.RS.ComBit++;
goto loopend;
loop1:
if((DM.RS.ComPtr==0)&&(DM.RS.hByte!=0x68)) goto looperr;
ComFlagRAM |= D_Comm;
DM.RS.ComBit = 0;
DM.RS.ComBuf[DM.RS.ComPtr]=DM.RS.hByte;
if ( DM.RS.ComPtr == RS_Len+11 )
{
DM.RS.ComPtr=0;
DM.RS.ComTmr=0; // 停止接收超时
DM.Tsk.Req.Com=1;
goto loopend; //Added by ZhaoZhendong 2005.11.14
}
else
{
DM.RS.ComPtr++;
if(DM.RS.ComPtr>42) goto looperr;
}
CapStart(); // communication start
goto loopend;
looperr:
DM.RS.ComBit = 0;
DM.RS.ComPtr = 0;
RXRst(); // communication reseat
loopend:
_NOP();
}
}break;
case 4:{}break;
}
}
#if EMETER_VERSION == 1
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=PORT1_VECTOR
__interrupt void p1_int (void)
#else
interrupt[PORT1_VECTOR] void p1_int (void)
#endif
#else
interrupt[PORT1_VECTOR] void p1_int (void)
#endif
{
if( (KEY_DOWN_IFG&KEY_DOWN_BIT)!=0 )
{
#ifndef DATA_IN_LCDMEM
DM.KeyTmr=20;
#else
DM1.KeyTmr=20;
#endif
}
if( (REVP_IFG&REVP_BIT)!=0 )
{
SM.Cfg.IRevTmr[0]=SM.Clk.Min[0];
SM.Cfg.IRevTmr[1]=SM.Clk.Hour[0];
SM.Cfg.IRevTmr[2]=SM.Clk.Day[0];
SM.Cfg.IRevTmr[3]=SM.Clk.Mon[0];
SM.E2Flgs |= S_E2CFGGRP;
DM.Tsk.Req.I2C=1;
}
if( (CF_IFG&CF_BIT)!=0 )
{
unsigned char TMP=BCD2Byte(SM.Cfg.MetConst[1]);
if (++SM.CMon.PlsNum>TMP)
{
SM.CMon.PlsNum=1;
DM.Tsk.Req.EC=1;
}
SM.CMonChk=ChkSum(SM.CMon.Fee[0], sizeof(CMONBLK));
}
P1IFG =0;
_NOP();
}
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=PORT2_VECTOR
__interrupt void p2_int (void)
#else
interrupt[PORT2_VECTOR] void p2_int (void)
#endif
#else
interrupt[PORT2_VECTOR] void p2_int (void)
#endif
{
if( KEY_UNCOVER_IFG & KEY_UNCOVER_BIT )
{
SM.Cfg.UnCover.Tmr[1][0]=SM.Cfg.UnCover.Tmr[0][0];
SM.Cfg.UnCover.Tmr[1][1]=SM.Cfg.UnCover.Tmr[0][1];
SM.Cfg.UnCover.Tmr[1][2]=SM.Cfg.UnCover.Tmr[0][2];
SM.Cfg.UnCover.Tmr[1][3]=SM.Cfg.UnCover.Tmr[0][3];
SM.Cfg.UnCover.Tmr[0][0]=SM.Clk.Min[0];
SM.Cfg.UnCover.Tmr[0][1]=SM.Clk.Hour[0];
SM.Cfg.UnCover.Tmr[0][2]=SM.Clk.Day[0];
SM.Cfg.UnCover.Tmr[0][3]=SM.Clk.Mon[0];
_BCD2INC(SM.Cfg.UnCover.Tms);
SM.E2Flgs |= S_E2CFGGRP;
DM.Tsk.Req.I2C=1;
}
if( POWERCHECK_IFG & POWERCHECK_BIT )
{
//TACTL &= ~MC1; //
SM.E2Flgs |= S_E2CMONGRP;
DM.Tsk.Req.I2C=1;
}
P2IFG =0;
_NOP();
}
#elif EMETER_VERSION == 2
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=PORT1_VECTOR
__interrupt void p1_int (void)
#else
interrupt[PORT1_VECTOR] void p1_int (void)
#endif
#else
interrupt[PORT1_VECTOR] void p1_int (void)
#endif
{
if( (KEY_DOWN_IFG&KEY_DOWN_BIT)!=0 )
#ifndef DATA_IN_LCDMEM
DM.KeyTmr=20;
#else
DM1.KeyTmr=20;
#endif
if( POWERCHECK_IFG & POWERCHECK_BIT )
{
//TACTL &= ~MC1; //2005.12.26
SM.E2Flgs |= S_E2CMONGRP;
DM.Tsk.Req.I2C=1;
}
P1IFG =0;
_NOP();
}
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=PORT2_VECTOR
__interrupt void p2_int (void)
#else
interrupt[PORT2_VECTOR] void p2_int (void)
#endif
#else
interrupt[PORT2_VECTOR] void p2_int (void)
#endif
{
if( KEY_UNCOVER_IFG & KEY_UNCOVER_BIT )
{
SM.Cfg.UnCover.Tmr[1][0]=SM.Cfg.UnCover.Tmr[0][0];
SM.Cfg.UnCover.Tmr[1][1]=SM.Cfg.UnCover.Tmr[0][1];
SM.Cfg.UnCover.Tmr[1][2]=SM.Cfg.UnCover.Tmr[0][2];
SM.Cfg.UnCover.Tmr[1][3]=SM.Cfg.UnCover.Tmr[0][3];
SM.Cfg.UnCover.Tmr[0][0]=SM.Clk.Min[0];
SM.Cfg.UnCover.Tmr[0][1]=SM.Clk.Hour[0];
SM.Cfg.UnCover.Tmr[0][2]=SM.Clk.Day[0];
SM.Cfg.UnCover.Tmr[0][3]=SM.Clk.Mon[0];
_BCD2INC(SM.Cfg.UnCover.Tms);
SM.E2Flgs |= S_E2CFGGRP;
DM.Tsk.Req.I2C=1;
}
if( (CF_IFG&CF_BIT)!=0 )
{
unsigned char TMP=BCD2Byte(SM.Cfg.MetConst[1]);
if (++SM.CMon.PlsNum>TMP)
{
SM.CMon.PlsNum=1;
DM.Tsk.Req.EC=1;
}
SM.CMonChk=ChkSum(SM.CMon.Fee[0], sizeof(CMONBLK));
}
if( (REVP_IFG&REVP_BIT)!=0 )
{
SM.Cfg.IRevTmr[0]=SM.Clk.Min[0];
SM.Cfg.IRevTmr[1]=SM.Clk.Hour[0];
SM.Cfg.IRevTmr[2]=SM.Clk.Day[0];
SM.Cfg.IRevTmr[3]=SM.Clk.Mon[0];
SM.E2Flgs |= S_E2CFGGRP;
DM.Tsk.Req.I2C=1;
}
P2IFG =0;
_NOP();
}
#else
#endif
#ifdef OSC_FAULT_DETECT
#ifdef __IAR_SYSTEMS_ICC__
#if __VER__ >= 200
#pragma vector=NMI_VECTOR
__interrupt void LFXT1_Oscillator_int (void)
#else
interrupt[NMI_VECTOR] void NMI_int (void)
#endif
#else
interrupt[NMI_VECTOR] void NMI_int (void)
#endif
{
do
{
IFG1 &= ~OFIFG; // Clear OSCFault flag
for (unsigned int i = 0xFF; i > 0; i--); // Time for flag to set
}
while ((IFG1 & OFIFG)); // OSCFault flag still set?
#ifdef DISPLAY_CHANGED
SM.Cfg.LcdCtl.Mode |= 0x0c;
#else
SM.Cfg.LcdCtl.Mode[0] |= 0x0c;
#endif
LED_YELLOW_OUT &= ~LED_YELLOW_BIT;
for (unsigned int i = 0; i < 10000; i++)
_NOP();
IE1 |= OFIE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -