接前一篇文章HLW8112芯片软件实现代码9二、寄存器介绍2. 详述1Init_HLW8112函数上一回继续结合官方例程讲解常用寄存器的细节。讲解了Init_HLW8112函数的第9段代码本回继续讲解该函数后续内容。为了便于理解和回顾再次贴出Init_HLW8112函数源码在HARDWARE\HLW8112-SPI\HLW8112-SPI.c中如下/* * Function : void Init_HLW8112(void) * Describe : 初始化8112 * Input : none * Output : none * Return : none * Record : 2018/05/09 */ void Init_HLW8112(void) { unsigned char a; // SPI init delay_ms(100); //STM32 IO init RCC-APB2ENR | 1 2; //使能PORTA时钟 RCC-APB2ENR | 5 6; //使能PORTD时钟 GPIOA-CRL 0X000F00FF; //IO状态设置设置PA7、PA6、PA5、PA3、PA2 GPIOA-CRL | 0X33308300; //IO状态设置PA7、PA6、PA5、PA2-输出、PA3-输入 //GPIOD-CRL 0XFFF00FFF; //IO状态设置,设置PD11、PD12 //GPIOD-CRL | 0X00088000; //IO状态设置PD11、PD12-输入 //STM32 IO init IO_HLW8112_EN 1; delay_ms(10); IO_HLW8112_CS HIGH; delay_us(2); delay_us(2); IO_HLW8112_SCLK LOW; delay_us(2); IO_HLW8112_SDI LOW; HLW8112_WriteREG_EN(); //打开写8112 Reg // ea 5a 电流通道A设置命令指定当前用于计算视在功率、功率因数、相角、 //瞬时有功功率、瞬时视在功率和有功功率过载的信号指示 的通道为通道A IO_HLW8112_CS LOW; HLW8112_SPI_WriteByte(0xea); HLW8112_SPI_WriteByte(0x5a); IO_HLW8112_CS HIGH; //写SYSCON REG, 关闭电流通道B电压通道 PGA 1电流通道A PGA 16; //三路通道满幅值峰峰值800ma,有效值/1.414 565mV IO_HLW8112_CS LOW; HLW8112_SPI_WriteReg(REG_SYSCON_ADDR); //HLW8112_SPI_WriteByte(0x0a); //开启电流通道A,PGA 16 ------高8bit HLW8112_SPI_WriteByte(0x0f); //开启电流通道A和电流通道B PGA 16;需要在EMUCON中关闭比较器------高8bit HLW8112_SPI_WriteByte(0x04); //-------------低8bit IO_HLW8112_CS HIGH; //写EMUCON REG, 使能A通道PF脉冲输出和有功能电能寄存器累加 IO_HLW8112_CS LOW; HLW8112_SPI_WriteReg(REG_EMUCON_ADDR); HLW8112_SPI_WriteByte(0x11); //最高位一定设置成0001关闭比较器,打开B通道 打开dcmode,和关闭高通 HLW8112_SPI_WriteByte(0x73); //打开A通道和B通道电量累计功能 IO_HLW8112_CS HIGH; //写EMUCON2 REG, 3.4HZ数据输出选择内部基准打开过压、过流等功能 //3.4HZ(300ms) 6.8HZ(150ms) 13.65HZ(75ms) 27.3HZ(37.5ms) IO_HLW8112_CS LOW; HLW8112_SPI_WriteReg(REG_EMUCON2_ADDR); HLW8112_SPI_WriteByte(0x0f); //电量寄存器读后不清 HLW8112_SPI_WriteByte(0xff); IO_HLW8112_CS HIGH; //关闭所有中断 IO_HLW8112_CS LOW; HLW8112_SPI_WriteReg(REG_IE_ADDR); HLW8112_SPI_WriteByte(0x00); HLW8112_SPI_WriteByte(0x00); IO_HLW8112_CS HIGH; HLW8112_WriteREG_DIS(); //关闭写8112 Reg //验证 REG_SYSCON_ADDR和REG_EMUCON_ADDR是否有写入 U16_RMSIAC_RegData Read_HLW8112_RegData(REG_SYSCON_ADDR, 2); U16_RMSIBC_RegData Read_HLW8112_RegData(REG_EMUCON2_ADDR, 2); printf(测试寄存器\r\n); printf(U16_RMSIAC_RegData %x\n ,U16_RMSIAC_RegData); printf(U16_RMSIBC_RegData %x\n ,U16_RMSIBC_RegData); printf(\r\n\r\n); // 读取RmsIAC、RmsIBC、RmsUC、PowerPAC、PowerPBC、PowerSC、EnergAc、EnergBc的值 U16_RMSIAC_RegData Read_HLW8112_RegData(REG_RMS_IAC_ADDR,2); //0xcad1 U16_RMSIBC_RegData Read_HLW8112_RegData(REG_RMS_IBC_ADDR,2); //0xcacf U16_RMSUC_RegData Read_HLW8112_RegData(REG_RMS_UC_ADDR,2); //0xa4c3 U16_PowerPAC_RegData Read_HLW8112_RegData(REG_POWER_PAC_ADDR,2); //0xab47 U16_PowerPBC_RegData Read_HLW8112_RegData(REG_POWER_PBC_ADDR,2); //0xab49 U16_PowerSC_RegData Read_HLW8112_RegData(REG_POWER_SC_ADDR,2); //0xab41 U16_EnergyAC_RegData Read_HLW8112_RegData(REG_ENERGY_AC_ADDR,2); //0xe9cc U16_EnergyBC_RegData Read_HLW8112_RegData(REG_ENERGY_BC_ADDR,2); //0xe9ce printf(系数寄存器\r\n); printf(U16_RMSIAC_RegData %x\n, U16_RMSIAC_RegData); printf(U16_RMSIBC_RegData %x\n, U16_RMSIBC_RegData); printf(U16_RMSUC_RegData %x\n , U16_RMSUC_RegData); printf(U16_PowerPAC_RegData %x\n, U16_PowerPAC_RegData); printf(U16_PowerPBC_RegData %x\n, U16_PowerPBC_RegData); printf(U16_PowerSC_RegData %x\n, U16_PowerSC_RegData); printf(U16_EnergyAC_RegData %x\n, U16_EnergyAC_RegData); printf(U16_EnergyBC_RegData %x\n, U16_EnergyBC_RegData); a Judge_CheckSum_HLW8112_Calfactor(); if (a 1) { printf(系数寄存器校验ok\r\n); } else { printf(系数寄存器校验fail\r\n); } }10验证校验和代码片段如下a Judge_CheckSum_HLW8112_Calfactor(); if (a 1) { printf(系数寄存器校验ok\r\n); } else { printf(系数寄存器校验fail\r\n); }Judge_CheckSum_HLW8112_Calfactor函数也在stm32-codetest\HARDWARE\HLW8112-SPI\HLW8112-SPI.c中代码如下/* * Function : void Judge_CheckSum_HLW8112_Calfactor(void) * Describe : 验证地址0x70-0x77地址的系数和 * Input : none * Output : none * Return : none * Record : 2019/03/18 */ unsigned char Judge_CheckSum_HLW8112_Calfactor(void) { unsigned long a; unsigned int b; unsigned int c; unsigned char d; // 读取RmsIAC、RmsIBC、RmsUC、PowerPAC、PowerPBC、PowerSC、EnergAc、EnergBc的值 U16_RMSIAC_RegData Read_HLW8112_RegData(REG_RMS_IAC_ADDR, 2); U16_RMSIBC_RegData Read_HLW8112_RegData(REG_RMS_IBC_ADDR, 2); U16_RMSUC_RegData Read_HLW8112_RegData(REG_RMS_UC_ADDR, 2); U16_PowerPAC_RegData Read_HLW8112_RegData(REG_POWER_PAC_ADDR, 2); U16_PowerPBC_RegData Read_HLW8112_RegData(REG_POWER_PBC_ADDR, 2); U16_PowerSC_RegData Read_HLW8112_RegData(REG_POWER_SC_ADDR, 2); U16_EnergyAC_RegData Read_HLW8112_RegData(REG_ENERGY_AC_ADDR, 2); U16_EnergyBC_RegData Read_HLW8112_RegData(REG_ENERGY_BC_ADDR, 2); b Read_HLW8112_RegData(REG_CHECKSUM_ADDR, 2); a 0; a ~(0xffffU16_RMSIAC_RegData U16_RMSIBC_RegData U16_RMSUC_RegData U16_PowerPAC_RegData U16_PowerPBC_RegData U16_PowerSC_RegData U16_EnergyAC_RegData U16_EnergyBC_RegData); c a 0xffff; if (c b) { d 1; } else { d 0; } return d; }Judge_CheckSum_HLW8112_Calfactor函数正如其名称就是验证HLW8112各个校正系数的校验和的。其实上一步已经得到了从REG_RMS_IAC_ADDR0x70到REG_ENERGY_BC_ADDR0x77的值了这里没必要再读一次。也许再读一次的原因是为了节省函数参数也可能是担心值会变化吧具体原因就不得而知了。总之读完那些寄存器之后将其值进行累加最后再与0xFFFF做累加完后再取反赋给变量a。同时直接读取REG_CHECKSUM_ADDR寄存器0x6F的内容赋给变量b。对a只保留低16位并赋给变量c。比较c与b是否相等。如果相等则返回1如果不相等则返回0。这其中的计算方法还是上一回芯片手册中的那个截图至此Init_HLW8112函数的代码就解析完了。下一回开始讲解后续步骤及函数。