RN8302b调试笔记

RN8302b调试笔记

艰难调试完毕,吐槽的话就不说了,只有个手册,官方应用笔记还不给,想想太窝火

无奈才某处花钱买了个官方应用笔记。。。。。

忽然发现,现在啥都要钱了,希望博客园的分享可以坚持下去!

 

1. 通讯接口

       别的不说了,既然PCB都做了,那就一个坑一个坑的来吧,这里不再赘述SPI的的接口以及通讯协议问题,这部分还都是靠谱的,按要求做就可以了。只要你读到IC的ID=0x830200,那就说明通讯接口调试完毕!

这里需要注意的是:RSTN引脚,必须处理!否则你会发现意想不到的惊喜!

通讯完成之后,我们可以读取寄存器了,这里强调一点,寄存器地址是分区的,通用的数据寄存器是BANK0,一些配置寄存器在BANK1,所以我们定义寄存器地址的时候,要有所区别。我习惯把他定义成十六位的,在写寄存器的函数里面,在处理一下,代码如下。

至于SPI的读写操作函数,不同的MCU不尽相同,不过大致都差不多,这里不再赘述了。

 1 static uint32_t
 2 bsp_rn8302_read_register(uint16_t Addr, uint8_t Length)
 3 {
 4     uint32_t Value = 0;
 5     uint8_t checksum = 0;
 6     uint8_t ucTemp;
 7 
 8     if (Length > 4) {
 9         Value = 0;
10     } else {
11         BSP_SPI_RN8302B_CS(0);
12         // AD[7:0]
13         bsp_spi_write_read((uint8_t)(Addr));
14         checksum += (uint8_t)(Addr);
15         // CMD[R/W-AD[10:8] BL[1:0] 00]
16         uint8_t cmd = (uint8_t)(((Addr>>8u)&0x07) << 4);
17         bsp_spi_write_read(cmd);
18         checksum += cmd;
19         // Read
20         for (uint8_t i=0u; i<Length; i++) {
21             ucTemp = bsp_spi_write_read(BSP_SPI_DUMMY_BYTE);
22             Value |= (uint32_t)ucTemp << (8*(Length-1u-i));
23             checksum += ucTemp;
24         }
25         // checksum
26         ucTemp = bsp_spi_write_read(BSP_SPI_DUMMY_BYTE);
27         if ((checksum|ucTemp) != 0xFF) {
28             Value = 0;
29             print("RN8302N<%s>: response checksum error\n", __FUNCTION__);
30         }
31         BSP_SPI_RN8302B_CS(1);
32     }
33     return Value;
34 }
 1 static void
 2 bsp_rn8302_write_register(uint16_t Addr, uint8_t Length, uint32_t Value)
 3 {
 4     uint8_t checksum = 0;
 5     uint8_t ucTemp;
 6     if (Length > 4) {
 7         return;
 8     }
 9 
10     BSP_SPI_RN8302B_CS(0);
11     // AD[7:0]
12     bsp_spi_write_read((uint8_t)(Addr));
13     checksum += (uint8_t)(Addr);
14     // CMD[R/W-AD[10:8] BL[1:0] 00]
15     uint8_t cmd = (uint8_t)((((Addr>>8u)&0x07) << 4) | 0x80);
16     bsp_spi_write_read(cmd);
17     checksum += cmd;
18     // DAT
19     for (uint8_t i=0u; i<Length; i++) {
20         ucTemp = (uint8_t)(Value >> (8u*(Length-1u-i)));
21         bsp_spi_write_read(ucTemp);
22         checksum += ucTemp;
23     }
24     // CHECKSUM
25     bsp_spi_write_read(~checksum);
26 
27     BSP_SPI_RN8302B_CS(1);
28 }

2. 电压、电流的转换

       可以读到寄存器的数值之后,我们要做的就是数据的处理,比如你读到了UA UB UC,你得转化为输入信号值啊,这个怎么转呢?也很头疼,因为手册他就没咋说!

       其实我们要先根据电路计算出电流、电压的转换系数,之后用码值来计算即可。先看一下基本的电压的输入电路:

 RN8302b调试笔记

如图,Un是我们输入的电压(比如:220V),Uv是ADC测量通道的输入值,根据已知电路,我们可以确定的是:

Uv = Un / 220K * (49.9*2),即:Un/Uv = 220000/99.8

电流的计算方式类似,电流的输入电路:

RN8302b调试笔记

       如图,Ib是我们输入的测量电流(比如:2A),Ui是ADC测量通道(电流通道)的输入值,我们同样可以确定:

     Ui = Ib / 2000 * (49.9*2):Ib/Ui = 2000/99.8

根据官方应用笔记的描述,我们先计算电压转换系数Kv:

  Kv = Un / (Uv / 0.8 * 227)

将上式转换:

  Kv = Un/Uv * 0.8/227

注:227是RMS寄存器的满码值,Un/Uv=220000/99.8是电路参数,使用时需要针对实际电路修改!

带入当前电路参数计算:Kv= 220000/99.8 * 0.8 / 227= 1.31393E-05

 

继续计算电流转换系数:

  Ki = Ib / (Ui / 0.8 * 227)

将上式转换:

  Ki = Ib/Ui * 0.8/227

注:227是RMS寄存器的满码值,Ib/Ui=2000/99.8是电路参数,使用时需要针对实际电路修改!

带入当前电路参数计算:Ki = 2000/99.8 * 0.8 / 227= 1.19448E-07

有了转换系数Kv、Ki,我们就可以计算出测量电流的实际值了,不过说实话,常温下读取的精度还是不错的。

3. 功率的转换

RN8302可以直接读取有功、无功、视在功率,三者的关系这里不再赘述,读取功率之前,我们先确认一下功率因数是否正常,功率因数的计算公式,手册中有明确给出,所以不是很麻烦。这里需要注意的是,采样通道的相位校准寄存器的默认值是: 0x80!有时候由于代码的移植问题,我们习惯性把该值设为0,这样会导致功率因数出错,此处需要注意!

功率的转换中,我们使用一个电表常数EC,通过他来计算HFConst,该值要写到HFCONST1、HFCONST2寄存器中。官方给的HFConst的计算公式:

HFConst = (Uv/0.8) * (Ui/0.8) * 3.6*106 * Fosc / (32*EC*Un*Ib)

转换一下:

HFConst = [3.6*106 * Fosc / (0.8*0.8*32)] * (Uv/Un) * (Ui/Ib) * (1/EC)

      此处暂时不计算该值,仅保留公式。

 

      下面转入正题,开始计算功率转换系数Kp,同样根据官方的公式:

      Kp = 3.6*106 * Fosc / (231 * 32 * HFConst * EC)

把HFConst带入,我们得到一个和EC无关的计算公式:

Kp = 3.6*106*Fosc/(231*32)*1/{[3.6*106*Fosc/(0.8*0.8*32)] * (Uv/Un) * (Ui/Ib) }

简化公式:

      Kp = (0.8 * 0.8 / 231) * Un/Uv * Ib/Ui

其中: 231为功率寄存器的满码值,Un/Uv=220000/99.8Ib/Ui=2000/99.8是电路参数。

带入当前电路的参数:

       Kp = 0.8 * 0.8 / 231 * (220000/99.8) * (2000/99.8) = 1.31656E-05

这样我们就得到了Kp的转换系数,功率寄存器的更新周期是250ms。

4. 电能的计算

在第3部分,我们提到了电表常数EC,以及通过电表常数计算的HFConst,用以设置HFCONST1、HFCONST2寄存器,不过我们之前的计算都和这个无关。在计算电能的时候,我们就要用到这个参数了。

HFConst = [3.6*106 * Fosc / (0.8*0.8*32)] * (Uv/Un) * (Ui/Ib) * (1/EC)

关于电能的计算,手册有说明,这里不再赘述。说明的是,我们要给定一个EC(比如:3200),以此来计算出HFConst的值,这里的EC选取要注意大小,太小了可能会导致HFConst的计算值超限,因为HFCONST寄存器是16bits的。

RN8302可以方便的读取各项电能累计,常用的比如:

  • 合相有功电能累计、合相正向有功电能累计、合相反向有功电能累计
  • 合相无功电能累计、合相正向无功电能累计、合相反向无功电能累计
  • RMS合相视在电能累计

有个上述寄存器的数值,除以EC值,就是我们要读取的电表度数了。

5. 电参的校准

RN8302的校准相对比较简单,在其数据手册和应用笔记上都给出了计算方法,利用功率校表,总结起来就是:

  •  设定标准源输入的电压、电流,PF=1.0
  •  根据输入值校准各相电压、电流的增益
  •  校准有功功率增益(无功、视在增益等于有功增益)
  •  设定PF0.5
  •  根据有功功率的误差,校正功率相位。

设定标准源输入为Ui、Ii,寄存器读到的码值Ux_REG、Ix_REG:

各相电压增益的计算如下,GSUx(x=A、B、C):

GSUx = Ui / (Ux_REG * Kv) – 1

  •  如果GSUx≥0,     GSUx = GSUx * 215
  •  如果GSUx<0,     GSUx = GSUx * 215 + 216

各相电流增益的计算如下,GSIx(x=A、B、C):

  •  GSIx = Ii / (Ix_REG * Ki) – 1
  •  如果GSIx≥0, GSIx = GSIx * 215
  •  如果GSIx<0, GSIx = GSIx * 215 + 216

各相功率增益的计算如下,GPx(x=A、B、C):

ErrP = (Px_REG * Kp) / (Ui * Ii * 1.0) – 1

GPx = ErrP / (1 + ErrP) * (-1)

  •  如果GPx≥0,  GPx = GPx * 215
  •  如果GPx<0,  GPx = GPx * 215 + 216

设定PF=0.5,各相功率相位,Px_PHSL(x=A、B、C):

ErrP = (Px_REG * Kp) / (Ui * Ii * 0.5) – 1

Px_PHSL = ErrP /  * (-1)

  •  如果Px_PHSL≥0,Px_PHSL = Px_PHSL * 215
  •  如果Px_PHSL<0, Px_PHSL = Px_PHSL * 215 + 216

 

后记:

简单测了一下 ,电能计量和基本测量都不错,价格也便宜,还是值得使用的。

有需要官方应用笔记的可以留下邮箱,我看到的话会发给您。

上一篇:通过Chainlink预言机构建参数化保险智能合约


下一篇:Codeforces Round #731 (Div. 3) 题解 (DEFG)