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

📄 dds18838104.c

📁 一个电表的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
     }
   else
    {
	   LcdBuf_Disp[8]  &=0xf7; 
     }
   Read_Ad();
   if(RTm_Dtr[0] != 0x00)
    {
	   Dl_ZcFlg = 0;						//清除上次历史电量转存标志
     }
 }


/*************************************************************************/
void Rtc_Mcu_SetIrCom(void)
{
  if(SetTm_Accdnt)		//时间
   {
     RTm_Dtr[0] = E2Buffer[0];
     RTm_Dtr[1] = E2Buffer[1];
     RTm_Dtr[2] = E2Buffer[2];
    } 
  if(SetDate_Accdnt)
   {  
//     _DOWR.Byte = Bcd_hex(E2Buffer[3]);
     RDtWk_Dtr[0] = E2Buffer[3];
     RDtWk_Dtr[1] = E2Buffer[4];
     RDtWk_Dtr[2] = E2Buffer[5];
	 RDtWk_Dtr[3] = E2Buffer[6];
    } 
} 
void Brochk_Time(void)
{ 

  if(Progrm_Disp)
   {
      Rtc_Mcu_SetIrCom();
    }  
} 

void	PowerUp_Time(void)				//上电事件处理
{
	F_BlckRead_Eeprm(PowDwn_Reg,Databuf,0x01);			//读取掉电事件完成寄存器
    if((Databuf[0] == 0xe8) && (PowerUp_Flg))				//表示已有一次下电及上电事件生成
     {
        F_BlckWrt_Eeprm(PowUp_Tm,&RTm_Dtr[1],2);
        F_BlckWrt_Eeprm(PowUp_Tm+2,&RDtWk_Dtr[1],3);
     	F_BlckRead_Eeprm(PDRcd_Pter,Databuf,0x01);		//E2P中读取上电事件指针(同停电事件指针)
     	if(Databuf[0] > 0x00)
	  	 {
	        Databuf[0]--;
	      }
	    else
	     {
	        Databuf[0]=0x09;
	      }
        F_BlckWrt_Eeprm(PDRcd_Pter,Databuf,0x01);		//写入E2P最新停电事件指针
	    F_BlckRead_Eeprm(PowDwn_Tm,Databuf+16,0x05);	//读取最近1次停电时间    
        F_BlckWrt_Eeprm((EPDRcd1_Dtr+Databuf[0]*10),Databuf+16,0x05);	//当前停电时间保存到当前停电事件中
        F_BlckRead_Eeprm(EPdCnt_Dtr,Databuf,0x02);
        Databuf[0] = Data_BcdAdd(Databuf[0]);	 
	    if(Databuf[0] == 0x00)
	     {
	        Databuf[1] = Data_BcdAdd(Databuf[1]); 
          }
	    F_BlckWrt_Eeprm(EPdCnt_Dtr,Databuf,0x02);;			//掉电次数保存到E2P中
        F_BlckRead_Eeprm(PDRcd_Pter,Databuf,0x01);		//E2P中读取上电事件指针
        F_BlckWrt_Eeprm((EPDRcd1_Dtr+Databuf[0]*10+0x05),&RTm_Dtr[1],0x02);		//当前上电时间保存到当前上电事件中
        F_BlckWrt_Eeprm((EPDRcd1_Dtr+Databuf[0]*10+0x07),&RDtWk_Dtr[1],0x03);
     }
}	

/**********************************************************************************/
void	incident_time1(unsigned int addr_star,unsigned addr_point)		//编程时间、次数
{
	F_BlckRead_Eeprm(addr_point,Databuf,0x01);
	if(Databuf[0] > 0x00)
	 {
	   Databuf[0]--;
	  }
	else
	 {
	   if(ClrPw_Accdnt[0] == 0xe8)
	    {
	       Databuf[0]=0x04;
         }
       else if(Prgrm_Accdnt)
	    {
		   Databuf[0] = 0x03;
         }
	 }
	F_BlckWrt_Eeprm((addr_star+Databuf[0]*0x05+0x02),&RTm_Dtr[1],0x02);		//当前时间写入到最近一次编程时间内
	F_BlckWrt_Eeprm((addr_star+Databuf[0]*0x05+0x04),&RDtWk_Dtr[1],0x03);
	if(ClrPw_Accdnt[0] == 0xe8)
	 {
	    F_BlckWrt_Eeprm((ELClrPwrTtl_Dtr+Databuf[0]*0x04),RPPwrTtl_Dtr,0x04);
	   }		//当前电量写入到最近一次清零时电量区内
	    
	if(Prgrm_Accdnt)
	 {
       Databuf[10]=SignPrgrm;
       Databuf[11]=(SignPrgrm>>8);
	   F_BlckWrt_Eeprm((ELPrgrm_MdCnt_Dtr+Databuf[0]*0x02),&Databuf[10],0x02);
	   } 
	F_BlckWrt_Eeprm(addr_point,Databuf,0x01);		//编程事件指针
	F_BlckRead_Eeprm(addr_star,Databuf,0x02);		//事件设置事件次数
    Databuf[0] = HEX2BCD(Databuf[0]+1);
	if(Databuf[0] == 0x00)
     {
       Databuf[1] =HEX2BCD(Databuf[1]+1);
      }
	F_BlckWrt_Eeprm(addr_star,Databuf,0x02);	 
}	
/******************************************************************/
void	Revp_End(void)
{
   if(CrntRStr_Flg[0] == 0x01)			//电流处于正向启动状态
    {
        F_BlckRead_Eeprm(CrntRvrs_Pter,Databuf,0x01);				//读取反向事件次数
        F_BlckWrt_Eeprm((ECrntRvrs_Rcd1_Dtr+Databuf[0]*10+5),&RTm_Dtr[1],0x02);	//当前时间写入反向事件中
 	    F_BlckWrt_Eeprm((ECrntRvrs_Rcd1_Dtr+Databuf[0]*10+0x07),&RDtWk_Dtr[1],0x03);   	          	
 		F_BlckWrt_Eeprm(CrntRvrs_Pter,Databuf,0x01);
 	    CrntRStr_Flg[0]=0x00;				//电流正向
     }
}


	 	
void Incident_Judge(void)			//事件记录
{
  unsigned char i;
  if(ClrPw_Accdnt[0] == 0xe8)				//电量清零记录
   {
     incident_time1(EClrPw_Cnt_Dtr,ClrPw_Tm_Pter);  
     ClrPw_Accdnt[0] =0x00;
     for(i=0;i<4;i++)						//清当前有功电量
      { 						
         *(RPPwrTtl_Dtr+i) = 0;				//清当前有功总电量
 //      *(RPPwrTar1_Dtr+i) = 0;				//清当前有功费率1电量
 //      *(RPPwrTar2_Dtr+i) = 0;				//清当前有功费率2电量
 //      *(RPPwrTar3_Dtr+i) = 0;				//清当前有功费率3电量
 //      *(RPPwrTar4_Dtr+i) = 0;				//清当前有功费率1电量
         *(RNPwrTtl_Dtr+i) = 0;				//清当前反向有功总电量
//       *(RNPwrTar1_Dtr+i) = 0;				//清当前反向有功费率1电量
//       *(RNPwrTar2_Dtr+i) = 0;				//清当前反向有功费率2电量
//       *(RNPwrTar3_Dtr+i) = 0;				//清当前反向有功费率3电量
//       *(RNPwrTar4_Dtr+i) = 0;				//清当前反向有功费率1电量 
      }	
    WatchDog_Set();						//喂狗	
	F_BlckWrt_Eeprm(EPPwrTtl_Dtr,RPPwrTtl_Dtr,4);	//清E2P中当前电量
	F_BlckWrt_Eeprm(EPPwrTtl_BKUP,RPPwrTtl_Dtr,4);	//清E2P中当前电量备份
	F_BlckWrt_Eeprm2(EPPwrTtl_BKUP1,RPPwrTtl_Dtr,4);	//清E2P中当前电量备份
	F_BlckWrt_Eeprm(ENPwrTtl_Dtr,RNPwrTtl_Dtr,4);	//清E2P中当前反向电量
	F_BlckWrt_Eeprm(ENPwrTtl_BKUP,RNPwrTtl_Dtr,4);	//清E2P中当前反向电量备份
	F_BlckWrt_Eeprm2(ENPwrTtl_BKUP1,RNPwrTtl_Dtr,4);	//清E2P中当前反向电量备份
	CF_CUNT = 0x00;
	WatchDog_Set();						//喂狗	
   } 

  if(Prgrm_Accdnt)				//编程时间
   {
     incident_time1(EPrgrm_Cnt_Dtr,Prgrm_Tm_Pter);
     Prgrm_Accdnt=0;     
    }
  if((SetTm_Accdnt)	&& (SetDate_Accdnt))		//广播校时记录
   {
     Brochk_Time();
     SetTm_Accdnt=0;
     SetDate_Accdnt=0;
	 BrochkSec_Cnt = 0;			//广播校时周期清零
    }  
  if((SetTm_Accdnt) || (SetDate_Accdnt))			//时钟设置记录
   {
     Brochk_Time();					//需调试
     SetTm_Accdnt=0;
     SetDate_Accdnt=0;
    }    

  if(PowerUp_Flg)				//上电信号
   {
     PowerUp_Time();					//最近一次上电时间判断	
    } 
  if(Cf_Set)
   {    
      if(Revp_Curr)
       {
          Revp_Flg = 1;
          Revp_Led = 0;
	      RMtWd_Dtr[0] |=0x10;
	      if(CrntRStr_Flg[0] == 0x00)		//电流处于反向启动状态
 	       {
 	         F_BlckRead_Eeprm(CrntRvrs_Pter,Databuf,0x01);				//读取反向事件次数
             if(Databuf[0] > 0x00)
              {
                 Databuf[0]--;
 	           }
		     else
 		      {
 		         Databuf[0]=0x09;
 		       }
             F_BlckWrt_Eeprm(CrntRvrs_Pter,Databuf,0x01);		//保存反向次数指针
 	         F_BlckWrt_Eeprm((ECrntRvrs_Rcd1_Dtr+Databuf[0]*10),&RTm_Dtr[1],0x02);	//当前时间写入反向事件中
 	         F_BlckWrt_Eeprm((ECrntRvrs_Rcd1_Dtr+Databuf[0]*10+0x02),&RDtWk_Dtr[1],0x03);  
			 for(i=0;i<5;i++)
			  {
			      Databuf[10+i] = 0x00;
               }
 	         F_BlckWrt_Eeprm((ECrntRvrs_Rcd1_Dtr+Databuf[0]*10+0x05),&Databuf[10],0x05);  
		     CrntRStr_Flg[0]=0x01;	//电流反向
             F_BlckRead_Eeprm(ECrntRvrs_Cnt_Dtr,Databuf,0x02);			//读取反向次数
             Databuf[0] = Data_BcdAdd(Databuf[0]);	
			 if(Databuf[0] == 0x00)
			  {
			     Databuf[1] = Data_BcdAdd(Databuf[1]);
               }
	         F_BlckWrt_Eeprm(ECrntRvrs_Cnt_Dtr,Databuf,0x02);		//保存反向次数; 
	 	    
	 	    }
 		}
 	  else
 	   {
          Revp_Flg = 0;
          Revp_Led = 1;
	      RMtWd_Dtr[0] &=0xef;	
          Revp_End();
        }      		        	
     }		 
 }    

    
/*****************************************************************************/
void	Power_Reset(void)
{
	unsigned char i;
	IO.PDR9.BYTE |= 0x0E;			//CF_TEST、LED1、LED2置高电平
	IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
	if(!Power_Io_Data)				//
	 {
	    Io_initial();
		Power_Lvi();			//低功耗状态
      }
	delay_10ms();
	WatchDog_Set();						//喂狗
	IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
	if(!Power_Io_Data)				//
	 {
	    Io_initial();
		Power_Lvi();			//低功耗状态
      }
	delay_10ms();
	WatchDog_Set();						//喂狗
	IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
	if(!Power_Io_Data)				//
	 {
	    IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
		if(!Power_Io_Data)
		 {
		    Io_initial();
			Power_Lvi();			//低功耗状态
          }
      }
 }


/*****************************************************************************/
void	Power_Lvi(void)
{
	unsigned char i;
	WatchDog_Set();						//喂狗
	Power_Flg.BYTE = 0x01;				//电源处于异常模式
	IO.PMR9.BYTE = 0xf8;
	IO.PDR9.BYTE = 0x3e;
    PowerLvi_Define();				//进入低功耗各寄存器配置
	SubActive_Define();
	NOP;
	NOP;
	NOP;
	NOP;
	sleep();					//进入SUBACTIVE模式
	NOP;
	NOP;
	NOP;
	NOP;
	NOP;
	for(i=0;i<16;i++)
	 {
	    RRttDspNo_Dtr[i] = 0x00;
      }
    RShftDspTm_Dtr[0] = 0x04;
	RStpDspTm_Dtr[0] = 0x09;
    LcdBuf_Disp[8] = 0x00;
	Disp_WORD = 0;				//显示触发信号清除
    Clr_Buffer();
	Batt_WorkSec_Cnt = 0x00;
	while(1)
	 {
	 	 IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
	     if(Power_Io_Data)		//进入正常模式
		  {
		     NOP;
			 NOP;
			 NOP;
			 NOP;
    	     IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
			 if(Power_Io_Data)
			  {
			      NOP;
				  NOP;
				  NOP;
				  Power_Flg.BYTE = 0x00;
				  IO.PDR9.BYTE |= 0x0E;			//CF_TEST、LED1、LED2置高电平
				  Active_Mode();
				  WatchDog_Define();
				  while(1)
				   {
					   IENR1.BYTE = 0x80;
				       set_imask_ccr(0);
					   PowerDwn_Disp();
                    }
//				  NOP;
//	 		      WatchDog_Set();						//喂狗
				  main();
				}
	   	   }
	     else
		  {
		      PowerDwn_Disp();
	
            }
        }
 }

		 
		 

void	Power_Down(void)
{
    if(Revp_Flg)
	 {
	     Revp_Reg = 0x38;			//表示有反向事件发生
      }
 	if(DlStar_Reg == 0x01)
     {
         F_BlckWrt_Eeprm(EPPwrTtl_Dtr,RPPwrTtl_Dtr,0x04);    
//         F_BlckWrt_Eeprm(EPPwrTtl_BKUP,RPPwrTtl_Dtr,0x04);    		    
		 F_BlckWrt_Eeprm(ENPwrTtl_Dtr,RNPwrTtl_Dtr,0x04); 				//当前反向电量保存到E2P中
	  }
    F_BlckWrt_Eeprm(E_Cf_Cnt,&CF_CUNT,0x01); 							//当前脉冲数保存到E2P中
    F_BlckWrt_Eeprm(PowDwn_Tm,&RTm_Dtr[1],2);							//当前时间保存到掉电时间中
    F_BlckWrt_Eeprm(PowDwn_Tm+2,&RDtWk_Dtr[1],3);
    Databuf[0] = 0xe8;
	F_BlckWrt_Eeprm(PowDwn_Reg,Databuf,0x01);			//掉电标志成立
	Power_Lvi();
 }

/*******************************************************************************/
void	Cf_Alter_Tmcnt(void)			//脉冲间隔时间计算	
{
    switch (RMtCt_Dtr[1])
    {
	   case	0x16:	  
       case 0x32:
	   Cf_Alt_TmConst = 0x07d0;		//33 min,按标准1脉冲产生时间为42.6min(0.0004Ib),8.52min(0.002Ib)
	   break;
	   case 0x08:
	   Cf_Alt_TmConst = 0x0bb8;		//50 min,按标准1脉冲产生时间为85.3min(0.0004Ib),17.04min(0.002Ib	
	   default:
	   Cf_Alt_TmConst = 0x07d0;		//50 min,按标准1脉冲产生时间为85.3min(0.0004Ib)
	   break;
	  }//switch end
    if(Revp_Reg == 0x38)					//系统在上次下电前有反向事件发生
     {
	    F_BlckRead_Eeprm(PowDwn_Tm,Databuf,0x05);			//读取上次系统下电时间
        F_BlckRead_Eeprm(CrntRvrs_Pter,&Databuf[10],0x01);				//读取反向事件次数
        F_BlckWrt_Eeprm((ECrntRvrs_Rcd1_Dtr+Databuf[10]*10+5),Databuf,0x05);	//当前时间写入反向事件中 	          	
 	    CrntRStr_Flg[0]=0x00;				//电流正向
     }
}
				
/*****************************************************************************/
void main(void)
{
    set_imask_ccr(1);
	IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
	if(!Power_Io_Data)				//
	 {
	    Io_initial();
		Power_Lvi();			//低功耗状态
      }
	if(!Power_Io_Data)				//
	 {
	    Io_initial();
		Power_Lvi();			//低功耗状态
      }
	Active_Mode();
    SYSCR1.BYTE = 0x07;
	SYSCR2.BYTE = 0xf0;
    OSCCR.BYTE  = 0x00;			//subclock active
	WatchDog_Define();					//开启看门狗
	WatchDog_Set();						//喂狗
	Power_Reset();						//上电电平检测
	Ram_Define();						//Ram区定义
	Io_Define();	
	Sys_UpVer();						//系统各项参、变量数据校验
    WatchDog_Set();						//喂狗
	IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
	if(!Power_Io_Data)				//
	 {
	    delay_10ms();
	    IO.PCR5 = 0xFE;			//POWER作为输入、WP1、SCL1、SDA1作为输出
		if(!Power_Io_Data)
		 {
		    Io_initial();
			PowerLvi_Define();
			Power_Lvi();			//低功耗状态
          }
      }
    else
	 {
	    Tma_Define();				//定时器A定义且开启计时
		Tmf_Define();				//定时器FH、FL定义且开启计时
		Pwm_Define();				//38.4kHzPWM定义
		Sci_Define();				//SCI定义
		Lcd_Define();				//LCD模块开启	
		Ad_Define();				//AD计量模块开启
		Int_Define();				//打开各项中断参数
        WatchDog_Set();						//喂狗
		Set_RxState();
		Cf_Alter_Tmcnt();			//脉冲间隔时间计算
		Rtc_Add();
		set_imask_ccr(0);					//开中断
		while(1)
		 {
		    if(Power_Flg.BYTE != 0x01)			//电源正常模式
			 {
	             WatchDog_Set();						//喂狗		    
                 Rtc_Judge();
				 F_DispMain_Disp();					//显示模块处理
              }
            if(Power_Flg.BYTE != 0x01)			//电源正常模式
			 {
			      WatchDog_Set();						//喂狗	
				  Protocel_Main_Comm();				//通讯模块处理	
                  F_ProtocolResolve_Comm();
              }
            if(Power_Flg.BYTE != 0x01)			//电源正常模式 
			 {
				  Incident_Judge();					//事件记录
				  Cf_Judge();							//当前电量计量处理	
				  Dianl_Judge();						//历史数据处理   
				  Key_Judge();						//按键判断
              }
            else
			 {
	              WatchDog_Set();				//喂狗		    
			      Power_Down();					//掉电模式
              }
          }
	  }			      
 }

void abort(void)
{
	
}




/******************************************************************************/
//单字节BCD码到二进制数的转换
unsigned char Bcd_hex(unsigned char B_H_data)
{
  unsigned char a;
  a = ((B_H_data&0xf0) >> 1) + ((B_H_data&0xf0)>>4) + ((B_H_data&0xf0)>>4);
  return (a + (B_H_data & 0x0f));
 }

⌨️ 快捷键说明

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