shuichan_old/V1.5/STM32F103_App1/HardWare/HLW8032/hlw8032.c

223 lines
7.8 KiB
C
Raw Normal View History

/* hlw8032.c - HLW8032 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UART5 ֻ<>գ<EFBFBD>4800 8E1<45><31>
*
* ֡<EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>24 <EFBFBD>ֽڣ<EFBFBD>ÿ 50ms һ֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* [0] ״̬<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> State REG 0x55=<EFBFBD><EFBFBD><EFBFBD><EFBFBD> / 0xAA=<EFBFBD>޵<EFBFBD>ʧЧ / 0xFx=<EFBFBD>мĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* [1] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> Check REG <EFBFBD>̶<EFBFBD> 0x5A
* [2:5] <EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>ã<EFBFBD>
* [5:8] <EFBFBD><EFBFBD>ѹ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
* [8:11] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
* [11:14]<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
* [14:17]<EFBFBD><EFBFBD><EFBFBD>ʲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> PowerPar оƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>
* [17:20]<EFBFBD><EFBFBD><EFBFBD>ʼĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
* [20] <EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><EFBFBD>¼Ĵ<EFBFBD><EFBFBD><EFBFBD> bit7 = PF <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>־
* [21:23]PF <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD> 16bit <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬʱ bit7 <EFBFBD><EFBFBD>ת
* [23] У<EFBFBD><EFBFBD><EFBFBD><EFBFBD> [2]~[22] <EFBFBD><EFBFBD> 21 <EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD> 8 λ
*
* <EFBFBD>ֲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>
* 1 <EFBFBD>ȵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = (1/PowerPar) <EFBFBD><EFBFBD> (1/(<EFBFBD><EFBFBD>ѹϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD>)) <EFBFBD><EFBFBD> 10^9 <EFBFBD><EFBFBD> 3600
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>(kWh) = <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> PowerPar <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ѹϵ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD> / (10^9 <EFBFBD><EFBFBD> 3600)
* <EFBFBD><EFBFBD>ѹ/<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> main.h<EFBFBD><EFBFBD>HLW_U_COEF / HLW_I_COEF<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PF <EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD> 16 λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ bit7 <EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ס bit7 <EFBFBD>ϴ<EFBFBD>ֵ<EFBFBD><EFBFBD>
* ÿ֡<EFBFBD>ȶԣ<EFBFBD><EFBFBD><EFBFBD>תһ<EFBFBD><EFBFBD>˵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>Σ<EFBFBD>+65536<EFBFBD><EFBFBD><EFBFBD><EFBFBD>50ms һ֡ vs <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҲҪ<EFBFBD><EFBFBD>Сʱ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>©<EFBFBD><EFBFBD>
*/
#include "hlw8032.h"
#include "uart.h"
#include "24c02.h"
#include "log.h"
#include <string.h>
#define HLW_FRAME_LEN 24
#define HLW_OVERFLOW_PULSES 65536u
#define HLW_EEP_ADDR 164 /* EEPROM 164~171: uint64 <20>ۼ<EFBFBD><DBBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>132~157 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 160 <20><>־<EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD> */
static uint8_t s_frame[HLW_FRAME_LEN];
static uint8_t s_idx = 0; /* ֡ͬ<D6A1><CDAC>״̬<D7B4><CCAC>0=<3D><><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD> 1=<3D><> 0x5A >=2=<3D>ռ<EFBFBD><D5BC><EFBFBD> */
static uint64_t s_total_pulses = 0; /* <20>ۼ<EFBFBD><DBBC><EFBFBD><EFBFBD><EFBFBD><E5A3A8> EEPROM <20>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ʷֵ<CAB7><D6B5> */
static uint64_t s_saved_pulses = 0; /* <20>ϴ<EFBFBD><CFB4><EFBFBD>д<EFBFBD><D0B4> EEPROM <20><>ֵ */
static uint32_t s_power_par = 0; /* <20><><EFBFBD>ʲ<EFBFBD><CAB2><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD> */
static uint32_t s_u_par = 0, s_u_reg = 0; /* <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>/<2F><>ѹ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>ѹ<EFBFBD>ã<EFBFBD> */
static uint32_t s_i_par = 0, s_i_reg = 0; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD> */
static uint32_t s_p_reg = 0; /* <20><><EFBFBD>ʼĴ<CABC><C4B4><EFBFBD> */
static uint32_t s_k = 0; /* <20><><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD> bit7 <20><>ת<EFBFBD><D7AA>PF <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static uint8_t s_last_bit7 = 0;
static uint32_t s_last_chip = 0; /* <20><>һ֡оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> k*65536+n */
static uint8_t s_synced = 0; /* <20><>ȷ<EFBFBD><C8B7>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч֡<D0A7><D6A1> */
static uint8_t s_streak = 0; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч֡<D0A7><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD> */
static uint32_t s_last_valid_tick = 0; /* <20><>һ<EFBFBD><D2BB>Ч֡ʱ<D6A1>̣<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ã<EFBFBD> */
static uint32_t s_last_frame_tick = 0;
/*==== ֡У<D6A1><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۼƣ<DBBC><C6A3>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>====*/
static void hlw8032_parse(const uint8_t *f)
{
uint8_t sum = 0;
for (uint8_t i = 2; i <= 22; i++) sum += f[i];
if (sum != f[23]) return; /* У<><D0A3>ʧ<EFBFBD>ܶ<EFBFBD>֡ */
uint32_t power_par = ((uint32_t)f[14] << 16) | ((uint32_t)f[15] << 8) | f[16];
if (power_par == 0) return; /* <20><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><ECB3A3>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
s_power_par = power_par;
/* <20><>ѹ/<2F><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>ԭʼ<D4AD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE>ʾ<EFBFBD><CABE> */
s_u_par = ((uint32_t)f[2] << 16) | ((uint32_t)f[3] << 8) | f[4];
s_u_reg = ((uint32_t)f[5] << 16) | ((uint32_t)f[6] << 8) | f[7];
s_i_par = ((uint32_t)f[8] << 16) | ((uint32_t)f[9] << 8) | f[10];
s_i_reg = ((uint32_t)f[11] << 16) | ((uint32_t)f[12] << 8) | f[13];
s_p_reg = ((uint32_t)f[17] << 16) | ((uint32_t)f[18] << 8) | f[19];
uint8_t bit7 = f[20] & 0x80;
uint16_t pf = ((uint16_t)f[21] << 8) | f[22];
if (!s_synced) {
/* <20><>ֻ֡<D6A1><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD><DBBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>Ƭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬһֱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD> Wh<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
s_last_bit7 = bit7;
s_k = 0;
} else if (bit7 != s_last_bit7) {
s_k++; /* PF <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> */
s_last_bit7 = bit7;
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ 50ms һ֡<D2BB>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD>Ҫ<EFA3AC><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3 ֡<>Ҽ<EFBFBD><D2BC><EFBFBD> 20~150ms <20><><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD>
* PD2 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>ĵ<EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD><EFBFBD>ż<EFBFBD><EFBFBD>Ҳ<EFBFBD>ܴճ<EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD>ļ<EFBFBD>֡<EFBFBD><EFBFBD>Լ 1/256<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3 ֡<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 50ms <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
{
uint32_t now = HAL_GetTick();
uint32_t gap = now - s_last_valid_tick;
s_last_valid_tick = now;
if (gap >= 20 && gap <= 150) {
if (s_streak < 3) s_streak++;
} else {
s_streak = 1;
}
if (s_streak < 3) return; /* δȷ<CEB4><C8B7>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>һ<EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD><EFBFBD><EFBFBD> */
}
uint32_t chip_total = s_k * HLW_OVERFLOW_PULSES + pf;
if (s_synced) {
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С˵<D0A1><CBB5>оƬ<D0BE>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3A3A9><EFBFBD>ӵ<EFBFBD>ǰֵ<C7B0><D6B5><EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD> */
uint32_t delta = (chip_total >= s_last_chip) ? (chip_total - s_last_chip) : chip_total;
s_total_pulses += delta;
}
s_last_chip = chip_total;
if (!s_synced) {
s_synced = 1;
log_info("> <20><><EFBFBD><EFBFBD>: HLW8032 <20><><EFBFBD><EFBFBD>, <20><><EFBFBD>ʲ<EFBFBD><CAB2><EFBFBD>=%lu", (unsigned long)s_power_par);
}
s_last_frame_tick = HAL_GetTick();
}
/*==== UART5 <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>ֽ<EFBFBD>ι<EFBFBD><EFBFBD><EBA3BA><EFBFBD>ֽ<EFBFBD>ͬ<EFBFBD><CDAC> + 0x5A <20><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7> + <20><><EFBFBD><EFBFBD> 24 <20>ֽڽ<D6BD><DABD><EFBFBD> ====*/
void hlw8032_rx_byte(uint8_t b)
{
if (s_idx == 0) {
/* <20><><EFBFBD>ֽں<D6BD>ѡ<EFBFBD><D1A1>0x55 / 0xAA / 0xFx */
if (b == 0x55 || b == 0xAA || (b & 0xF0) == 0xF0) {
s_frame[0] = b;
s_idx = 1;
}
return;
}
if (s_idx == 1) {
if (b == 0x5A) {
s_frame[1] = b;
s_idx = 2;
} else {
/* <20>ڶ<EFBFBD><DAB6>ֽڲ<D6BD><DAB2><EFBFBD> 0x5A<35><41>αͬ<CEB1><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD> */
s_idx = 0;
if (b == 0x55 || b == 0xAA || (b & 0xF0) == 0xF0) {
s_frame[0] = b;
s_idx = 1;
}
}
return;
}
s_frame[s_idx++] = b;
if (s_idx >= HLW_FRAME_LEN) {
s_idx = 0;
hlw8032_parse(s_frame);
}
}
/*==== <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>EEPROM <20>ָ<EFBFBD><D6B8>ۼ<EFBFBD> + UART5 <20><><EFBFBD><EFBFBD> ====*/
void hlw8032_init(void)
{
uint64_t v = 0;
eepromReadData(HLW_EEP_ADDR, &v, sizeof(v));
if (v == 0xFFFFFFFFFFFFFFFFULL) v = 0; /* <20>հ<EFBFBD> EEPROM<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0xFF<46><46> */
s_total_pulses = v;
s_saved_pulses = v;
MX_UART5_UART_Init();
UART5_StartRx();
if (s_total_pulses) {
log_info("> <20><><EFBFBD><EFBFBD>: HLW8032 <20><><EFBFBD><EFBFBD> (UART5 PD2), <20><>ʷ<EFBFBD><CAB7><EFBFBD><EFBFBD> %lu%09lu",
(unsigned long)(s_total_pulses / 1000000000ULL),
(unsigned long)(s_total_pulses % 1000000000ULL));
} else {
log_info("> <20><><EFBFBD><EFBFBD>: HLW8032 <20><><EFBFBD><EFBFBD> (UART5 PD2)");
}
}
/*==== <20>ۼƵ<DBBC><C6B5><EFBFBD> kWh ====*/
float hlw8032_get_energy_kwh(void)
{
if (!s_power_par) return 0.0f;
return (float)((double)s_total_pulses * (double)s_power_par *
(double)HLW_U_COEF * (double)HLW_I_COEF / 3.6e12);
}
/*==== <20><>ѹ/<2F><><EFBFBD><EFBFBD>/<2F><><EFBFBD>ʣ<EFBFBD><CAA3>ֲ᣺<D6B2><E1A3BA>Чֵ = <20><><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>/<2F>Ĵ<EFBFBD><C4B4><EFBFBD> <20><> ϵ<><CFB5><EFBFBD><EFBFBD>====*/
float hlw8032_get_voltage_v(void)
{
if (!s_u_reg) return 0.0f;
return (float)((double)s_u_par / (double)s_u_reg * HLW_U_COEF);
}
float hlw8032_get_current_a(void)
{
if (!s_i_reg) return 0.0f;
float a = (float)((double)s_i_par / (double)s_i_reg * HLW_I_COEF);
a -= HLW_I_ZERO_A; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB> */
return a > 0.0f ? a : 0.0f; /* ǯλ<C7AF><CEBB> 0 */
}
float hlw8032_get_power_w(void)
{
if (!s_p_reg) return 0.0f;
float w = (float)((double)s_power_par / (double)s_p_reg * HLW_U_COEF * HLW_I_COEF);
if (w < HLW_P_DEAD_W) return 0.0f; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ 0 */
return w - HLW_P_ZERO_W;
}
/*==== <20><><EFBFBD><EFBFBD><EFBFBD>жϣ<D0B6>1s <20><><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD>Ч֡ ====*/
uint8_t hlw8032_online(void)
{
return s_synced && (HAL_GetTick() - s_last_frame_tick) < 1000;
}
/*==== <20><><EFBFBD><EFBFBD>д EEPROM<4F><4D><EFBFBD>ϵ<EFBFBD>Ԥ<EFBFBD><D4A4>/<2F>ƻ<EFBFBD><C6BB><EFBFBD>λǰ<CEBB><C7B0><EFBFBD>ã<EFBFBD>====*/
void hlw8032_save(void)
{
if (s_total_pulses == s_saved_pulses) return;
uint64_t v = s_total_pulses;
if (eepromWriteData(HLW_EEP_ADDR, &v, sizeof(v)) == 0) {
s_saved_pulses = s_total_pulses;
}
}
/*==== 1s <20><><EFBFBD>ڣ<EFBFBD>ÿ<EFBFBD>ܹ<EFBFBD>Լ 0.1 kWh дһ<D0B4><D2BB> EEPROM<4F><4D><EFBFBD><EFBFBD><EFBFBD>Ʋ<EFBFBD>дƵ<D0B4><C6B5> ====*/
void hlw8032_tick(void)
{
if (!s_power_par) return;
double per_01kwh = 3.6e11 / ((double)s_power_par * HLW_U_COEF * HLW_I_COEF);
if (per_01kwh < 1.0) per_01kwh = 1.0;
if (s_total_pulses - s_saved_pulses >= (uint64_t)per_01kwh) {
hlw8032_save();
}
}