码迷,mamicode.com
首页 > 其他好文 > 详细

CS5463校验方法

时间:2018-08-30 16:55:25      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:读取数据   精度   taf   符号位   cond   start   mode   返回值   进制   

1:校验电压,电流偏移(交流,直流)

//偏移校正
void cs5463AcDcOffsetwrite(void)
{
uint8_t readBuffer[4];
uint32_t vulue=0;


emberAfCorePrintln("cs5463AcDcOffset satrt.......");

halcs5463Init();

Clear_DRDY();
sendCS5463CalCmd(CS5463_CMD_POWERUP_HALT);


Clear_DRDY();
sendCS5463CalCmd(CS5463_CMD_CALIBRATION_CURRENT_DC_OFFSET);

Wait_DRDY_High();

memset(readBuffer,0,4);
readCs5463Register(0,CS5463_CURRENTDCOFFSET_REG,readBuffer);
emberAfCorePrintln("CS5463_CURRENTDCOFFSET_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
vulue = INT8U_TO_INT32U(0, readBuffer[1], readBuffer[2], readBuffer[3]);
SetCs5463CalDataToFlash(vulue,CS5463_IDCOFF);

Clear_DRDY();
sendCS5463CalCmd(CS5463_CMD_CALIBRATION_VOLTAGE_DC_OFFSET);
Wait_DRDY_High();
memset(readBuffer,0,4);
readCs5463Register(0,CS5463_VOLTAGEDCOFFSET_REG,readBuffer);
emberAfCorePrintln("CS5463_VOLTAGEDCOFFSET_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
vulue = INT8U_TO_INT32U(0, readBuffer[1], readBuffer[2], readBuffer[3]);
SetCs5463CalDataToFlash(vulue,CS5463_VDCOFF);

Clear_DRDY();
sendCS5463CalCmd(CS5463_CMD_CALIBRATION_CURRENT_AC_OFFSET);
Wait_DRDY_High();
memset(readBuffer,0,4);
readCs5463Register(0,CS5463_IACOFF_REG,readBuffer);
emberAfCorePrintln("CS5463_IACOFF_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
vulue = INT8U_TO_INT32U(0, readBuffer[1], readBuffer[2], readBuffer[3]);
SetCs5463CalDataToFlash(vulue,CS5463_IACOFF);

Clear_DRDY();
sendCS5463CalCmd(CS5463_CMD_CALIBRATION_VOLTAGE_AC_OFFSET);
Wait_DRDY_High();
memset(readBuffer,0,4);
readCs5463Register(0,CS5463_VACOFF_REG,readBuffer);
emberAfCorePrintln("CS5463_VACOFF_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
vulue = INT8U_TO_INT32U(0, readBuffer[1], readBuffer[2], readBuffer[3]);
SetCs5463CalDataToFlash(vulue,CS5463_VACOFF);
sendCS5463CalCmd(CS5463_CMD_START_CONV_CONTINUOUS);
emberAfCorePrintln("cs5463AcDcOffset end.......");

}

//偏移读取
void cs5463AcDcOffsetread(void)
{
uint32_t Value=0;
#if 1
uint8_t readBuffer[4];
emberAfCorePrintln("cs5463AcDcOffsetread start*************");
readCs5463Register(0,CS5463_CURRENTDCOFFSET_REG,readBuffer);
emberAfCorePrintln("CS5463_CURRENTDCOFFSET_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
readCs5463Register(0,CS5463_VOLTAGEDCOFFSET_REG,readBuffer);
emberAfCorePrintln("CS5463_CURRENTDCOFFSET_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
readCs5463Register(0,CS5463_IACOFF_REG,readBuffer);
emberAfCorePrintln("CS5463_CURRENTDCOFFSET_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
readCs5463Register(0,CS5463_VACOFF_REG,readBuffer);
emberAfCorePrintln("CS5463_CURRENTDCOFFSET_REG: 0x%x,%x,%x,%x",readBuffer[0],readBuffer[1],readBuffer[2],readBuffer[3]);
#endif

Value= GetCs5463CalDataFromFlash(CS5463_IDCOFF);
emberAfCorePrintln("GetCs5463Vdcoffset: 0x%02x",Value>>16);
}

/********************************************
32位浮点数字转成二进制,
小数点后面的位数,由intNum来决定
************************************************/
uint32_t FloatToBinary(float value)
{
// (-1) s表示符号位,当s = 0,V为正数;当s = 1,V为负数。
// (2)M表示有效数字,大于等于1,小于2。
// (3)2^E表示指数位。
// 对于单精度 符号位 1 指数为8 有效数字 23

uint32_t P_value=0;

uint8_t num=0;
uint32_t reval=0,temp=0;
uint8_t sign =(value>=0)?0:1; //获取符号位
emberAfCorePrintln("sign:%d",sign);
value= fabs(value); //求绝对值
int Interger = floor(value); //获取整数部分
float frac = value - (float)Interger; //获取小数部分
/************************************************************
正数部分42.75;-42.75
sign:0
Interger:42
frac_h:0x1560
frac_l:0x0000
sign:1
Interger:42
frac_h:0x9560
frac_l:0x0000
********************************************************/
while (Interger)
{
if(Interger % 2)
{
temp |= (1<<num);
}
num++;
Interger /= 2;
}

temp <<=23;
reval=temp;
/************************************************************
分解小数部分----由于小部分,可能会出现分解不完全的情况,
并且float中仅有23位,所以仅仅循环23次
------但是对于仅有小数的部分,还要截断一部分,所以需要补充
********************************************************/
temp=0;

for(num=0;num<23;num++)
{
frac *=2;
if(frac>=1)
{
frac -=1;
temp |=(1<<(22-num));
}
if(frac==0)
{
break;
}

}
reval |=temp;
//符号位的处理
if(sign)
{
reval |=(1<<31); //负数
}
emberAfCorePrintln("frac_h:0x%02x",reval>>16);
emberAfCorePrintln("frac_l:0x%02x",reval&(0xffff));
return reval;
}

 

 

//清除数据就绪位

void Clear_DRDY()
{
uint8_t buf[4];
cs5463ReadReg(PAGE_0, CS5463_STATUS_REG, buf);
cs5463WriteReg(PAGE_0, CS5463_STATUS_REG, buf);
}

 

//等待数据就绪,转换好

void Wait_DRDY_High()
{

uint8_t readBuffer[4];
while(1)
{
halResetWatchdog();
cs5463ReadReg(PAGE_0, CS5463_STATUS_REG, readBuffer);
if(readBuffer[1] & 0x80) break; //??DRDY=1
}
}

 

2:校验电压,电流增益

2.1:电压增益:要带负载,输入电压电流

void cs5463GainVwrite(void)
{
uint8_t value = (uint8_t)emberUnsignedCommandArgument(0);
emberAfCorePrintln("Voltage:%d",value);
InitCalVlltage(1);   //电压增益初始化

Wait_DRDY_High();
CalVoltageGain(value);  //把表上读到的值,输入进去。(0-255V)1个字节
}

//电压,电流增益初始化函数

void InitCalVlltage(uint8_t VorI)
{
uint32_t config;
uint32_t Value;

// Dessert PWR_SEN_RESET pin and delay 10ms
GPIO_PinModeSet(PWR_SEN_RESET_PORT, PWR_SEN_RESET_PIN, gpioModePushPull, 1);
GPIO_PinOutClear(PWR_SEN_RESET_PORT, PWR_SEN_RESET_PIN);
halCommonDelayMilliseconds(10);
GPIO_PinOutSet(PWR_SEN_RESET_PORT, PWR_SEN_RESET_PIN);  //复位5463



Value= GetCs5463CalDataFromFlash(CS5463_VACOFF);
cs5463WriteValue(PAGE_0, CS5463_VACOFF_REG, Value);  //输入电压交流偏移

Value= GetCs5463CalDataFromFlash(CS5463_IACOFF);
cs5463WriteValue(PAGE_0, CS5463_IACOFF_REG, Value);  //输入电流交流偏移

Value= GetCs5463CalDataFromFlash(CS5463_IDCOFF);
cs5463WriteValue(PAGE_0,
CS5463_CURRENTDCOFFSET_REG,              //输入电流直流偏移
Value);

Value= GetCs5463CalDataFromFlash(CS5463_VDCOFF);  //输入电压直流偏移
cs5463WriteValue(PAGE_0,
CS5463_VOLTAGEDCOFFSET_REG,
Value);

cs5463WriteValue(PAGE_0, CS5463_CYCLECOUNT_REG, 4000); //zgm  写入N周期数
if(VorI==0) //校准电流
{
cs5463WriteValue(PAGE_0, CS5463_CURRENTGAIN_REG, 0x00400000);   //电流增益初始化为1,这个要校准的参数
Value= GetCs5463CalDataFromFlash(CS5463_VACGAIN);
cs5463WriteValue(PAGE_0, CS5463_VOLTAGEGAIN_REG, Value);   //把校准过的电压增益写入

else //校准电压
{
cs5463WriteValue(PAGE_0, CS5463_VOLTAGEGAIN_REG, 0x00400000);   //把电压增益初始化为1,这个要校准的参数
Value= GetCs5463CalDataFromFlash(CS5463_IACGAIN);
cs5463WriteValue(PAGE_0, CS5463_CURRENTGAIN_REG, Value);

}
cs5463WriteValue(PAGE_0, CS5463_MODE_REG, 0x00000030); //dakai hpf zgm   打开高频滤波

cs5463WriteValue(PAGE_1, CS5463_TEMP_OFFSET, TEMPERATURE_OFFSET_DEFAULT);  //写入温度偏移

config = ((PC) | (IGAIN) | (EWA) | (IMODE) | (IINV) | (ICPU) | (CDIV));   //设置电流10X  (176.8MV)
isCalibrating = false;
cs5463WriteValue(PAGE_0, CS5463_CONFIG_REG, config);  //写入配置字
halCommonDelayMilliseconds(20);
cs5463WriteCommand(CS5463_CMD_START_CONV_CONTINUOUS); // start conversion  开启转换
Clear_DRDY(); //清除DRDY
}

//===========校准电压增益==========================Vgain=Vin/(MAX_VOLTAGE*VRMS)。========
//Vgain=Vin/(MAX_VOLTAGE*读取CS5463的有效电压值)
//Vgain =输入的电压220V,除以读出的电压值230V ,
//vgain=220/230=0.956
void CalVoltageGain(uint8_t value)
{

float vgain=0;
uint32_t vrms;
uint8_t readBuffer[WRITE_BUFFER_SIZE];

cs5463ReadReg(PAGE_0, CS5463_RMSVOLTAGE_REG, readBuffer);
vrms = INT8U_TO_INT32U(0, readBuffer[1], readBuffer[2], readBuffer[3]);
vrms = vrms >> 5;
vrms = vrms * MAX_VOLTAGE;
vrms = vrms >> 19;

emberAfCorePrintln("cs5463ReadReg: %d",vrms);

vgain=(float)value/vrms;


if(vgain>=4)
{
emberAfCorePrintln("Vgain>4, Fail");
return ;
}
vrms = FloatToBinary(vgain);

vrms >>=1;//因为增益只有22位小数,没23为小数 范围【0,4)
vrms &=0x00ffffff;
cs5463WriteValue(PAGE_0, CS5463_VOLTAGEGAIN_REG, vrms);
SetCs5463CalDataToFlash(vrms,CS5463_VACGAIN);


emberAfCorePrintln("CalVoltageGain, ok");
}

2.2:电流增益:要带负载,输入电压电流

void cs5463GainIwrite(void)
{

uint8_t value = (uint8_t)emberUnsignedCommandArgument(0);
emberAfCorePrintln("Current:%d",value);
InitCalVlltage(0);
Wait_DRDY_High();
CalCurrentGain(value);
}

//===========校准电流增益==================================
void CalCurrentGain(uint8_t value)
{

float cgain=0;
double fgain=0;
uint32_t crms;
uint8_t readBuffer[WRITE_BUFFER_SIZE];

cs5463ReadReg(PAGE_0, CS5463_RMSCURRENT_REG, readBuffer);
crms = INT8U_TO_INT32U(0, readBuffer[1], readBuffer[2], readBuffer[3]);
crms = crms >> 8;
crms = crms * 315; //3.157
crms = crms >> 16;

fgain =(double)crms /100.0;
cgain=(float)value/crms;


if(cgain>=4)
{
emberAfCorePrintln("cgain>4, cgain");
return ;
}

crms = FloatToBinary(cgain);
crms >>=1;//因为增益只有22位小数,没23为小数 范围【0,4)
crms &=0x00ffffff;
cs5463WriteValue(PAGE_0, CS5463_CURRENTGAIN_REG, crms);
SetCs5463CalDataToFlash(crms,CS5463_IACGAIN);
emberAfCorePrintln("CalCurrentGain, ok");
}

 

 

/***************************************
从FLSAH中读取数据
item: 表示读的是哪个数据
CS5463_VDCOFF 电压直流偏移
CS5463_IDCOFF 电流直流偏移
CS5463_VACOFF 电压交流偏移
CS5463_IACOFF 电流交流偏移
CS5463_IACGAIN 电流增益
CS5463_VACGAIN 电压增益

uint32_t 返回值
***************************************/

uint32_t GetCs5463CalDataFromFlash(uint32_t item)
{

uint32_t Value=0;
switch(item)
{
case CS5463_VDCOFF:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_VDCOFF);
break;

case CS5463_IDCOFF:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_IDCOFF);
break;

case CS5463_VACOFF:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_VACOFF);
break;

case CS5463_IACOFF:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_IACOFF);
break;

case CS5463_IACGAIN:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_IACGAIN);
break;

case CS5463_VACGAIN:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_VACGAIN);
break;

case CS5463_POWEROFF:
halCommonGetToken((uint32_t *)&Value, TOKEN_CS5463_POWEROFF);
break;

}



return Value;

}
/***************************************
从FLSAH中读取数据
item: 表示读的是哪个数据
CS5463_VDCOFF 电压直流偏移
CS5463_IDCOFF 电流直流偏移
CS5463_VACOFF 电压交流偏移
CS5463_IACOFF 电流交流偏移
CS5463_IACGAIN 电流增益
CS5463_VACGAIN 电压增益

uint32_t Value :
对应的条款的值
***************************************/

void SetCs5463CalDataToFlash(uint32_t Value,uint32_t item)
{
switch(item)
{
case CS5463_VDCOFF:

halCommonSetToken(TOKEN_CS5463_VDCOFF,(uint32_t *)&Value);
break;

case CS5463_IDCOFF:

halCommonSetToken(TOKEN_CS5463_IDCOFF,(uint32_t *)&Value);
break;

case CS5463_VACOFF:

halCommonSetToken(TOKEN_CS5463_VACOFF,(uint32_t *)&Value);
break;

case CS5463_IACOFF:

halCommonSetToken(TOKEN_CS5463_IACOFF,(uint32_t *)&Value);
break;

case CS5463_IACGAIN:

halCommonSetToken(TOKEN_CS5463_IACGAIN,(uint32_t *)&Value);
break;

case CS5463_VACGAIN:

halCommonSetToken(TOKEN_CS5463_VACGAIN,(uint32_t *)&Value);
break;

case CS5463_POWEROFF:
halCommonSetToken(TOKEN_CS5463_POWEROFF,(uint32_t *)&Value );
break;
}

}

CS5463校验方法

标签:读取数据   精度   taf   符号位   cond   start   mode   返回值   进制   

原文地址:https://www.cnblogs.com/zhuguangming/p/9560646.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!