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

📄 main.c

📁 电能表源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************************

	文件类型:
	文件作用:
	修改权限:
	文件相关:
	
	创 建 人:GeminiKQ
	创建日期:2006.12.20
	当前版本:Ver0.1
	
	版本信息:Ver0.1					GeminiKQ

**************************************************************************************/
#define	MAIN

#include "Tiger.h"
#include "typemeter.h"


//==================================================================
//系统默认较表参数
//==================================================================
unsigned long code meterprm_table[]=
 { 0x00000000,                                // 有功门限高
   0xF2ED9618,                                // 有功门限低
   0x00000000,                                // 有效值门限高
   0x00654FD6,                                // 有效值门限低
   0xffffffff,                                // 启动门限值高
   0xffffffff,                                // 启动门限值低
   0x010CA23A,                                // IA有效值比差
   0x01609618,                                // IB有效值比差
   0x00000000,                                // LA有效值比差
   0x00000000,                                // LB有效值比差
   0x00000000,                                // M有效值比差
   0x00000000,                                // M有效值比差
   0x00000000,                                // M有效值比差
   0xFCCD0213,                                // PA比差
   0xF37D0381,                                // PB比差
   0xF4DB1D71                                 // 电压比差
 };

//=========================================================================
//函数功能:通过入口ID号恢复各参数项  (数据存放在EEPROM中)
//入口参数:ID号
//返回参数:1:成功,0:失败    数据放在wr_buff中
//=========================================================================
unsigned char recover_item(unsigned int chk_id)
{ unsigned char i,j,num,value,datanum;
  value=0;
  num=addr_from_coreID(1,chk_id);					// 数据个数
  for(i=0;i<num;i++)
     { if((*ID_coretalbpoint[i]).stortype==EEPROM) // EEP中
	      {  data_addr.word[1]=(*ID_coretalbpoint[i]).dataaddr;  // 取地址
		     datanum=(*ID_coretalbpoint[i]).datalong;			// 要读的数据个数
		     Read_data(EEPROM,datanum);							// 读函数
			 wr_buff[datanum]=0;							// 读出的数据放在wr_buff[0]--wr_buff[datanum-1]中	
			 for(j=0;j<datanum-1;j++)                            //校验和判断
			     { wr_buff[datanum]+=wr_buff[j];
				 }
             if(wr_buff[datanum]==(wr_buff[datanum-1]-0x33))      //  如果校验和正确
			     {  if((*ID_coretalbpoint[i]).datatype==BCD)
				        { if(check_X_bcd((datanum-1),wr_buff)==1)     //BCD嘛校验
				             { value=1;                               //检测到合法数据,放在wr_buff中
				               break;
				             }
				  	    }
                     else
                        { value=1;                                  //检测到合法数据,放在wr_buff中
				          break;
                        }
				 }
   	      }	
	 }

 return value;
}

//================================================================
// 函数功能:从EEPROM中恢复meterprm_table[]表参数
//      如果恢复成功则返回,不成功,则加载meterprm_table[]表
//================================================================
void Recover_meter(void)
{ uint8 i;
  Word32 read_buff;
  for(i=0;i<16;i++)
     { if(recover_item(0x8500+i)==1)                      // 恢复系统参数正确(见meterprm_table[]表)
	      { read_buff.lword=ReadMeterPara(i+18);
            if(compare_x_byte(&read_buff.byte[0],wr_buff,4)==1)      //与寄存器中参数比较,不同则写参数
                {  read_buff.lword=Longdate_from_xbcd(wr_buff,4);
			       SetMeterCfg(read_buff.lword,(18+i));
		        }
		  }
	   else                                                          //恢复参数失败
           { read_buff.lword=ReadMeterPara(i+18);
		     if(read_buff.lword!=meterprm_table[i])                  //与寄存器中参数比较,不同则写参数
	            { read_buff.lword=meterprm_table[i];
			      SetMeterCfg(read_buff.lword,(18+i));
			    }
		   }
	 }
}



//==========================================
// 函数功能:禁止所有IO口的输入输出
//==========================================
void port_init(void)
{
//   P1OE &= ~BIT0;
//   P10FS = 0x01;   //select second pluss output

     P0OE = 0;
     P1OE = 0;
	 P2OE = 0;
	 P3OE = 0xff;
	 P4OE = 0xff;
	 P5OE = 0xff;
	 P6OE = 0xff;

	 P0IE = 0;
	 P1IE = 0;
	 P2IE = 0;
	 P3IE = 0;
	 P4IE = 0;
	 P5IE = 0;
	 P6IE = 0;
}



//=================================================
// 函数功能: 初始化Timer0
//
//=================================================
void Init_Timer0(void)
{	
	TMOD = 0x01;	     // 工作在模式1
	CKCON|=0x08;         // clk/4 
    TL0  = 0xff;         // 10ms
    TH0  = 0xdf;
    TR0 = 1;		     // 开定时器0
	SetInterrupt(1);     // 打开中断
    
}


//===========================================================
// 函数功能:初始化模拟部分
//
//===========================================================
void Inti_anlmode(void)
{  SetADC(1,8);                 //A通道电流,采用8倍增益
   SetADC(2,8);                 //B通道电流,采用8倍增益
   SetADC(3,8);                 //电压通道,采用8倍增益
   SetMChannel(0,0);            //关m通道
   SetFrq(1);                   //60hz
}

//===============================================
// 函数功能:初始化计量系统
//
//===============================================
void Inti_metermode(void)
{ 
   Inti_anlmode();                // AD增益
   SetMeterFunc(0x80);            // 关闭所有计量通道,关CF输出,开启启动潜动功能
   SetMeterCfg(0xffffffff,22);    //潜动门限高位
   SetMeterCfg(0xffffffff,23);    //潜动门限低位
   InitMeter();                   //初始化计量电路
   Recover_meter();               //恢复校表参数
   SetMeterFunc(0x8f);             //开启电压和A通道计量,A通道输出,能量输出模式
   count_opencftime=3;            //CF延时3妙打开 
}

//==========================================
// 函数功能:系统初始化,
// 备注:初始化模拟部分和数字部分寄存器
//===========================================
void Init_System(void)
{  battest=0;					// 清电池欠压标志
//    SetPLL(1);	
   port_init();                 // 初始化io口
   SetXRam(0);                  // 开启对XRAM的写保护
//   Init_eeprom();             // 初始化EEPROM      上电误操作
   Init_Timer0();
   Inti_metermode();
   OpenPDT();                   // 打开调电检测功能
}


//======================================================
// 函数功能:复位计量模块
//
//======================================================
void reset_primjiaobiao(void)
{
  Inti_metermode();                              //初始化计量模块
  buffer_energ[0]=0;
  buffer_energ[1]=0;
}


//=====================================================
// 函数功能:检测CF脉冲是否异常
// 入口参数:CF脉冲数
// 返回数据:修正后的CF脉冲数
//=====================================================
unsigned long check_jump(unsigned char data_cf)
{ unsigned long value;
 if(data_cf>max_CF)
      { value=0;                                            //停止能量计量
	    if(count_errenergmode<10)
	       { count_errenergmode++;
	         reset_primjiaobiao();                          //重新初始化计量模块
	       }
	  }
 else
      { count_errenergmode=0;
	    value=data_cf;
	  }
 return value;
}


//============================================================================
//读取CF脉冲
//===========================================================================
void read_encount(void)
{ unsigned char temp_CF,temp_data;
  temp_data=ReadMeterFunc();
  if((temp_data&0x40)!=0x40)
      buffer_energ[0]=ReadMeterPara(12)+ReadMeterPara(9);    //读有功脉冲数
  else
      buffer_energ[0]=ReadMeterPara(15);
  if(buffer_energ[0]>buffer_energ[1])                    // 如果脉冲数有增加
    { temp_CF=buffer_energ[0]-buffer_energ[1];           // 计算增加的脉冲数
      temp_CF=check_jump(temp_CF);                       // 防飞走
	  sumCF_Z=sumCF_Z+temp_CF;                           // 能量脉冲累加  
 	  //qidong_time=0;
    }
  buffer_energ[1]=buffer_energ[0];                          
 
}

//==============================================================
//函数功能:恢复电量的整数部分,3个字节
//===============================================================
void Recover_int(unsigned int rec_id)
{ 
  check_engint(rec_id);    // 调用在 energradd.c 中
} 

//-----------------------------------------------------
//函数功能:恢复电量数据
//备注:
//----------------------------------------------------
void Recover_eng(void)
{ 
  Recover_int(ID_POSENGSUM);   		// ID_POSENGSUM 当前有功总电量ID号=0x0100 
}



//======================================================
//函数功能:恢复参数
//  恢复的数据都在RAM中,恢复错误,则,中心设置
//======================================================
void Recover_prim(void)
{unsigned char i,len; 

 if(recover_item(ID_CHANGSHU)==0)                              // 如果脉冲常数恢复错误
   { wr_buff[0]=0;
     wr_buff[1]=0x4;                                           // 默认为400
     wr_buff[2]=0;
   }  															// 存放RAM地址 0x40
 addr_baseonIDandtype(RAM,ID_CHANGSHU);
 data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;      
 Write_data(RAM,(*ID_coretalbpoint[0]).datalong);

 if(recover_item(ID_BANTRATA)==0)                             // 如果恢复波特率出错
   { 
     wr_buff[0]=01;                                           // 默认参数1200
   }
 addr_baseonIDandtype(RAM,ID_BANTRATA);					 	  // 存放RAM地址 0x43
 data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
 Write_data(RAM,(*ID_coretalbpoint[0]).datalong);

 if(recover_item(ID_COMADDR)==0)                               // 恢复表地址错误  表号
   { for(i=0;i<6;i++)
      wr_buff[i]=0;
   }
 addr_baseonIDandtype(RAM,ID_COMADDR);							// 存放RAM地址 0x44
 data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
 len=(*ID_coretalbpoint[0]).datalong;
 Write_data(RAM,len);

 if(recover_item(ID_TIMERETUN)==0)                                  //轮显时间
    { 
      wr_buff[0]=5;                                                 //5秒
    }
 addr_baseonIDandtype(RAM,ID_TIMERETUN);							// 存放RAM地址 0x50
 data_addr.word[1]=(*ID_coretalbpoint[0]).dataaddr;
 len=(*ID_coretalbpoint[0]).datalong;
 Write_data(RAM,len);

}


//=============================================================
//函数功能:恢复停电时保存的数据
// 要恢复的数据都存放在EEPROM中

⌨️ 快捷键说明

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