Hlw8110.c 23 KB

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