huyongji1.1-system/App/HLW8032/HLW8032.c

178 lines
6.4 KiB
C

#include "HLW8032.h"
#include "math.h"
/* Private defines -----------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t first_run = 1; // 添加这行代码
float E_total = 0; // 累计电量
uint8_t UART4_RX_BUF[UART4_MAX_RECV_LEN]; // 改为UART4
uint8_t UART4_TX_BUF[UART4_MAX_SEND_LEN]; // 改为UART4
__IO uint16_t UART4_RX_STA; // 改为UART4
float g_energy = 0; // 初始化为0
uint8_t link = 0;
volatile float analog_status[3] = {0}; // 定义并初始化数组
uint8_t k = 0;
uint16_t old_reg = 0, len = 0;
double V = 0, C = 0, P = 0, E_con = 0;
double base_energy = 0; // EEPROM中的基准值
float last_minute_energy = 0; // 上一分钟的电量值
float current_minute_energy = 0; // 当前分钟的电量值
void Apphl8032_Init(void)
{
/* 初始化串口4 */
MX_UART4_Init();
// 使用HAL库的单字节接收中断
HAL_UART_Receive_IT(&huart4, &aRxBuffer, 1);
//从EEPROM读取累计电量
base_energy = Load_Energy_From_EEPROM();
analog_status[1] = base_energy; // 初始化为0
last_minute_energy=0.0f;
current_minute_energy=0.0f;
}
void Data_Processing(void)
{
static uint32_t lastProcessTime = 0;
static uint32_t lastSaveTime = 0;
static uint32_t last_saved_energy =0.0f;
uint32_t currentTime = HAL_GetTick();
// 至少1秒处理一次
if(currentTime - lastProcessTime < 1000)
{
// printf("Data processing skipped: less than 1 second since last processing.\r\n");
UART4_RX_STA = 0;
return;
}
if (UART4_RX_STA & 0x8000) // 接收完成
{
// printf("Data reception complete. Processing data...\r\n");
uint32_t VP_REG = 0, V_REG = 0; // 电压相关寄存器
uint32_t CP_REG = 0, C_REG = 0; // 电流相关寄存器
uint32_t PP_REG = 0, P_REG = 0; // 功率相关寄存器
uint32_t PF = 0, PF_COUNT = 0; // 电量相关寄存器
uint32_t dat_sum = 0; // 校验和
// 计算校验和
for (uint8_t i = 2; i < 23; i++)
{
dat_sum += UART4_RX_BUF[i];
}
// printf("Calculated checksum: %lu, Received checksum: %02X\r\n", dat_sum % 256, UART4_RX_BUF[23]);
if (dat_sum % 256 == UART4_RX_BUF[23]) // 校验和正确
{
// printf("Checksum is valid.\r\n");
// 1. 计算电压
VP_REG = UART4_RX_BUF[2] * 65536 + UART4_RX_BUF[3] * 256 + UART4_RX_BUF[4];
V_REG = UART4_RX_BUF[5] * 65536 + UART4_RX_BUF[6] * 256 + UART4_RX_BUF[7];
if (V_REG != 0)
{
V = (VP_REG / V_REG) * 1.88;
// printf("Voltage calculated: V=%.2fV\r\n", V);
}
else
{
// printf("V_REG is zero, voltage calculation skipped.\r\n");
}
// 2. 计算电流
CP_REG = UART4_RX_BUF[8] * 65536 + UART4_RX_BUF[9] * 256 + UART4_RX_BUF[10];
C_REG = UART4_RX_BUF[11] * 65536 + UART4_RX_BUF[12] * 256 + UART4_RX_BUF[13];
if (C_REG != 0)
{
C = ((CP_REG * 100.0) / C_REG) / 100.0;
// printf("Current calculated: I=%.3fA\r\n", C);
}
else
{
// printf("C_REG is zero, current calculation skipped.\r\n");
}
// 3. 计算功率
PP_REG = UART4_RX_BUF[14] * 65536 + UART4_RX_BUF[15] * 256 + UART4_RX_BUF[16];
P_REG = UART4_RX_BUF[17] * 65536 + UART4_RX_BUF[18] * 256 + UART4_RX_BUF[19];
if (P_REG != 0)
{
P = (PP_REG / P_REG) * 1.88;
// printf("Power calculated: P=%.3fW\r\n", P);
}
else
{
// printf("P_REG is zero, power calculation skipped.\r\n");
}
// 4. 计算电量
if ((UART4_RX_BUF[20] & 0x80) != old_reg)
{
k++;
old_reg = UART4_RX_BUF[20] & 0x80;
}
PF = (k * 65536) + (UART4_RX_BUF[21] * 256) + UART4_RX_BUF[22];
// printf("Power factor calculated: PF=%lu\r\n", PF);
if (P >= 0.0 && PP_REG != 0)
{
PF_COUNT = ((100000 * 3600) / (PP_REG * 1.88)) * 10000;
current_minute_energy = ((PF * 10000.0) / PF_COUNT) / 10000.0;
static uint32_t last_save_time = 0;
uint32_t current_time = HAL_GetTick();
// 每10秒打印一次当前状态
if(current_time - last_save_time >= 10000) // 每10秒
{
// printf("Current Status:\r\n");
// printf("V=%.2fV, I=%.3fA, P=%.3fW\r\n", V, C, P);
// printf("Current Energy=%.6f, Last Energy=%.6f\r\n",
// current_minute_energy, last_minute_energy);
}
// 每分钟计算一次增量
if (current_time - last_save_time >= 60000) // 60秒
{
float minute_increase = current_minute_energy - last_minute_energy;
// printf("Minute increase: %.6f KWH\r\n", minute_increase);
// 添加保护,防止异常值
if (minute_increase > 0.0f && minute_increase < 1.0f)
{
base_energy += minute_increase;
analog_status[1] = base_energy;
if((base_energy - last_saved_energy >= 0.1f)|| (currentTime-lastSaveTime>300000))
{
Save_Energy_To_EEPROM(base_energy);
last_saved_energy=base_energy;
}
}
else
{
// printf("Invalid energy increase: %.6f KWH\r\n", minute_increase);
}
last_minute_energy = current_minute_energy;
last_save_time = current_time;
}
}
else
{
// printf("Power or PP_REG is zero. P=%.3f, PP_REG=%lu\r\n", P, PP_REG);
}
}
else
{
// printf("Checksum is invalid.\r\n");
}
}
lastProcessTime = currentTime;
UART4_RX_STA = 0; // 这里可能需要调整
}