Hlw8110.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. /*=========================================================================================================
  2. * File Name : HLW8110.c
  3. * Describe : HLW8110 UART 通讯程序,使用USATR2.(HLW8110 code,use USATE2)
  4. * Author : Tuqiang
  5. * Version : V1.3
  6. * Record : 2019/04/16,V1.2
  7. * Record : 2020/04/02, V1.3
  8. ==========================================================================================================*/
  9. #include "Hlw8110.h"
  10. #include "stdio.h"
  11. #include "Config.h"
  12. #include "SysTick.h"
  13. #include "Uart1.h"
  14. #include "Timer.h"
  15. #if HLW8110
  16. #define HIGH 1
  17. #define LOW 0
  18. /*---------------------------------------------------------------------------------------------------------*/
  19. /*---------------------------------------------------------------------------------------------------------*/
  20. /*---------------------------------------------------------------------------------------------------------*/
  21. /*---------------------------------------------------------------------------------------------------------*/
  22. union IntData
  23. {
  24. unsigned int inte;
  25. unsigned char byte[2];
  26. };
  27. union LongData
  28. {
  29. unsigned long int word;
  30. unsigned int inte[2];
  31. unsigned char byte[4];
  32. };
  33. /*---------------------------------------------------------------------------------------------------------*/
  34. /*---------------------------------------------------------------------------------------------------------*/
  35. unsigned char u8_TxBuf[10];
  36. unsigned char u8_RxBuf[10];
  37. unsigned char u8_TX_Length;
  38. unsigned char u8_RX_Length;
  39. unsigned char u8_RX_Index;
  40. //unsigned char B_ReadReg_Time_EN; // 串口读取寄存器数据,时间计数器标志位,1--开启计数,0--关闭计数
  41. //unsigned char B_Tx_Finish;
  42. unsigned char B_Rx_Finish;
  43. unsigned char B_Rx_Data_ING; // 接收数据标志位 , < 1:接收数据中,0:未接收到数据 >
  44. unsigned char B_Read_Error; // UART读取出据校验和出错,< 1:数据读错,0:数据读取正确 >
  45. //unsigned char u8_ReadReg_Index;
  46. //unsigned char u8_ReadReg_Time; // 串口读取寄存器数据的时间
  47. /*---------------------------------------------------------------------------------------------------------*/
  48. /*---------------------------------------------------------------------------------------------------------*/
  49. unsigned int U16_TempData;
  50. unsigned int U16_IFData;
  51. unsigned int U16_RIFData;
  52. unsigned int U16_LineFData;
  53. unsigned int U16_AngleData;
  54. unsigned int U16_PFData;
  55. unsigned int U16_HFConst_RegData;
  56. /*---------------------------------------------------------------------------------------------------------*/
  57. /*---------------------------------------------------------------------------------------------------------*/
  58. unsigned int U16_RMSIAC_RegData; // A通道电流转换系数
  59. unsigned int U16_RMSIBC_RegData; // B通道电流转换系数
  60. unsigned int U16_RMSUC_RegData; // 电压通道转换系数
  61. unsigned int U16_PowerPAC_RegData; // A通道功率转换系数
  62. unsigned int U16_PowerPBC_RegData; // B通道功率转换系数
  63. unsigned int U16_PowerSC_RegData; // 视在功率转换系数,如果选择A通道,则是A通道视在功率转换系数。A和B通道只能二者选其一
  64. unsigned int U16_EnergyAC_RegData; // A通道有功电能(量)转换系数
  65. unsigned int U16_EnergyBC_RegData; // A通道有功电能(量)转换系数
  66. unsigned int U16_CheckSUM_RegData; // 转换系数的CheckSum
  67. unsigned int U16_CheckSUM_Data; // 转换系数计算出来的CheckSum
  68. unsigned int U16_Check_SysconReg_Data;
  69. unsigned int U16_Check_EmuconReg_Data;
  70. unsigned int U16_Check_Emucon2Reg_Data;
  71. /*---------------------------------------------------------------------------------------------------------*/
  72. /*---------------------------------------------------------------------------------------------------------*/
  73. unsigned long U32_RMSIA_RegData; // A通道电流有效值寄存器
  74. unsigned long U32_RMSU_RegData; // 电压有效值寄存器
  75. unsigned long U32_POWERPA_RegData; // A通道功率有效值寄存器
  76. unsigned long U32_ENERGY_PA_RegData; // A通道有功电能(量)有效值寄存器
  77. unsigned long U32_RMSIB_RegData; // B通道电流有效值寄存器
  78. unsigned long U32_POWERPB_RegData; // B通道功率有效值寄存器
  79. unsigned long U32_ENERGY_PB_RegData; // B通道有功电能(量)有效值寄存器
  80. /*---------------------------------------------------------------------------------------------------------*/
  81. /*---------------------------------------------------------------------------------------------------------*/
  82. float F_AC_V; // 电压有效值
  83. float F_AC_I; // A通道电流
  84. float F_AC_P; // A通道有功功率
  85. float F_AC_E; // A通道有功电能(量)
  86. float F_AC_BACKUP_E; // A通道电量备份
  87. float F_AC_PF; // 功率因素,A通道和B通道只能选其一
  88. float F_Angle; // 相角,A通道和B通道只能选其一
  89. float F_AC_I_B; // B通道电流有效值
  90. float F_AC_P_B; // B通道有功功率
  91. float F_AC_E_B; // B通道有功电能(量)
  92. float F_AC_BACKUP_E_B; // B通道电量备份
  93. float F_AC_LINE_Freq; // 市电线性频率
  94. /*---------------------------------------------------------------------------------------------------------*/
  95. /*---------------------------------------------------------------------------------------------------------*/
  96. /*---------------------------------------------------------------------------------------------------------*/
  97. /*---------------------------------------------------------------------------------------------------------*/
  98. /*=========================================================================================================
  99. * Function : void Clear_RxBuf(void)
  100. * Describe : 在准备接收串口数据前,清空接收缓存器的数据
  101. * Input : none
  102. * Output : none
  103. * Return : none
  104. * Record : 2019/04/03
  105. =========================================================================================================*/
  106. void Clear_RxBuf(void)
  107. {
  108. unsigned char i;
  109. for(i = 0;i<10;i++)
  110. {
  111. u8_RxBuf[i] = 0x00;
  112. }
  113. B_Rx_Data_ING = 0;
  114. B_Rx_Finish = FALSE;
  115. u8_RX_Index = 0;
  116. }
  117. /*=========================================================================================================
  118. * Function : unsigned char HLW8110_checkSum_Write(unsigned char u8_Reg_length)
  119. * Describe :
  120. * Input : none
  121. * Output : none
  122. * Return : none
  123. * Record : 2019/04/03
  124. =========================================================================================================*/
  125. unsigned char HLW8110_checkSum_Write(unsigned char u8_Reg_length)
  126. {
  127. unsigned char i;
  128. unsigned char Temp_u8_checksum;
  129. unsigned int a;
  130. a = 0x0000;
  131. Temp_u8_checksum = 0;
  132. for (i = 0; i< (u8_Reg_length-1); i++)
  133. {
  134. a += u8_TxBuf[i];
  135. }
  136. a = ~a;
  137. Temp_u8_checksum = a & 0xff;
  138. return Temp_u8_checksum;
  139. }
  140. /*=========================================================================================================
  141. * Function : unsigned char HLW8110_checkSum_Read(void)
  142. * Describe :
  143. * Input : none
  144. * Output : none
  145. * Return : none
  146. * Record : 2019/04/03
  147. ==========================================================================================================*/
  148. unsigned char HLW8110_checkSum_Read(unsigned char u8_Reg_length)
  149. {
  150. unsigned char i;
  151. unsigned char Temp_u8_checksum;
  152. unsigned int a;
  153. a = 0x0000;
  154. Temp_u8_checksum = 0;
  155. for (i = 0; i< (u8_Reg_length-1); i++)
  156. {
  157. a += u8_RxBuf[i];
  158. }
  159. a = a + u8_TxBuf[0] + u8_TxBuf[1];
  160. a = ~a;
  161. Temp_u8_checksum = a & 0xff;
  162. return Temp_u8_checksum;
  163. }
  164. /*=========================================================================================================
  165. * Function : void Uart_HLW8110_WriteREG_EN(void)
  166. * Describe :
  167. * Input : none
  168. * Output : none
  169. * Return : none
  170. * Record : 2019/04/03
  171. ==========================================================================================================*/
  172. void Uart_HLW8110_WriteREG_EN(void)
  173. {
  174. u8_TX_Length = 4;
  175. u8_RX_Length = 0;
  176. u8_TxBuf[0] = 0xa5;
  177. u8_TxBuf[1] = 0xea;
  178. u8_TxBuf[2] = 0xe5;
  179. // u8_TxBuf[3] = 0x8b; //checksum
  180. u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);
  181. Start_Send_UartData(u8_TX_Length);
  182. }
  183. /*=========================================================================================================
  184. * Function : void Uart_HLW8110_WriteREG_DIS(void)
  185. * Describe :
  186. * Input : none
  187. * Output : none
  188. * Return : none
  189. * Record : 2019/04/03
  190. ==========================================================================================================*/
  191. void Uart_HLW8110_WriteREG_DIS(void)
  192. {
  193. u8_TX_Length = 4;
  194. u8_RX_Length = 0;
  195. u8_TxBuf[0] = 0xa5;
  196. u8_TxBuf[1] = 0xea;
  197. u8_TxBuf[2] = 0xdc;
  198. // u8_TxBuf[3] = 0x94; //checksum
  199. u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);
  200. Start_Send_UartData(u8_TX_Length);
  201. }
  202. /*=========================================================================================================
  203. * Function : void Uart_HLW8110_Set_Channel_A(void)
  204. * Describe :
  205. * Input : none
  206. * Output : none
  207. * Return : none
  208. * Record : 2019/04/03
  209. ==========================================================================================================*/
  210. void Uart_HLW8110_Set_Channel_A(void)
  211. {
  212. u8_TX_Length = 4;
  213. u8_RX_Length = 0;
  214. u8_TxBuf[0] = 0xa5;
  215. u8_TxBuf[1] = 0xea;
  216. u8_TxBuf[2] = 0x5a;
  217. // u8_TxBuf[3] = 0x16; //checksum
  218. u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);
  219. Start_Send_UartData(u8_TX_Length);
  220. }
  221. /*=========================================================================================================
  222. * Function : void Uart_Read_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length)
  223. * Describe :
  224. * Input :
  225. * Output :
  226. * Return :
  227. * Record : 2019/04/04
  228. ==========================================================================================================*/
  229. void Uart_Read_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length)
  230. {
  231. u8_TxBuf[0] = 0xa5;
  232. u8_TxBuf[1] = ADDR_Reg;
  233. u8_TX_Length = 2;
  234. u8_RX_Length = u8_reg_length + 1; // +1,是因为接收的数据长度,除了REG值,还有一个校验和数据
  235. Clear_RxBuf(); //清空接收缓冲区
  236. Start_Send_UartData(u8_TX_Length);
  237. }
  238. /*=========================================================================================================
  239. * Function : void Uart_Write_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length,unsigned long u32_data)
  240. * Describe : 写寄存器命令,u8_reg_length:写入的寄存器数据字节长度
  241. * Input :
  242. * Output :
  243. * Return :
  244. * Record : 2019/04/03
  245. ==========================================================================================================*/
  246. void Uart_Write_HLW8110_Reg(unsigned char ADDR_Reg,unsigned char u8_reg_length,unsigned long u32_data)
  247. {
  248. unsigned char i;
  249. union LongData Temp_u32_a;
  250. u8_TxBuf[0] = 0xa5;
  251. u8_TxBuf[1] = ADDR_Reg|0x80;
  252. Temp_u32_a.word = u32_data;
  253. for (i = 0; i< u8_reg_length; i++)
  254. {
  255. u8_TxBuf[i+2] = Temp_u32_a.byte[u8_reg_length-1-i]; //STM32,32位MCU,union定义,是低位在前
  256. //u8_TxBuf[i+2] = Temp_u32_a.byte[4-u8_reg_length + i]; //STM8,STC MCU, union定义,是高位在前
  257. }
  258. u8_TX_Length = 3 + u8_reg_length ;
  259. u8_RX_Length = 0;
  260. u8_TxBuf[u8_TX_Length-1] = HLW8110_checkSum_Write(u8_TX_Length);
  261. Start_Send_UartData(u8_TX_Length);
  262. }
  263. /*=========================================================================================================
  264. * Function : void Uart_HLW8110_Reset(void)
  265. * Describe :
  266. * Input : none
  267. * Output : none
  268. * Return : none
  269. * Record : 2019/04/03
  270. ==========================================================================================================*/
  271. void Uart_HLW8110_Reset(void)
  272. {
  273. u8_TX_Length = 4;
  274. u8_RX_Length = 0;
  275. u8_TxBuf[0] = 0xa5;
  276. u8_TxBuf[1] = 0xea;
  277. u8_TxBuf[2] = 0x96;
  278. // u8_TxBuf[3] = 0xda; //checksum
  279. u8_TxBuf[3] = HLW8110_checkSum_Write(u8_TX_Length);
  280. Start_Send_UartData(u8_TX_Length);
  281. }
  282. /*=========================================================================================================
  283. * Function : void Judge_CheckSum_HLW8110_Calfactor(void)
  284. * Describe : 验证地址0x70-0x77地址的系数和
  285. * Input : none
  286. * Output : none
  287. * Return : none
  288. * Record : 2019/03/18
  289. ==========================================================================================================*/
  290. unsigned char Judge_CheckSum_HLW8110_Calfactor(void)
  291. {
  292. unsigned long a;
  293. //unsigned int b;
  294. //unsigned int c;
  295. unsigned char d;
  296. //读取RmsIAC、RmsIBC、RmsUC、PowerPAC、PowerPBC、PowerSC、EnergAc、EnergBc的值
  297. Uart_Read_HLW8110_Reg(REG_RMS_IAC_ADDR,2);
  298. DelayNms(50);
  299. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  300. {
  301. U16_RMSIAC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  302. // printf("A通道电流转换系数:%x\n " ,U16_RMSIAC_RegData);
  303. }
  304. Uart_Read_HLW8110_Reg(REG_RMS_IBC_ADDR,2);
  305. DelayNms(50);
  306. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  307. {
  308. U16_RMSIBC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  309. // printf("B通道电流转换系数:%x\n " ,U16_RMSIBC_RegData);
  310. }
  311. Uart_Read_HLW8110_Reg(REG_RMS_UC_ADDR,2);
  312. DelayNms(50);
  313. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  314. {
  315. U16_RMSUC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  316. // printf("电压通道转换系数:%x\n " ,U16_RMSUC_RegData);
  317. }
  318. Uart_Read_HLW8110_Reg(REG_POWER_PAC_ADDR,2);
  319. DelayNms(50);
  320. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  321. {
  322. U16_PowerPAC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  323. // printf("A通道功率转换系数:%x\n " ,U16_PowerPAC_RegData);
  324. }
  325. Uart_Read_HLW8110_Reg(REG_POWER_PBC_ADDR,2);
  326. DelayNms(50);
  327. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  328. {
  329. U16_PowerPBC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  330. // printf("B通道功率转换系数:%x\n " ,U16_PowerPAC_RegData);
  331. }
  332. Uart_Read_HLW8110_Reg(REG_POWER_SC_ADDR,2);
  333. DelayNms(50);
  334. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  335. {
  336. U16_PowerSC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  337. // printf("视在功率转换系数:%x\n " ,U16_PowerSC_RegData);
  338. }
  339. Uart_Read_HLW8110_Reg(REG_ENERGY_AC_ADDR,2);
  340. DelayNms(50);
  341. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  342. {
  343. U16_EnergyAC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  344. // printf("A通道电量转换系数:%x\n " ,U16_EnergyAC_RegData);
  345. }
  346. Uart_Read_HLW8110_Reg(REG_ENERGY_BC_ADDR,2);
  347. DelayNms(50);
  348. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  349. {
  350. U16_EnergyBC_RegData = (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  351. // printf("B通道电量转换系数:%x\n " ,U16_EnergyBC_RegData);
  352. }
  353. Uart_Read_HLW8110_Reg(REG_CHECKSUM_ADDR,2);
  354. DelayNms(50);
  355. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  356. {
  357. U16_CheckSUM_RegData= (u8_RxBuf[0]<<8) + u8_RxBuf[1] ;
  358. // printf("系数校验和:%x\n " ,U16_CheckSUM_RegData);
  359. }
  360. a = 0;
  361. a = ~(0xffff+U16_RMSIAC_RegData + U16_RMSIBC_RegData + U16_RMSUC_RegData +
  362. U16_PowerPAC_RegData + U16_PowerPBC_RegData + U16_PowerSC_RegData +
  363. U16_EnergyAC_RegData + U16_EnergyBC_RegData );
  364. U16_CheckSUM_Data = a & 0xffff;
  365. // printf("计算系数校验和:%x\n " ,U16_CheckSUM_Data);
  366. if ( U16_CheckSUM_Data == U16_CheckSUM_RegData)
  367. {
  368. d = 1;
  369. // printf("校验和正确\r\n ");
  370. }
  371. else
  372. {
  373. d = 0;
  374. // printf("校验和出错\r\n ");
  375. }
  376. return d;
  377. }
  378. /*=========================================================================================================
  379. * Function : void Init_HLW8110(void)
  380. * Describe :
  381. * Input : none
  382. * Output : none
  383. * Return : none
  384. * Record : 2019/04/03
  385. ==========================================================================================================*/
  386. void Init_HLW8110(void)
  387. {
  388. Uart_HLW8110_WriteREG_EN();
  389. DelayNms(10);
  390. //电流通道A设置命令,指定当前用于计算视在功率、功率因数、相角、瞬时有功功率、瞬时视在功率和有功功率过载的信号指示 的通道为通道A
  391. Uart_HLW8110_Set_Channel_A();
  392. DelayNms(10);
  393. Uart_Write_HLW8110_Reg(REG_SYSCON_ADDR,2,0x0a04); //开启A通道,关闭B通道,电压通道PGA = 1,电流通道PGA = 16
  394. DelayNms(10);
  395. Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,0x0001); //1,使能PFA 脉冲输出和有功电能寄存器累加;
  396. // Uart_Write_HLW8110_Reg(REG_EMUCON_ADDR,2,0x0018); //正向和负向过零点均发生变化,ZXD0 = 1,ZXD1 = 1
  397. Uart_Write_HLW8110_Reg(REG_EMUCON2_ADDR,2,0x0065); //0x0001是EMUCON2的默认值,waveEn = 1,zxEn = 1,A通道电量寄存器,读后不清0,EPA_CB = 1;打开功率因素检测
  398. DelayNms(10);
  399. Uart_HLW8110_WriteREG_DIS();
  400. // DelayNms(3);
  401. //读取地址是0x6F至0x77的寄存器,验证系数是否正确
  402. Judge_CheckSum_HLW8110_Calfactor();
  403. }
  404. /*=========================================================================================================
  405. * Function : void Check_WriteReg_Success(void)
  406. * Describe : 检验写入的REG是否正确写入
  407. * Input : none
  408. * Output : none
  409. * Return : none
  410. * Record : 2020/04/02
  411. ==========================================================================================================*/
  412. void Check_WriteReg_Success(void)
  413. {
  414. Uart_Read_HLW8110_Reg(REG_SYSCON_ADDR,2);
  415. DelayNms(10);
  416. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  417. {
  418. U16_Check_SysconReg_Data = (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
  419. // printf("写入的SysconReg寄存器:%lx\n " ,U16_Check_SysconReg_Data);
  420. }
  421. else
  422. {
  423. // printf("SysconReg寄存器读取出错\r\n");
  424. B_Read_Error = 1;
  425. }
  426. Uart_Read_HLW8110_Reg(REG_EMUCON_ADDR,2);
  427. DelayNms(10);
  428. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  429. {
  430. U16_Check_EmuconReg_Data = (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
  431. // printf("写入的EmuconReg寄存器:%lx\n " ,U16_Check_EmuconReg_Data);
  432. }
  433. else
  434. {
  435. // printf("EmuconReg寄存器读取出错\r\n");
  436. B_Read_Error = 1;
  437. }
  438. Uart_Read_HLW8110_Reg(REG_EMUCON2_ADDR,2);
  439. DelayNms(10);
  440. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  441. {
  442. U16_Check_Emucon2Reg_Data = (u8_RxBuf[0]<<8) + (u8_RxBuf[1]);
  443. // printf("写入的Emucon2Reg寄存器寄存器:%lx\n " ,U16_Check_Emucon2Reg_Data);
  444. }
  445. else
  446. {
  447. // printf("Emucon2Reg寄存器读取出错\r\n");
  448. B_Read_Error = 1;
  449. }
  450. }
  451. /*=========================================================================================================
  452. * Function : void Read_HLW8112_IA(void)
  453. * Describe : 读取A通道电流
  454. * Input : none
  455. * Output : none
  456. * Return : none
  457. * Record : 2019/04/03
  458. ==========================================================================================================*/
  459. void Read_HLW8110_IA(void)
  460. {
  461. float a;
  462. Uart_Read_HLW8110_Reg(REG_RMSIA_ADDR,3);
  463. DelayNms(10);
  464. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  465. {
  466. U32_RMSIA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
  467. // printf("A通道电流寄存器:%lx\n " ,U32_RMSIA_RegData);
  468. }
  469. else
  470. {
  471. // printf("A通道电流寄存器读取出错\r\n");
  472. B_Read_Error = 1;
  473. }
  474. //A通道电流PGA = 16,电压通道PGA = 1;电流采样电阻1mR,电压采样电阻1M
  475. //计算公式,U16_AC_I = (U32_RMSIA_RegData * U16_RMSIAC_RegData)/(电流系数* 2^23)
  476. if ((U32_RMSIA_RegData & 0x800000) == 0x800000)
  477. {
  478. F_AC_I = 0;
  479. }
  480. else
  481. {
  482. a = (float)U32_RMSIA_RegData;
  483. a = a * U16_RMSIAC_RegData;
  484. a = a/0x800000; //电流计算出来的浮点数单位是mA,比如5003.12
  485. a = a/1; // 1 = 电流系数
  486. a = a/1000; //a= 5003ma,a/1000 = 5.003A,单位转换成A
  487. a = a * D_CAL_A_I; //D_CAL_A_I是校正系数,默认是1
  488. F_AC_I = a;
  489. }
  490. }
  491. /*=========================================================================================================
  492. * Function : void Read_HLW8110_U(void)
  493. * Describe : 读取电压
  494. * Input : none
  495. * Output : none
  496. * Return : none
  497. * Record : 2019/04/03
  498. ==========================================================================================================*/
  499. void Read_HLW8110_U(void)
  500. {
  501. float a;
  502. Uart_Read_HLW8110_Reg(REG_RMSU_ADDR,3);
  503. DelayNms(10);
  504. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  505. {
  506. U32_RMSU_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
  507. // printf("电压通道寄存器:%lx\n " ,U32_RMSU_RegData);
  508. }
  509. else
  510. {
  511. // printf("电压通道寄存器读取出错\r\n");
  512. B_Read_Error = 1;
  513. }
  514. //电压
  515. //计算:U16_AC_V = (U32_RMSU_RegData * U16_RMSUC_RegData)/2^23
  516. if ((U32_RMSU_RegData &0x800000) == 0x800000)
  517. {
  518. F_AC_V = 0;
  519. }
  520. else
  521. {
  522. a = (float)U32_RMSU_RegData;
  523. a = a*U16_RMSUC_RegData;
  524. a = a/0x400000;
  525. a = a/1; // 1 = 电压系数
  526. a = a/100; //计算出a = 22083.12mV,a/100表示220.8312V,电压转换成V
  527. a = a*D_CAL_U; //D_CAL_U是校正系数,默认是1,
  528. F_AC_V = a;
  529. }
  530. }
  531. /*=========================================================================================================
  532. * Function : void Read_HLW8110_PA(void)
  533. * Describe : 读取A通道功率
  534. * Input : none
  535. * Output : none
  536. * Return : none
  537. * Record : 2019/04/03
  538. ==========================================================================================================*/
  539. void Read_HLW8110_PA(void)
  540. {
  541. float a;
  542. float b;
  543. Uart_Read_HLW8110_Reg(REG_POWER_PA_ADDR,4);
  544. DelayNms(10);
  545. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  546. {
  547. U32_POWERPA_RegData = (unsigned long)(u8_RxBuf[0]<<24) + (unsigned long)(u8_RxBuf[1]<<16) + (unsigned long)(u8_RxBuf[2]<<8) + (unsigned long)(u8_RxBuf[3]);
  548. // printf("A通道功率寄存器:%lx\n " ,U32_POWERPA_RegData);
  549. }
  550. else
  551. {
  552. // printf("A通道功率寄存器读取出错\r\n");
  553. B_Read_Error = 1;
  554. }
  555. if (U32_POWERPA_RegData > 0x80000000)
  556. {
  557. b = ~U32_POWERPA_RegData;
  558. a = (float)b;
  559. }
  560. else
  561. a = (float)U32_POWERPA_RegData;
  562. //功率需要分正功和负功
  563. //计算,U16_AC_P = (U32_POWERPA_RegData * U16_PowerPAC_RegData)/(2^31*电压系数*电流系数)
  564. //单位为W,比如算出来5000.123,表示5000.123W
  565. a = a*U16_PowerPAC_RegData;
  566. a = a/0x80000000;
  567. a = a/1; // 1 = 电流系数
  568. a = a/1; // 1 = 电压系数
  569. a = a * D_CAL_A_P; //D_CAL_A_P是校正系数,默认是1
  570. F_AC_P = a; //单位为W,比如算出来5000.123,表示5000.123W
  571. }
  572. /*=========================================================================================================
  573. * Function : void void Read_HLW8112_EA(void)
  574. * Describe : 读取A通道有功电量
  575. * Input : none
  576. * Output : none
  577. * Return : none
  578. * Record : 2019/04/03
  579. ==========================================================================================================*/
  580. void Read_HLW8110_EA(void)
  581. {
  582. float a;
  583. Uart_Read_HLW8110_Reg(REG_ENERGY_PA_ADDR,3);
  584. DelayNms(10);
  585. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  586. {
  587. U32_ENERGY_PA_RegData = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
  588. // printf("A通道有功电量寄存器:%lx\n " ,U32_ENERGY_PA_RegData);
  589. }
  590. else
  591. {
  592. // printf("A通道有功电量寄存器读取出错\r\n");
  593. B_Read_Error = 1;
  594. }
  595. Uart_Read_HLW8110_Reg(REG_HFCONST_ADDR,2);
  596. DelayNms(10);
  597. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  598. {
  599. U16_HFConst_RegData = (unsigned int)(u8_RxBuf[0]<<8) + (unsigned int)(u8_RxBuf[1]);
  600. // printf("HFCONST常数 = :%d\n " ,U16_HFConst_RegData);
  601. }
  602. else
  603. {
  604. // printf("HFCONST常数寄存器读取出错\r\n");
  605. B_Read_Error = 1;
  606. }
  607. //电量计算,电量 = (U32_ENERGY_PA_RegData * U16_EnergyAC_RegData * HFCONST) /(K1*K2 * 2^29 * 4096)
  608. //HFCONST:默认值是0x1000, HFCONST/(2^29 * 4096) = 0x20000000
  609. a = (float)U32_ENERGY_PA_RegData;
  610. a = a*U16_EnergyAC_RegData;
  611. a = a/0x20000000; //电量单位是0.001KWH,比如算出来是2.002,表示2.002KWH
  612. a = a/1; // 1 = 电流系数
  613. a = a/1; // 1 = 电压系数
  614. a = a * D_CAL_A_E; //D_CAL_A_E是校正系数,默认是1
  615. F_AC_E = a;
  616. F_AC_BACKUP_E = F_AC_E;
  617. }
  618. /*=========================================================================================================
  619. * Function : void Read_HLW8110_LineFreq(void)
  620. * Describe : 读取A通道的线性频率
  621. * Input : none
  622. * Output : none
  623. * Return : none
  624. * Record : 2019/04/12
  625. ==========================================================================================================*/
  626. void Read_HLW8110_LineFreq(void)
  627. {
  628. float a;
  629. unsigned long b;
  630. Uart_Read_HLW8110_Reg(REG_UFREQ_ADDR,2);
  631. DelayNms(10);
  632. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  633. {
  634. b = (unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
  635. // printf("A通道线性频率寄存器:%ld\n " ,b);
  636. }
  637. else
  638. {
  639. // printf("A通道线性频率寄存器读取出错\r\n");
  640. B_Read_Error = 1;
  641. }
  642. if(b!=0)
  643. {
  644. a = (float)b;
  645. a = 3579545/(8*a);
  646. F_AC_LINE_Freq = a;
  647. }
  648. }
  649. /*=========================================================================================================
  650. * Function : void Read_HLW8110_PF(void)
  651. * Describe : 读取功率因素
  652. * Input : none
  653. * Output : none
  654. * Return : none
  655. * Record : 2019/03/18
  656. ==========================================================================================================*/
  657. void Read_HLW8110_PF(void)
  658. {
  659. float a;
  660. unsigned long b;
  661. //测量A通道的功率因素,需要发送EA+5A命令
  662. //测量B通道的功率因素,需要发送EA+A5命令
  663. Uart_Read_HLW8110_Reg(REG_PF_ADDR,3);
  664. DelayNms(10);
  665. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  666. {
  667. b = (unsigned long)(u8_RxBuf[0]<<16) + (unsigned long)(u8_RxBuf[1]<<8) + (unsigned long)(u8_RxBuf[2]);
  668. // printf("A通道功率因素寄存器:%ld\n " ,b);
  669. }
  670. else
  671. {
  672. // printf("读取A通道功率因素寄存器出错\r\n");
  673. B_Read_Error = 1;
  674. }
  675. if (b>0x800000) //为负,容性负载
  676. {
  677. a = (float)(0xffffff-b + 1)/0x7fffff;
  678. }
  679. else
  680. {
  681. a = (float)b/0x7fffff;
  682. }
  683. if (F_AC_P < 0.3) // 小于0.3W,空载或小功率,PF不准
  684. a = 0;
  685. //功率因素*100,最大为100,最小负100
  686. F_AC_PF = a;
  687. }
  688. /*=========================================================================================================
  689. * Function : void Read_HLW8110_Angle(void)
  690. * Describe : 读取相位角
  691. * Input : none
  692. * Output : none
  693. * Return : none
  694. * Record : 2019/04/12
  695. ==========================================================================================================*/
  696. void Read_HLW8110_Angle(void)
  697. {
  698. float a;
  699. unsigned long b;
  700. Uart_Read_HLW8110_Reg(REG_ANGLE_ADDR,2);
  701. DelayNms(10);
  702. if ( u8_RxBuf[u8_RX_Length-1] == HLW8110_checkSum_Read(u8_RX_Length) )
  703. {
  704. b =(unsigned long)(u8_RxBuf[0]<<8) + (unsigned long)(u8_RxBuf[1]);
  705. // printf("A通道线相角寄存器:%ld\n " ,b);
  706. }
  707. else
  708. {
  709. // printf("A通道线相角寄存器出错\r\n");
  710. B_Read_Error = 1;
  711. }
  712. if ( F_AC_PF < 55) //线性频率50HZ
  713. {
  714. a = b;
  715. a = a * 0.0805;
  716. F_Angle = a;
  717. }
  718. else
  719. {
  720. //线性频率60HZ
  721. a = b;
  722. a = a * 0.0965;
  723. F_Angle = a;
  724. }
  725. if (F_AC_P < 0.5) //功率小于0.5时,说明没有负载,相角为0
  726. {
  727. F_Angle = 0;
  728. }
  729. if (F_Angle < 90)
  730. {
  731. a = F_Angle;
  732. // printf("电流超前电压:%f\n " ,a);
  733. }
  734. else if (F_Angle < 180)
  735. {
  736. a = 180-F_Angle;
  737. // printf("电流滞后电压:%f\n " ,a);
  738. }
  739. else if (F_Angle < 360)
  740. {
  741. a = 360 - F_Angle;
  742. // printf("电流滞后电压:%f\n " ,a);
  743. }
  744. else
  745. {
  746. a = F_Angle -360;
  747. // printf("电流超前电压:%f\n " ,a);
  748. }
  749. }
  750. /*=========================================================================================================
  751. * Function : void Calculate_HLW8110_MeterData(void);
  752. * Describe :
  753. * Input : none
  754. * Output : none
  755. * Return : none
  756. * Record : 2018/05/10
  757. ==========================================================================================================*/
  758. void Calculate_HLW8110_MeterData(void)
  759. {
  760. Check_WriteReg_Success();
  761. Read_HLW8110_IA();
  762. Read_HLW8110_U();
  763. Read_HLW8110_PA();
  764. Read_HLW8110_EA();
  765. Read_HLW8110_LineFreq();
  766. Read_HLW8110_Angle();
  767. Read_HLW8110_PF();
  768. // printf("\r\n");
  769. // printf("\r\n");
  770. // printf("交流测量,uart通讯方式\r\n");
  771. // printf("A通道电流转换系数:%x\n " ,U16_RMSIAC_RegData);
  772. // printf("B通道电流转换系数:%x\n " ,U16_RMSIBC_RegData);
  773. // printf("电压通道转换系数:%x\n " ,U16_RMSUC_RegData);
  774. // printf("A通道功率转换系数:%x\n " ,U16_PowerPAC_RegData);
  775. // printf("B通道功率转换系数:%x\n " ,U16_PowerPBC_RegData);
  776. // printf("视在功率转换系数:%x\n " ,U16_PowerSC_RegData);
  777. // printf("A通道电量转换系数:%x\n " ,U16_EnergyAC_RegData);
  778. // printf("B通道电量转换系数:%x\n " ,U16_EnergyBC_RegData);
  779. // printf("转换系数校验和:%x\n " ,U16_CheckSUM_RegData);
  780. // printf("转换系数计算出的校验和:%x\n " ,U16_CheckSUM_Data);
  781. //
  782. // printf("\r\n");//插入换行
  783. // printf("A通道电流寄存器:%x\n " ,U32_RMSIA_RegData);
  784. // printf("电压寄存器:%x\n " ,U32_RMSU_RegData);
  785. // printf("A通道功率寄存器:%x\n " ,U32_POWERPA_RegData);
  786. // printf("A通道电量寄存器:%x\n " ,U32_ENERGY_PA_RegData);
  787. // printf("\r\n");//插入换行
  788. // printf("F_AC_I = %f A \n " ,F_AC_I); //电流
  789. // printf("F_AC_V = %f V \n " ,F_AC_V); //电压
  790. // printf("F_AC_P = %f W \n " ,F_AC_P); //功率
  791. // printf("F_AC_BACKUP_E = %f KWH \n " ,F_AC_BACKUP_E); //电量
  792. // printf("F_AC_LINE_Freq = %f Hz \n " ,F_AC_LINE_Freq); //市电线性频率
  793. // printf("F_Angle = %f\n " ,F_Angle); //L和N的相角
  794. // printf("F_AC_PF = %f\n " ,F_AC_PF); //功率因素
  795. //
  796. // printf("\r\n");//插入换行
  797. // printf("\r\n");//插入换行
  798. // printf("----------------------------------------------\r\n");
  799. // printf("----------------------------------------------\r\n");
  800. }
  801. #endif