Files
tronone-h7-scaffold/User_Code/module/periph/power_meters/xiditech/xidipwmeter.c

180 lines
5.0 KiB
C
Raw Normal View History

2025-11-20 19:11:56 +08:00
#include "bsp_dwt.h"
#include "bsp_fdcan.h"
#include "xidipwmeter.h"
2025-11-17 16:27:19 +08:00
2025-11-20 19:11:56 +08:00
#include <stdlib.h>
#include <string.h>
2026-02-24 23:47:15 +08:00
#include "daemon.h"
2026-03-09 01:57:43 +08:00
static XidiPowerMeterInstance *power_meter_instance = NULL;
2025-11-20 19:11:56 +08:00
/**
* @brief
2026-03-09 01:57:43 +08:00
* @param _instance FDCAN实例指针
2025-11-20 19:11:56 +08:00
*
* @note :
* DATA[0]: 8
* DATA[1]: 8
* DATA[2]: 8
* DATA[3]: 8
* DATA[4]-DATA[7]:
*
* 100100.0
*/
2026-03-09 01:57:43 +08:00
void XidiPowerMeterDecode(FDCANInstance *_instance)
2025-11-20 19:11:56 +08:00
{
if (power_meter_instance == NULL)
return;
2026-03-09 01:57:43 +08:00
uint8_t *rxbuff = _instance->rx_buff;
XidiPowerMeter_Msg_s *measure = &power_meter_instance->powermeter_msg;
2025-11-20 19:11:56 +08:00
// 重载守护进程
2026-03-09 02:35:08 +08:00
if (power_meter_instance->daemon != NULL)
{
DaemonReload(power_meter_instance->daemon);
}
2025-11-20 19:11:56 +08:00
// 计算时间间隔
measure->dt = DWT_GetDeltaT(&power_meter_instance->feed_cnt);
// 解析电流数据 (放大100倍需要除以100)
2025-11-20 19:26:42 +08:00
auto current_raw = (int16_t) ((rxbuff[1] << 8) | rxbuff[0]);
2025-11-20 19:11:56 +08:00
measure->current = (float) current_raw / 100.0f;
// 解析电压数据 (放大100倍需要除以100)
2025-11-20 19:26:42 +08:00
auto voltage_raw = (int16_t) ((rxbuff[3] << 8) | rxbuff[2]);
2025-11-20 19:11:56 +08:00
measure->voltage = (float) voltage_raw / 100.0f;
// 计算功率
measure->power = measure->voltage * measure->current;
// 计算累计能量 (功率 × 时间)
measure->energy += measure->power * measure->dt * 0.001f; // dt单位是ms转换为秒
measure->update_cnt++;
}
/**
* @brief
* @param power_meter_ptr
*/
2026-03-09 01:57:43 +08:00
void XidiPowerMeterLostCallback(void *power_meter_ptr)
2025-11-20 19:11:56 +08:00
{
2026-03-09 01:57:43 +08:00
XidiPowerMeterInstance *power_meter = (XidiPowerMeterInstance *) power_meter_ptr;
2025-11-20 19:11:56 +08:00
}
/**
* @brief
2026-03-09 01:57:43 +08:00
* @param XidiPowerMeter_config ()
* @return XidiPowerMeterInstance*
2025-11-20 19:11:56 +08:00
*/
2026-03-09 01:57:43 +08:00
XidiPowerMeterInstance *XidiPowerMeterInit(XidiPowerMeter_Init_Config_s *XidiPowerMeter_config)
2025-11-20 19:11:56 +08:00
{
2026-03-09 01:57:43 +08:00
// 1. 检查是否已经初始化
2025-11-20 19:11:56 +08:00
if (power_meter_instance != NULL)
{
return power_meter_instance;
}
2026-03-09 01:57:43 +08:00
// 2. 分配内存并清零
power_meter_instance = (XidiPowerMeterInstance *)malloc(sizeof(XidiPowerMeterInstance));
2025-11-20 19:11:56 +08:00
if (power_meter_instance == NULL)
{
return NULL;
}
2026-03-09 01:57:43 +08:00
memset(power_meter_instance, 0, sizeof(XidiPowerMeterInstance));
// 3. 配置并注册 FDCAN 实例
// (rx_id, tx_id, can_handle 等参数由外部 config 提供,这里只绑定回调和私有指针)
XidiPowerMeter_config->can_config.can_module_callback = XidiPowerMeterDecode;
XidiPowerMeter_config->can_config.id = power_meter_instance;
power_meter_instance->fdcan_ins = CANRegister(&XidiPowerMeter_config->can_config);
if (power_meter_instance->fdcan_ins == NULL)
2025-11-20 19:11:56 +08:00
{
free(power_meter_instance);
power_meter_instance = NULL;
return NULL;
}
2026-03-09 01:57:43 +08:00
// 4. 配置并注册 守护进程
// (reload_count 等参数由外部 config 提供,这里只绑定回调和私有指针)
XidiPowerMeter_config->daemon_config.callback = XidiPowerMeterLostCallback;
XidiPowerMeter_config->daemon_config.owner_id = power_meter_instance;
power_meter_instance->daemon = DaemonRegister(&XidiPowerMeter_config->daemon_config);
2025-11-20 19:11:56 +08:00
return power_meter_instance;
}
/**
* @brief
* @param power_meter
* @return float (V)
*/
2026-03-09 01:57:43 +08:00
float XidiPowerMeterGetVoltage(XidiPowerMeterInstance *power_meter)
2025-11-20 19:11:56 +08:00
{
if (power_meter == NULL)
return 0.0f;
2026-03-09 01:57:43 +08:00
return power_meter->powermeter_msg.voltage;
2025-11-20 19:11:56 +08:00
}
/**
* @brief
* @param power_meter
* @return float (A)
*/
2026-03-09 01:57:43 +08:00
float XidiPowerMeterGetCurrent(XidiPowerMeterInstance *power_meter)
2025-11-20 19:11:56 +08:00
{
if (power_meter == NULL)
return 0.0f;
2026-03-09 01:57:43 +08:00
return power_meter->powermeter_msg.current;
2025-11-20 19:11:56 +08:00
}
/**
* @brief
* @param power_meter
* @return float (W)
*/
2026-03-09 01:57:43 +08:00
float XidiPowerMeterGetPower(XidiPowerMeterInstance *power_meter)
2025-11-20 19:11:56 +08:00
{
if (power_meter == NULL)
return 0.0f;
2026-03-09 01:57:43 +08:00
return power_meter->powermeter_msg.power;
2025-11-20 19:11:56 +08:00
}
/**
* @brief
* @param power_meter
* @return float (J)
*/
2026-03-09 01:57:43 +08:00
float XidiPowerMeterGetEnergy(XidiPowerMeterInstance *power_meter)
2025-11-20 19:11:56 +08:00
{
if (power_meter == NULL)
return 0.0f;
2026-03-09 01:57:43 +08:00
return power_meter->powermeter_msg.energy;
2025-11-20 19:11:56 +08:00
}
/**
* @brief
* @param power_meter
*/
2026-03-09 01:57:43 +08:00
void XidiPowerMeterResetEnergy(XidiPowerMeterInstance *power_meter)
2025-11-20 19:11:56 +08:00
{
if (power_meter != NULL)
{
2026-03-09 01:57:43 +08:00
power_meter->powermeter_msg.energy = 0.0f;
2025-11-20 19:11:56 +08:00
}
}
/**
* @brief 访
* @return PowerMeterInstance*
*/
2026-03-09 01:57:43 +08:00
XidiPowerMeterInstance *GetXidiPowerMeterInstance(void)
2025-11-20 19:11:56 +08:00
{
return power_meter_instance;
}