diff --git a/V1.5/STM32F103_App1/HardWare/HLW8032/hlw8032.c b/V1.5/STM32F103_App1/HardWare/HLW8032/hlw8032.c index bf1465a..660d0da 100644 --- a/V1.5/STM32F103_App1/HardWare/HLW8032/hlw8032.c +++ b/V1.5/STM32F103_App1/HardWare/HLW8032/hlw8032.c @@ -42,6 +42,7 @@ static uint32_t s_power_par = 0; /* static uint32_t s_u_par = 0, s_u_reg = 0; /* 电压参数/电压寄存器(显示电压用) */ static uint32_t s_i_par = 0, s_i_reg = 0; /* 电流参数/电流寄存器 */ static uint32_t s_p_reg = 0; /* 功率寄存器 */ +static float s_u_f = 0, s_i_f = 0, s_p_f = 0; /* 电压/电流/功率 EMA 滤波值 */ static uint32_t s_k = 0; /* 本次上电以来 bit7 翻转(PF 溢出)次数 */ static uint8_t s_last_bit7 = 0; @@ -97,6 +98,17 @@ static void hlw8032_parse(const uint8_t *f) if (s_streak < 3) return; /* 未确认同步:帧内容一律不采用 */ } + /* EMA 滑动平均(系数 1/8,约 0.4s 响应):压空载噪声跳变, + * 真实负载变化延迟 <0.5s,不影响使用 */ + { + float u = s_u_reg ? (float)((double)s_u_par / (double)s_u_reg * HLW_U_COEF) : 0.0f; + float a = s_i_reg ? (float)((double)s_i_par / (double)s_i_reg * HLW_I_COEF) : 0.0f; + float w = s_p_reg ? (float)((double)s_power_par / (double)s_p_reg * HLW_U_COEF * HLW_I_COEF) : 0.0f; + s_u_f += (u - s_u_f) * 0.125f; + s_i_f += (a - s_i_f) * 0.125f; + s_p_f += (w - s_p_f) * 0.125f; + } + uint32_t chip_total = s_k * HLW_OVERFLOW_PULSES + pf; if (s_synced) { /* 正常单调递增;变小说明芯片断电重启过(寄存器清零),从当前值重新累计 */ @@ -185,24 +197,22 @@ float hlw8032_get_energy_kwh(void) /*==== 电压/电流/功率(手册:有效值 = 参数寄存器/寄存器 × 系数)====*/ 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); + if (!s_synced) return 0.0f; + return s_u_f; } 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; /* 减零点偏移 */ - return a > 0.0f ? a : 0.0f; /* 钳位到 0 */ + if (!s_synced) return 0.0f; + float a = s_i_f - HLW_I_ZERO_A; /* 减零点偏移 */ + return a > 0.0f ? a : 0.0f; /* 钳位到 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; /* 死区:空载噪声底显示 0 */ - return w - HLW_P_ZERO_W; + if (!s_synced) return 0.0f; + if (s_p_f < HLW_P_DEAD_W) return 0.0f; /* 死区:空载噪声底显示 0 */ + return s_p_f - HLW_P_ZERO_W; } /*==== 在线判断:1s 内收到过有效帧 ====*/