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

📄 ade7758.c

📁 ADI公司的ADE7758全部使用原代码(包括校验)
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
	装载上电后首先AdeInit(),调用3个子程序为Read_Ade_Burn_Parm/Write_Ade_Reg_Val/AdeRead,其中Read_Ade_Burn_Parm
将EEPROM中的要固化ADE参数读到adeburnparm(用于固化的参数区),自检通过后调用Read_Ade_Reg_Val将此adeburnparm读到
runaderegval.Write_Ade_Reg_Val则调用若干子程序将上面的参数写入ADE的参数区,其中WriteConfig为通用配置寄存器的设置.
	调用ADE_Calib对ADE进行校验,采用线性积分方式:
	1)ADE的电流waveform sampling为带符号的24位,同时考虑50%的gain增溢调整,则实际为22位,即最大为
3FFFFF,又考虑63%的裕度,则0.5V时的最大值为2642412.IRMS从以上的waveform sampling而来,最大为1921472.
	2)ADE的电压waveform sampling当0.5V时其输出值为电压满刻度的63%,为0X2797,VRMS从waveform sampling
而来,处理后0.5V时为1678210.
	3)电流的gain增溢调整:ITEST=2A(IMAX=20A)
		2*1921472/20=IRMSTEST*(1+IRMSGAIN/2**12)
	4)电压的gain增溢调整:VTEST=220V(VMAX=520V)
		220*1678210/520=VRMSTEST*(1+VRMSGAIN/2**12)
	注:1)\2)\3)\4)的LCYCMODE_VAL_RW8U=0X38
	5)APCFDEN的计算:APCFNOMAL=(16*1000*60*0.5)/(134.33*7.778)=459.41		
					APCFEXPECTED=(32000*60*0.5)/(1000*3600)=0.26666666
					APCFDEN=1723
					VADIV=0X0C
	6)WAT\VA的gain增溢调整:ITEST=0.5A,VTEST=60V,LCYCMODE=0XBF,LINECYC=0X800,MASK=0x001000,@=0.
		WATTHREXTECTED=[(4*32000*0.5*60*1*ACCUMTIME*1723)/1000*3600]/12
		其中ACCUMTIME=2048/[2*(1/2085*9.6*10**-6)*3]=6.832128
		WATTHREXTECTED=1046.38
	7)VAR的gain增溢调整:@=90,其余同6).
	8)WAT的OS调整:ITEST=0.5A,VTEST=60V,LCYCMODE=0XBF,LINECYCTEST=0X800,MASK=0x001000,@=0.
		IMIN=0.02A,VMIN=7V,LINECYCTEST=0X4000
		分别读出WATTHRTEST及WATTHRMIN.
		WATOFFSET=(WATTHRMIN*0.5-WATTHRTEST*8*0.02)/(0.02-0.5)
		WATTHROS=[(4*WATOFFSET)/(ACCUMTIME*10)]*2**29
		其中ACCUMTIME=16384/[2*(1/2085*9.6*10**-6)*3]=54.657S
		WATOFFSET=(WATTHRMIN*19645-WATTHRTEST*6286)/(-4800)
	9)VAR的OS调整:@=90,其余同8).		
*/
#include "config.h"
#include "pinsel.h"
#include "ade7758.h"
#include "eint3.h"
#include "e2prom.h"
#include "function.h"
#include "wpd800.h"
#include "string.h"
#include "main.h"
#include "timer1.h"
#include "mea.h"
#include "math.h"

AdeRegVal runaderegval;//对应ADE7758全部内部寄存器
CalibUI_RMS_VAL uirmsval;//UI RMS
CalibUI_RMS_VAL_TEST uirmsvaltest;// 输入标准(0.5A,60V) UI RMS
CalibUI_RMS_VAL_MIN uirmsvalmin;//输入最小值(0.013A,7V) UI RMS
Calib_WATVARVA_VAL watvarvaval;
Calib_WATVARVA_VAL_TEST watvarvavaltest;
Calib_WATVARVA_VAL_TEST_PF05 watvarvavaltestpf05;
Calib_WATVARVA_VAL_MIN watvarvavalmin;
Ade_Burn_Parm adeburnparm;//用于固化的ADE寄存器参数
Ade_Mea_VAL ademeaval;//读取的ADE各电量(经过处理)

uint32 eint3timer=0;
uint32 eint3timer1;
uint32 eint3timer2;
uint32 TCTEMP1,TCTEMP2;
uint16 CalibTypeR=0;//下行命令标志
uint16 CalibTypeW=0;//上行命令标志
uint32 eint3intcnt=0;
bool booladeinit=TRUE;
bool Ade_Test=TRUE;


uint32 HrT0TCFI=0;
uint32 HrT0TCEND=0;

//uint8 tempia[32],tempib[32],tempic[32],tempua[32],tempub[32],tempuc[32];

//extern TMEAVAL tMeaVal;
extern BYTE adehrcnt;
extern BYTE adermscnt;
extern volatile DWORD dTCounter;//计数器

//extern uint32 freqnumcnt;
//extern uint32 freqcalcnt;
//extern uint32 freqvalue[freqlgh];
 
const uint8 aderegaddr[80]=
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,	
 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,	
 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x7e,0x7f,0x80,0x00,0x00,0x00,0x00};

void RunReadAde_Hr_Val(void);
void RunReadAde_Rms_Val(void);
void Write_Energy_Cmd(void);
void AdeEntCalibSt(void);
void AdeEscCalibSt(void);
void Calib_UI_Gain_Sub(void);
void Get_Calib_UI_Os_TestVal_Sub(void);
void Get_Calib_UI_Os_MinVal_Sub(void);
void Calib_UI_Os_Sub(void);
void Calib_WATVA_Gain_Sub(void);
void Calib_VAR_Gain_Sub(void);
void Get_Calib_Ph_Os_TestVal_Sub(void);
void Get_Calib_Ph_Os_TestVal_PF05_Sub(void);
void Calib_Ph_Os_Sub(void);
void Get_Calib_WATVA_Os_TestVal_Sub(void);
void Get_Calib_WATVA_Os_TestVal_Min_Sub(void);
void Calib_WATVA_Os_Sub(void);
void Get_Calib_VAR_Os_TestVal_Sub(void);
void Get_Calib_VAR_Os_TestVal_Min_Sub(void);
void Calib_VAR_Os_Sub(void);
void ReadAde3byte(uint8 cmdval,uint32 *p24);

extern int32 _div32by32(int32,int32);
extern int32 _div32by32COS(int32,int32);
extern uint32 udiv32by32mea(uint32,uint32);

void  DelayAdeNS(uint32  dly)
{  
    uint32  i;

    for(; dly>0; dly--) 
        for(i=0; i<30; i++);
}
void adecmdwrite(uint8 data)//写命令
{
	bool booladecmd;	
	
	IO1CLR = ADECS_CLR;
	IO0SET = ADESCK_SET;		
	booladecmd=data&0x80;//7
	if(booladecmd) IO0SET = 0x00080000;
	else IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;	
	booladecmd=data&0x40;//6
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;	
	booladecmd=data&0x20;//5
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;
	booladecmd=data&0x10;//4
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;
	booladecmd=data&0x08;//3
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;
	booladecmd=data&0x04;//2
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;
	booladecmd=data&0x02;//1
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;
	booladecmd=data&0x01;//0
	IO0SET = ADESCK_SET;		
	if(booladecmd) IO0SET = 0x00080000;
	else	IO0CLR = 0x00080000;
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};
	__asm{nop};
	__asm{nop};	
}
uint8 adereadvalue(void)//读一个BYTE
{
	uint8 data;
	uint32 bak1;//,TCTEMP1,TCTEMP2;

	//TCTEMP1=T0TC;
	bak1=0x00;

	__asm{nop};
	__asm{nop};
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//0	
	__asm{nop};
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//1
	__asm{nop};
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//2	
	__asm{nop};
	__asm{nop};
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};		
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//3
	__asm{nop};		
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};	
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//4
	__asm{nop};		
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};	
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//5
	__asm{nop};		
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};		
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//6
	__asm{nop};		
	IO0CLR = ADESCK_CLR;
	__asm{nop};
	__asm{nop};	
	IO0SET = ADESCK_SET;
	bak1 = (((IO0PIN) & (0x00040000)) | bak1 ) << 1;//7
	__asm{nop};		
	IO0CLR = ADESCK_CLR;

	bak1 = ((bak1 >> 19) & (0x000000ff));
	data = (uint8)bak1; 

	//TCTEMP2=T0TC;

	return data;
}
void WriteAde3byte(uint8 cmdval,uint32 dat24)//写三个BYTE命令
{
	adecmdwrite(cmdval);
	adecmdwrite((uint8)((dat24>>0x10)&0x000000ff));
	adecmdwrite((uint8)((dat24>>0x08)&0x000000ff));
	adecmdwrite((uint8)(dat24&0x000000ff));
	DelayAdeNS(1);	
	IO1SET = ADECS_SET;
}	
void WriteAde2byte(uint8 cmdval,uint16 dat16)//写二个BYTE命令
{
	adecmdwrite(cmdval);
	adecmdwrite((uint8)((dat16>>0x08)&0x00ff));
	adecmdwrite((uint8)(dat16&0x00ff));
	DelayAdeNS(1);	
	IO1SET = ADECS_SET;
}	
void WriteAde1byte(uint8 cmdval,uint8 dat8)//写一个BYTE命令
{
	adecmdwrite(cmdval);
	adecmdwrite(dat8);
	DelayAdeNS(1);	
	IO1SET = ADECS_SET;
}	
void ReadAde3byte(uint8 cmdval,uint32 *p24)//读三个BYTE
{
	uint8 data1,data2,data3;
	uint32 temp1,temp2,temp3;
	
	adecmdwrite(cmdval);
	temp1=T0TC;
	DelayAdeNS(2);
	temp2=T0TC;					
	data3=adereadvalue();
	data2=adereadvalue();
	data1=adereadvalue();
	IO1SET = ADECS_SET;	
	temp3=T0TC;
	*p24=(data3<<0x10)|(data2<<0x08)|data1;	
}
void ReadAde2byte(uint8 cmdval,uint16 *p16)//读二个BYTE
{
	uint8 data1,data2;

	adecmdwrite(cmdval);
	DelayAdeNS(2);				
	data2=adereadvalue();
	data1=adereadvalue();
	IO1SET = ADECS_SET;	
	*p16=(uint16)(data2<<0x08)|data1;	
}
void ReadAde1byte(uint8 cmdval,uint8 *p8)//读一个BYTE
{
	uint8 data1;

	adecmdwrite(cmdval);
	DelayAdeNS(2);				
	data1=adereadvalue();
	IO1SET = ADECS_SET;	
	*p8=data1;	
}
void setadereg2byte(uint16 *p16,uint16 data)
{
	*p16=data;
}	
void Write_Energy_Cmd(void)//脉冲方式能量命令写入
{
	ReadAde3byte(aderegaddr[RSTATUS_R24U],(uint32 *)&(runaderegval.RSTATUS_VAL_R24U));
	runaderegval.LCYCMODE_VAL_RW8U=0x40;//0x78;
	runaderegval.MASK_VAL_RW24U=0x201;//0x204;//0x000004;//视在能量中断	
	WriteAde1byte((aderegaddr[LCYCMODE_RW8U])|0x80,runaderegval.LCYCMODE_VAL_RW8U);
	WriteAde3byte((aderegaddr[MASK_RW24U])|0x80,runaderegval.MASK_VAL_RW24U);

	//ademeaval.MEA_AWATHR=0;
	//ademeaval.MEA_BWATHR=0;
	//ademeaval.MEA_CWATHR=0;
	//ademeaval.MEA_AVARHR=0;
	//ademeaval.MEA_BVARHR=0;
	//ademeaval.MEA_CVARHR=0;
	//ademeaval.MEA_AVAHR=0;
	//ademeaval.MEA_BVAHR=0;
	//ademeaval.MEA_CVAHR=0;	
	
	ReadAde2byte(aderegaddr[AWATTHR_R16S],(uint16 *)&(runaderegval.AWATTHR_VAL_R16S));
	ReadAde2byte(aderegaddr[BWATTHR_R16S],(uint16 *)&(runaderegval.BWATTHR_VAL_R16S));
	ReadAde2byte(aderegaddr[CWATTHR_R16S],(uint16 *)&(runaderegval.CWATTHR_VAL_R16S));
	ReadAde2byte(aderegaddr[AVARHR_R16S],(uint16 *)&(runaderegval.AVARHR_VAL_R16S));
	ReadAde2byte(aderegaddr[BVARHR_R16S],(uint16 *)&(runaderegval.BVARHR_VAL_R16S));
	ReadAde2byte(aderegaddr[CVARHR_R16S],(uint16 *)&(runaderegval.CVARHR_VAL_R16S));
	ReadAde2byte(aderegaddr[AVAHR_R16U],(uint16 *)&(runaderegval.AVAHR_VAL_R16U));
	ReadAde2byte(aderegaddr[BVAHR_R16U],(uint16 *)&(runaderegval.BVAHR_VAL_R16U));
	ReadAde2byte(aderegaddr[CVAHR_R16U],(uint16 *)&(runaderegval.CVAHR_VAL_R16U));

	booleint3=FALSE;			
	ReadAde3byte(aderegaddr[RSTATUS_R24U],(uint32 *)&(runaderegval.RSTATUS_VAL_R24U));
}
void Write_Lcycle_Cmd(void)//线性积分方式能量命令写入
{
	ReadAde3byte(aderegaddr[RSTATUS_R24U],(uint32 *)&(runaderegval.RSTATUS_VAL_R24U));
	runaderegval.LCYCMODE_VAL_RW8U=0xbf;
	runaderegval.MASK_VAL_RW24U=0x001000;	
	WriteAde1byte((aderegaddr[LCYCMODE_RW8U])|0x80,runaderegval.LCYCMODE_VAL_RW8U);
	WriteAde2byte((aderegaddr[LINECYC_RW16U])|0x80,runaderegval.LINECYC_VAL_RW16U);
	WriteAde3byte((aderegaddr[MASK_RW24U])|0x80,runaderegval.MASK_VAL_RW24U);
	while(booleint3==FALSE);
	booleint3=FALSE;	
	ReadAde3byte(aderegaddr[RSTATUS_R24U],(uint32 *)&(runaderegval.RSTATUS_VAL_R24U));

	while(booleint3==FALSE);
	booleint3=FALSE;	
	ReadAde3byte(aderegaddr[RSTATUS_R24U],(uint32 *)&(runaderegval.RSTATUS_VAL_R24U));
}
//调试方式读取电量,共10次,第1次不用,9次值平均用于能量的校验
void ReadVal_WatVarVa(void)
{
	int32 awathr,bwathr,cwathr,avarhr,bvarhr,cvarhr,freqval,uitemp4;
	int16 uitemp1,uitemp2,uitemp3;	
	uint32 avahr,bvahr,cvahr,uhrtemp4;
	uint16 uhrtemp1,uhrtemp2,uhrtemp3;
	
	uint8 *pfreq,*pawat,*pbwat,*pcwat,*pavar,*pbvar,*pcvar;
	uint8 *pava,*pbva,*pcva,i;
	uint8 tempfreq[24];
	uint8 tempawathr[24];
	uint8 tempbwathr[24];
	uint8 tempcwathr[24];
	uint8 tempavarhr[24];
	uint8 tempbvarhr[24];
	uint8 tempcvarhr[24];
	uint8 tempavahr[24];
	uint8 tempbvahr[24];
	uint8 tempcvahr[24];
	pfreq=&tempfreq[0];
	pawat=&tempawathr[0];
	pbwat=&tempbwathr[0];
	pcwat=&tempcwathr[0];
	pavar=&tempavarhr[0];
	pbvar=&tempbvarhr[0];
	pcvar=&tempcvarhr[0];
	pava=&tempavahr[0];
	pbva=&tempbvahr[0];
	pcva=&tempcvahr[0];

	for(i=0;i<10;i++)
	{
		while(booleint3==FALSE);
		adecmdwrite(aderegaddr[FREQ_R12U]);
		DelayAdeNS(2);				
		*pfreq++=adereadvalue();
		*pfreq++=adereadvalue();
		IO1SET = ADECS_SET;	
		adecmdwrite(aderegaddr[AWATTHR_R16S]);
		DelayAdeNS(2);				
		*pawat++=adereadvalue();
		*pawat++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[BWATTHR_R16S]);
		DelayAdeNS(2);				
		*pbwat++=adereadvalue();
		*pbwat++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[CWATTHR_R16S]);
		DelayAdeNS(2);				
		*pcwat++=adereadvalue();
		*pcwat++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[AVARHR_R16S]);
		DelayAdeNS(2);				
		*pavar++=adereadvalue();
		*pavar++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[BVARHR_R16S]);
		DelayAdeNS(2);				
		*pbvar++=adereadvalue();
		*pbvar++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[CVARHR_R16S]);
		DelayAdeNS(2);				
		*pcvar++=adereadvalue();
		*pcvar++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[AVAHR_R16U]);
		DelayAdeNS(2);				
		*pava++=adereadvalue();
		*pava++=adereadvalue();
		IO1SET = ADECS_SET;
		adecmdwrite(aderegaddr[BVAHR_R16U]);
		DelayAdeNS(2);				
		*pbva++=adereadvalue();
		*pbva++=adereadvalue();

⌨️ 快捷键说明

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