#include "meter.h" #include "charger_control.h" METER_t METER; // Функция для расчета и накопления энергии c дробной частью без счетчиков void METER_CalculateEnergy() { // Проверяем, что индекс находится в пределах массива METER.online = 0; if(CONN.connState == Charging){ METER.enable = 1; }else{ METER.enable = 0; } uint32_t currentTick = HAL_GetTick(); // Получаем текущее время в миллисекундах uint32_t elapsedTimeMs = currentTick - METER.lastTick; // Вычисляем время, прошедшее с последнего вызова в секундах METER.lastTick = currentTick; // Обновляем время последнего вызова для текущего коннектора // uint64: Power*dt can exceed 2^32 at high power / long dt uint64_t energyWs = ((uint64_t)CONN.Power * elapsedTimeMs) / 1000U; //Расчет энергии теперь идет всегда, смещение берем суммарное METER.EnergyPSU_Ws += energyWs; // Divide in 64-bit first — casting Ws to uint32 before /3600 truncates ~1193 kWh METER.AbsoluteEnergy = (uint32_t)(METER.EnergyPSU_Ws / 3600U); if(METER.enable) { //enabled state if (METER.AbsoluteEnergy >= METER.EnergyOffset) { CONN.Energy = METER.AbsoluteEnergy - METER.EnergyOffset; } else { // Guard unsigned underflow (e.g. after Absolute wrap anomaly) CONN.Energy = 0; METER.EnergyOffset = METER.AbsoluteEnergy; } }else{ // Reset statе CONN.Energy = 0; METER.EnergyOffset = METER.AbsoluteEnergy; } }