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

📄 main.c

📁 MSP430F413单相电表DEMO(编译器IAR 3.42A)
💻 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 + -