📄 ade7758.c
字号:
/*
装载上电后首先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 + -