|
本帖最后由 Baldwin 于 2018-8-22 19:16 编辑
最近有款产品需要用到电能计量,选用了FM33A0xx+RN8302主流方案。计量模块开发也是从一知半解到懵懂,再到熟悉,酸甜苦辣因有尽有 ,下面把相关资料分享给大家,尽量少走弯路;
1---------------------------------------硬件部分-------------------------------------------------------------------------
RN8302外围电路
电压、电流信号采集电路;电压采用常规电阻分压,电流采用电流互感器5(60)A/2mA;
2---------------------------------------RN8302 通信部分-------------------------------------------------------------------------
(1)RN8302采用模拟SPI通信(RN8302与MCU之间采用了光耦隔离,无法直接用硬件SPI,只能用软件SPI)
- static void RN8302_GPIO_Init(void)
- {
- //cs端口初始化
- OutputIO(RN8302_CS_GPIO, RN8302_CS_GPIO_Pin, 0);
- OutputIO(RN8302_SCK_GPIO, RN8302_SCK_GPIO_Pin, 0);
- InputIO(RN8302_MISO_GPIO, RN8302_MISO_GPIO_Pin, 1);
- OutputIO(RN8302_MOSI_GPIO, RN8302_MOSI_GPIO_Pin, 0);
- //MySPI1_Init();
- //SPIx_SPICR2_SPIEN_Setable(SPI1, ENABLE);//SPI1模块使能
- RN8302_CS_SET();
- RN8302_SCK_CLR();
- RN8302_MOSI_SET();
- }
- static void RN8302_SPI_WriteByte(uint8_t byte)
- {
- uint8_t i=0;
- for(i=0;i<8;i++) //写字节
- {
- RN8302_SCK_SET(); //在时钟的上升沿写数据
- RN8302_SCK_SET();
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- if(byte & 0x80 ){
- RN8302_MOSI_SET();
- RN8302_MOSI_SET();
- }
- else{
- RN8302_MOSI_CLR();
- RN8302_MOSI_CLR();
- }
- RN8302_DelayUs(RN8302_CLOCKWIDTH/2);
- RN8302_SCK_CLR();
- RN8302_SCK_CLR();
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- byte <<= 1;
- }
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- }
- static uint8_t RN8302_SPI_ReadByte(void)
- {
- uint8_t i=0,byte=0;
- for(i=0;i<8;i++) //读字节
- {
- byte <<= 1;
- RN8302_SCK_SET();
- RN8302_SCK_SET();
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- RN8302_SCK_CLR();
- RN8302_SCK_CLR();
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- if(RN8302_Read_MISO()) //在时钟的下降沿读数据
- byte += 0x01;
- //RN8302_DelayUs(RN8302_CLOCKWIDTH/2);
- }
- return byte;
- }
复制代码
(2)RN8302读写寄存器,查看手册,不具体说明
- /********************************************************
- 功能描述:
- 参数说明:
- 返回说明: 0表示读取成功,非0表示读取失败
- 调用方式:
- 全局变量:
- 读写时间:
- 注意事项:
- 日期 :
- ********************************************************/
- uint8_t RN8302_ReadReg(uint16_t regAddr,uint8_t *regBuf,uint8_t regLen)
- {
- uint8_t i = 0,chksum = 0;
- uint8_t buf[2]={0};
- RN8302_CS_CLR();
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- buf[0] = (uint8_t)(regAddr&0x00FF);
- buf[1] = ((uint8_t)(regAddr>>4))&0xF0|RN8302_Cmd_Read;
- for(i=0;i<2;i++)
- {
- RN8302_SPI_WriteByte(buf[i]);
- chksum += buf[i];
- }
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- //最后一个字节是cs校验,所以要多收一个
- for(i=0;i<regLen+1;i++)
- {
- regBuf[i] = RN8302_SPI_ReadByte();
- }
- for(i=0;i<regLen;i++)
- {
- chksum += regBuf[i];
- }
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- RN8302_CS_SET();
-
- chksum ^= 0xFF;
-
- if(chksum == regBuf[regLen])
- return 0;
- else
- return 1;
- }
- void RN8302_WriteReg(uint16_t regAddr,uint8_t *regBuf,uint8_t regLen)
- {
- uint8_t i = 0;
- uint8_t buf[2]={0};
- uint8_t chksum = 0;
- RN8302_CS_CLR();
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- buf[0] = (uint8_t)(regAddr&0xFF);
- buf[1] = RN8302_Cmd_Write|((uint8_t)(regAddr>>4))&0xF0;
- for(i=0;i<2;i++){
- RN8302_SPI_WriteByte(buf[i]);
- chksum += buf[i];
- }
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- for(i=0;i<regLen;i++){
- chksum += regBuf[i];
- }
- //最后一个字节是cs校验,所以要多写一个
- for(i=0;i<regLen;i++){
- RN8302_SPI_WriteByte(regBuf[i]);
- }
- RN8302_SPI_WriteByte(~chksum);
- RN8302_DelayUs(RN8302_CLOCKWIDTH);
- RN8302_CS_SET();
- }
复制代码
这是RN8302寄存器地址范围,读取计量参数存储区时,16位寄存器地址前面为0x00xx;读取配置和状态寄存器时,16位寄存器地址前面为0x01xx,这点千万不用忘记了,之前再这边坑了好久
(3)RN8302初始化,将之前校表时换算出的寄存器值填入,这样RN8302采集到的值就是校准好的
- uint8_t RN8302_Init(void)
- {
- uint8_t regbuf[4];
- uint8_t status = 1;
- /* 端口初始化 */
- RN8302_GPIO_Init();
- //读取RN8302 DeviceID
- if(RN8302_ReadReg(0x018F,regbuf,3) == 0){
- if((regbuf[0]==0x83)&&(regbuf[1]==0x02)&&(regbuf[2]==0x00)){
- status = 0;
- }
- else{
- status = 1;
- }
- }
- else{
- status = 1;
- }
- //deviceID读取成功
- if(status == 0){
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- //切换到EMM模式
- regbuf[0] = 0xA2;
- RN8302_WriteReg(WMSW,regbuf,1);
- //复位
- regbuf[0] = 0xFA;
- RN8302_WriteReg(SOFTRST,regbuf,1);
- TicksDelayMs(20);
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- //切换到EMM模式
- regbuf[0] = 0xA2;
- RN8302_WriteReg(WMSW,regbuf,1);
- //写HFCONST1
- regbuf[0] = 0x2E;
- regbuf[1] = 0xA1;
- RN8302_WriteReg(HFCONST1,regbuf,2);
- //写电压增益
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSUx[0]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSUx[0]%256;
- RN8302_WriteReg(GSUA,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSUx[1]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSUx[1]%256;
- RN8302_WriteReg(GSUB,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSUx[2]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSUx[2]%256;
- RN8302_WriteReg(GSUC,regbuf,2);
- //写电流增益
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSIx[0]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSIx[0]%256;
- RN8302_WriteReg(GSIA,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSIx[1]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSIx[1]%256;
- RN8302_WriteReg(GSIB,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSIx[2]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSIx[2]%256;
- RN8302_WriteReg(GSIC,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GSIx[3]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GSIx[3]%256;
- RN8302_WriteReg(GSIN,regbuf,2);
- //采样通道IA分段相位校正
- // RN8302_WriteReg(PHSIA,(uint8_t*)&StDef_RN8302Para_Reg.PHSI[0],2);
- // RN8302_WriteReg(PHSIB,(uint8_t*)&StDef_RN8302Para_Reg.PHSI[1],2);
- // RN8302_WriteReg(PHSIC,(uint8_t*)&StDef_RN8302Para_Reg.PHSI[2],2);
- //通道相位分段校正,电流阈值
- // RN8302_WriteReg(PRTH1L,(uint8_t*)&Dl645FirmPara.PRth[0],2);
- // RN8302_WriteReg(PRTH1H,(uint8_t*)&Dl645FirmPara.PRth[1],2);
- // RN8302_WriteReg(PRTH2L,(uint8_t*)&Dl645FirmPara.PRth[2],2);
- // RN8302_WriteReg(PRTH2H,(uint8_t*)&Dl645FirmPara.PRth[3],2);
- //x相有功功率增益
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GPx[0]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GPx[0]%256;
- RN8302_WriteReg(GPA,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GPx[1]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GPx[1]%256;
- RN8302_WriteReg(GPB,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_GPx[2]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_GPx[2]%256;
- RN8302_WriteReg(GPC,regbuf,2);
- //x相有功分段相位校正
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Px_PHSL[0]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Px_PHSL[0]%256;
- RN8302_WriteReg(PA_PHS,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Px_PHSL[1]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Px_PHSL[1]%256;
- RN8302_WriteReg(PB_PHS,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Px_PHSL[2]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Px_PHSL[2]%256;
- RN8302_WriteReg(PC_PHS,regbuf,2);
- //x相无功分段相位校正
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Qx_PHSL[0]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Qx_PHSL[0]%256;
- RN8302_WriteReg(QA_PHS,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Qx_PHSL[1]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Qx_PHSL[1]%256;
- RN8302_WriteReg(QB_PHS,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Qx_PHSL[2]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Qx_PHSL[2]%256;
- RN8302_WriteReg(QC_PHS,regbuf,2);
- //x相无功功率增益
- // RN8302_WriteReg(GQA,(uint8_t*)&Dl645FirmPara.PGain[0],2);
- // RN8302_WriteReg(GQB,(uint8_t*)&Dl645FirmPara.PGain[1],2);
- // RN8302_WriteReg(GQC,(uint8_t*)&Dl645FirmPara.PGain[2],2);
- //x相视在功率增益
- // RN8302_WriteReg(GSA,(uint8_t*)&Dl645FirmPara.PGain[0],2);
- // RN8302_WriteReg(GSB,(uint8_t*)&Dl645FirmPara.PGain[1],2);
- // RN8302_WriteReg(GSC,(uint8_t*)&Dl645FirmPara.PGain[2],2);
- //x相有功功率offset
- // RN8302_WriteReg(PA_OS,(uint8_t*)&Dl645FirmPara.UI_Offset[0],2);
- // RN8302_WriteReg(PB_OS,(uint8_t*)&Dl645FirmPara.UI_Offset[1],2);
- // RN8302_WriteReg(PC_OS,(uint8_t*)&Dl645FirmPara.UI_Offset[2],2);
- //电流offset
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Ix_OS[0]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Ix_OS[0]%256;
- RN8302_WriteReg(IA_OS,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Ix_OS[1]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Ix_OS[1]%256;
- RN8302_WriteReg(IB_OS,regbuf,2);
- regbuf[0] = StDef_RN8302Para_Reg.Cst_Ix_OS[2]/256;
- regbuf[1] = StDef_RN8302Para_Reg.Cst_Ix_OS[2]%256;
- RN8302_WriteReg(IC_OS,regbuf,2);
-
- //有功视在启动电流阈值
- regbuf[0] = 0x02;
- regbuf[1] = 0x36;
- RN8302_WriteReg(IStart_PS,regbuf,2);
- //无功视在启动电流阈值
- regbuf[0] = 0x02;
- regbuf[1] = 0x36;
- RN8302_WriteReg(IStart_Q,regbuf,2);
- //无功视在启动电流阈值
- regbuf[0] = 0x04;
- regbuf[1] = 0x00;
- RN8302_WriteReg(LostVoltT,regbuf,2);
- //无功视在启动电流阈值
- regbuf[0] = 0x00;
- regbuf[1] = 0x2C;
- RN8302_WriteReg(ZXOT,regbuf,2);
- //CF管脚配置
- regbuf[0] = 0x04;
- regbuf[1] = 0x77;
- regbuf[2] = 0x10;
- RN8302_WriteReg(CFCFG,regbuf,3);
- //计量单元配置寄存器
- regbuf[0] = 0x40;
- regbuf[1] = 0x00;
- regbuf[2] = 0x00;
- RN8302_WriteReg(EMUCFG,regbuf,3);
- //写缓存
- regbuf[0] = 0x10;
- RN8302_WriteReg(WSAVECON,regbuf,1);
- //三相四线
- regbuf[0] = 0x00;
- RN8302_WriteReg(MODESEL,regbuf,1);
- //计量控制位
- regbuf[0] = 0x77;regbuf[1] = 0x77;regbuf[2] = 0x77;
- RN8302_WriteReg(EMUCON,regbuf,3);
- //写保护
- regbuf[0] = 0xDC;
- RN8302_WriteReg(WREN,regbuf,1);
- }
- return status;
- }
复制代码
3---------------------------------------RN8302 校表部分-------------------------------------------------------------------------
(1)校表主要流程,详细流程可以参照用户手册
(2)RN8302校表初始化,这块参照手册,将RN8302的值设置成默认值
- /********************************************************
- 功能描述: RN8302校表初始化
- 参数说明:
- 返回说明:
- 调用方式:
- 全局变量:
- 读写时间:
- 注意事项:
- 日期 :
- ********************************************************/
- uint8_t RN8302_CalibrateInit(void)
- {
- uint8_t regbuf[4];
- uint8_t status = 1;
- if(RN8302_ReadReg(0x018F,regbuf,3) == 0){
- if((regbuf[0]==0x83)&&(regbuf[1]==0x02)&&(regbuf[2]==0x00)){
- status = 0;
- }
- else{
- status = 1;
- }
- }
- else{
- status = 1;
- }
- //deviceID读取成功
- if(status == 0){
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- //切换到EMM模式
- regbuf[0] = 0xA2;
- RN8302_WriteReg(WMSW,regbuf,1);
- //复位
- regbuf[0] = 0xFA;
- RN8302_WriteReg(SOFTRST,regbuf,1);
- TicksDelayMs(20);
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- //切换到EMM模式
- regbuf[0] = 0xA2;
- RN8302_WriteReg(WMSW,regbuf,1);
- //写HFCONST1
- regbuf[0] = 0x2E;
- regbuf[1] = 0xA1;
- RN8302_WriteReg(HFCONST1,regbuf,2);
- m_memset(regbuf,0,2);
- RN8302_ReadReg(HFCONST1,regbuf,2);
- //写电压增益
- StDef_RN8302Para_Reg.Cst_GSUx[0] = 0;
- StDef_RN8302Para_Reg.Cst_GSUx[1] = 0;
- StDef_RN8302Para_Reg.Cst_GSUx[2] = 0;
- RN8302_WriteReg(GSUA,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSUx[0],2);
- RN8302_WriteReg(GSUB,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSUx[1],2);
- RN8302_WriteReg(GSUC,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSUx[2],2);
- //写电流增益
- StDef_RN8302Para_Reg.Cst_GSIx[0] = 0;
- StDef_RN8302Para_Reg.Cst_GSIx[1] = 0;
- StDef_RN8302Para_Reg.Cst_GSIx[2] = 0;
- StDef_RN8302Para_Reg.Cst_GSIx[3] = 0;
- RN8302_WriteReg(GSIA,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSIx[0],2);
- RN8302_WriteReg(GSIB,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSIx[1],2);
- RN8302_WriteReg(GSIC,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSIx[2],2);
- RN8302_WriteReg(GSIN,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GSIx[3],2);
- //x相有功功率增益
- StDef_RN8302Para_Reg.Cst_GPx[0] = 0;
- StDef_RN8302Para_Reg.Cst_GPx[1] = 0;
- StDef_RN8302Para_Reg.Cst_GPx[2] = 0;
- RN8302_WriteReg(GPA,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GPx[0],2);
- RN8302_WriteReg(GPB,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GPx[1],2);
- RN8302_WriteReg(GPC,(uint8_t*)&StDef_RN8302Para_Reg.Cst_GPx[2],2);
- //x相有功分段相位校正
- StDef_RN8302Para_Reg.Cst_Px_PHSL[0] = 0;
- StDef_RN8302Para_Reg.Cst_Px_PHSL[1] = 0;
- StDef_RN8302Para_Reg.Cst_Px_PHSL[2] = 0;
- RN8302_WriteReg(PA_PHS,(uint8_t*)&StDef_RN8302Para_Reg.Cst_Px_PHSL[0],2);
- RN8302_WriteReg(PB_PHS,(uint8_t*)&StDef_RN8302Para_Reg.Cst_Px_PHSL[1],2);
- RN8302_WriteReg(PC_PHS,(uint8_t*)&StDef_RN8302Para_Reg.Cst_Px_PHSL[2],2);
- //x相无功分段相位校正
- StDef_RN8302Para_Reg.Cst_Qx_PHSL[0] = 0;
- StDef_RN8302Para_Reg.Cst_Qx_PHSL[1] = 0;
- StDef_RN8302Para_Reg.Cst_Qx_PHSL[2] = 0;
- RN8302_WriteReg(QA_PHS,(uint8_t*)&StDef_RN8302Para_Reg.Cst_Qx_PHSL[0],2);
- RN8302_WriteReg(QB_PHS,(uint8_t*)&StDef_RN8302Para_Reg.Cst_Qx_PHSL[1],2);
- RN8302_WriteReg(QC_PHS,(uint8_t*)&StDef_RN8302Para_Reg.Cst_Qx_PHSL[2],2);
- //电流offset
- regbuf[0] = 0;
- regbuf[1] = 0;
- RN8302_WriteReg(IA_OS,regbuf,2);
- regbuf[0] = 0;
- regbuf[1] = 0;
- RN8302_WriteReg(IB_OS,regbuf,2);
- regbuf[0] = 0;
- regbuf[1] = 0;
- RN8302_WriteReg(IC_OS,regbuf,2);
- //有功视在启动电流阈值
- regbuf[0] = 0x02;
- regbuf[1] = 0x36;
- RN8302_WriteReg(IStart_PS,regbuf,2);
- //无功视在启动电流阈值
- regbuf[0] = 0x02;
- regbuf[1] = 0x36;
- RN8302_WriteReg(IStart_Q,regbuf,2);
- //无功视在启动电流阈值
- regbuf[0] = 0x04;
- regbuf[1] = 0x00;
- RN8302_WriteReg(LostVoltT,regbuf,2);
- //无功视在启动电流阈值
- regbuf[0] = 0x00;
- regbuf[1] = 0x2C;
- RN8302_WriteReg(ZXOT,regbuf,2);
- //CF管脚配置
- regbuf[0] = 0x04;
- regbuf[1] = 0x32;
- regbuf[2] = 0x10;
- RN8302_WriteReg(CFCFG,regbuf,3);
- //计量单元配置寄存器
- regbuf[0] = 0x40;
- regbuf[1] = 0x00;
- regbuf[2] = 0x00;
- RN8302_WriteReg(EMUCFG,regbuf,3);
- m_memset(regbuf,0,3);
- RN8302_ReadReg(EMUCFG,regbuf,3);
- //计量控制位
- regbuf[0] = 0x00;regbuf[1] = 0x00;regbuf[2] = 0x77;
- RN8302_WriteReg(EMUCON,regbuf,3);
- //校表时不要写保护
- //regbuf[0] = 0xDC;
- //RN8302_WriteReg(WREN,regbuf,1);
- }
- return status;
- }
复制代码
(3)RN8302校表,电压、电流增益校准(校表台设置3相电压设置成220V,3相电流设置成5A)
- /********************************************************
- 功能描述: 功率法校正电压增益
- 参数说明: vol:扩大100倍
- 返回说明:
- 调用方式:
- 全局变量:
- 读写时间:
- 注意事项:
- 日期 :
- ********************************************************/
- uint16_t RN8302_CalibrateUGain(uint16_t vol,uint8_t phase)
- {
- uint8_t regbuf[5];
- const uint16_t regURMS[]={0x0007,0x0008,0x0009};
- const uint16_t regGUSx[]={GSUA,GSUB,GSUC};
- float err=0;
- uint16_t uGain;
- int32_t data;
- if(RN8302_ReadReg(regURMS[phase],regbuf,4)==0){
- data = BufToU32(regbuf);
- err = (data-44000000)*1.0/44000000;
- err = -err/(1+err);
- if(err > 0){
- uGain = (uint16_t)(err*32768);
- }
- else{
- uGain = (uint16_t)(err*32768+65536);
- }
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- regbuf[0] = uGain/256;regbuf[1] = uGain%256;
- RN8302_WriteReg(regGUSx[phase],regbuf,2);
- m_memset(regbuf,0x00,2);
- RN8302_ReadReg(regGUSx[phase],regbuf,2);
- StDef_RN8302Para_Reg.Cst_GSUx[phase] = uGain;
- }
- return uGain;
- }
复制代码- /********************************************************
- 功能描述: 功率法校准电流
- 参数说明:
- 返回说明:
- 调用方式:
- 全局变量:
- 读写时间:
- 注意事项:
- 日期 :
- ********************************************************/
- uint16_t RN8302_CalibrateIGain(uint16_t cur,uint8_t phase)
- {
- uint8_t regbuf[5];
- const uint16_t regIRMS[]={0x000B,0x000C,0x000D};
- const uint16_t regGISx[]={GSIA,GSIB,GSIC};
- float err=0;
- uint16_t iGain;
- int32_t data;
- if(RN8302_ReadReg(regIRMS[phase],regbuf,4)==0){
- data = BufToU32(regbuf);
- err = (data-3500000)*1.0/3500000;
- err = -err/(1+err);
- if(err > 0){
- iGain = (uint16_t)(err*32768);
- }
- else{
- iGain = (uint16_t)(err*32768+65536);
- }
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- regbuf[0] = iGain/256;regbuf[1] = iGain%256;
- RN8302_WriteReg(regGISx[phase],regbuf,2);
- m_memset(regbuf,0x00,2);
- RN8302_ReadReg(regGISx[phase],regbuf,2);
- StDef_RN8302Para_Reg.Cst_GSIx[phase] = iGain;
- }
- return iGain;
- }
复制代码
(4)RN8302校表,功率因素在1.0情况下可以不校准,只需通过校表台查看一下误差,误差较大的,再进行校准;正常情况下,电压、电流校准后,1.0无需校准
(5)RN8302校表,0.5L,A相校准,(校表台设置A相电压设置成220V,A相电流设置成5A,功率因素0.5L)
(6)RN8302校表,0.5L,B相校准,(校表台设置B相电压设置成220V,B相电流设置成5A,功率因素0.5L)
(7)RN8302校表,0.5L,C相校准,(校表台设置C相电压设置成220V,C相电流设置成5A,功率因素0.5L)
- /********************************************************
- 功能描述: 功率法校准 Un Ib 0.5增益
- 参数说明: err扩大1000倍 xx.xxx
- 返回说明:
- 调用方式:
- 全局变量:
- 读写时间:
- 注意事项:
- 日期 :
- ********************************************************/
- uint16_t RN8302_CalibratePx_PHSL(uint8_t phase)
- {
- uint8_t regbuf[5],i;
- uint32_t regtemp[5],regtotal=0;
- float err = 0;
- const uint16_t regGPx[]={PA_PHS,PB_PHS,PC_PHS};
- const uint16_t regGQx[]={QA_PHS,QB_PHS,QC_PHS};
- const uint16_t regArry[]={0x0014,0x0015,0x0016};
- uint16_t pGain;
- uint32_t data;
- for(i=0;i<5;i++){
- if(RN8302_ReadReg(regArry[phase],regbuf,4)==0){
- regtemp[i] = BufToU32(regbuf);
- regtotal += regtemp[i];
- }
- TicksDelayMs(400);
- }
- data = regtotal / 5;
- err = (data-9179115)*1.0/9179115;
- err = -err/(sqrt(3));
- if(err > 0){
- pGain = (uint16_t)(err*32768);
- }
- else{
- pGain = (uint16_t)(err*32768+65536);
- }
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- regbuf[0] = pGain/256;regbuf[1] = pGain%256;
- RN8302_WriteReg(regGPx[phase],regbuf,2);
- RN8302_WriteReg(regGQx[phase],regbuf,2);
- StDef_RN8302Para_Reg.Cst_Px_PHSL[phase] = pGain;
- StDef_RN8302Para_Reg.Cst_Qx_PHSL[phase] = pGain;
- return pGain;
- }
复制代码
(8)RN8302校表,电流offset校准,(校表台设置三相相电压设置成220V,三相电流设置成0A)
- /********************************************************
- 功能描述: 校准电流偏置
- 参数说明:
- 返回说明:
- 调用方式:
- 全局变量:
- 读写时间:
- 注意事项:
- 日期 :
- ********************************************************/
- uint8_t RN8302_CalibrateCurrentOffset(uint8_t phase)
- {
- uint8_t regbuf[5];
- uint32_t regtemp[10],regtotal=0;
- const uint16_t regArry[]={0x000B,0x000C,0x000D};
- const uint16_t regIx_OS[]={IA_OS,IB_OS,IC_OS};
- uint8_t i = 0;
- uint16_t temp;
- for(i=0;i<12;i++)
- {
- if(RN8302_ReadReg(regArry[phase],regbuf,4)==0){
- regtemp[i] = (regbuf[0]<<24)+(regbuf[1]<<16)+\
- (regbuf[2]<<8)+(regbuf[3]);
- }
- regtotal += regtemp[i];
- TicksDelayMs(300);
- }
- regtotal /= 12;
- regtotal = regtotal * regtotal;
- //求反码
- regtotal = ~regtotal;
- temp = (regtotal / 0x4000)&0xFFFF;
- //符号位
- if(regtotal & 0x80000000)
- temp |= 0x8000;
- //写使能
- regbuf[0] = 0xE5;
- RN8302_WriteReg(WREN,regbuf,1);
- regbuf[0] = temp/256;regbuf[1] = temp%256;
- RN8302_WriteReg(regIx_OS[phase],regbuf,2);
- StDef_RN8302Para_Reg.Cst_Ix_OS[phase] = temp;
- return 0;
- }
复制代码
(9)RN8302校表,电量清零
RN8302累计电量采用的是读后清零方式,所以累计电量是存在eeprom中的,只需要将eeprom中数据清空就可以,不用对RN8302进行操作
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|