mirror of
https://gitee.com/dlmu-cone/tronone-h7-scaffold
synced 2026-07-24 03:27:45 +08:00
powermeter
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
# 溪地创新功率计驱动
|
||||
|
||||
使用示例:
|
||||
|
||||
```c
|
||||
// 在适当的地方初始化功率计(如main.c中)
|
||||
PowerMeterInstance *power_meter = PowerMeterInit(&hfdcan1); // 使用FDCAN1
|
||||
|
||||
// 在任务循环中获取功率数据
|
||||
void PowerMonitorTask(void)
|
||||
{
|
||||
float voltage = PowerMeterGetVoltage(power_meter);
|
||||
float current = PowerMeterGetCurrent(power_meter);
|
||||
float power = PowerMeterGetPower(power_meter);
|
||||
float energy = PowerMeterGetEnergy(power_meter);
|
||||
|
||||
// 打印或使用这些数据
|
||||
printf("V: %.1fV, I: %.1fA, P: %.1fW, E: %.1fJ\n",
|
||||
voltage, current, power, energy);
|
||||
}
|
||||
```
|
||||
@@ -1,5 +1,183 @@
|
||||
//
|
||||
// Created by ASUS on 2025/11/17.
|
||||
//
|
||||
#include "bsp_dwt.h"
|
||||
#include "bsp_fdcan.h"
|
||||
#include "xidipwmeter.h"
|
||||
|
||||
#include "xidipwmeter.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static PowerMeterInstance *power_meter_instance = NULL;
|
||||
|
||||
/**
|
||||
* @brief 功率计数据解码函数
|
||||
* @param instance FDCAN实例指针
|
||||
*
|
||||
* @note 数据格式:
|
||||
* DATA[0]: 电流数值低8位
|
||||
* DATA[1]: 电流数值高8位
|
||||
* DATA[2]: 电压数值低8位
|
||||
* DATA[3]: 电压数值高8位
|
||||
* DATA[4]-DATA[7]: 保留
|
||||
*
|
||||
* 电压电流数值均为放大100倍后的整数,需要除以100.0得到实际值
|
||||
*/
|
||||
void PowerMeterDecode(FDCANInstance *instance)
|
||||
{
|
||||
if (power_meter_instance == NULL)
|
||||
return;
|
||||
|
||||
uint8_t *rxbuff = instance->rx_buff;
|
||||
PowerMeter_Measure_s *measure = &power_meter_instance->measure;
|
||||
|
||||
// 重载守护进程
|
||||
// if (power_meter_instance->daemon != NULL)
|
||||
// {
|
||||
// DaemonReload(power_meter_instance->daemon);
|
||||
// }
|
||||
|
||||
// 计算时间间隔
|
||||
measure->dt = DWT_GetDeltaT(&power_meter_instance->feed_cnt);
|
||||
|
||||
// 解析电流数据 (放大100倍,需要除以100)
|
||||
int16_t current_raw = (int16_t) ((rxbuff[1] << 8) | rxbuff[0]);
|
||||
measure->current = (float) current_raw / 100.0f;
|
||||
|
||||
// 解析电压数据 (放大100倍,需要除以100)
|
||||
int16_t voltage_raw = (int16_t) ((rxbuff[3] << 8) | rxbuff[2]);
|
||||
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 功率计实例指针
|
||||
*/
|
||||
void PowerMeterLostCallback(void *power_meter_ptr)
|
||||
{
|
||||
PowerMeterInstance *power_meter = (PowerMeterInstance *) power_meter_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 功率计初始化
|
||||
* @param can_handle FDCAN句柄指针
|
||||
* @return PowerMeterInstance* 功率计实例指针
|
||||
*/
|
||||
PowerMeterInstance *PowerMeterInit(FDCAN_HandleTypeDef *can_handle)
|
||||
{
|
||||
// 检查是否已经初始化
|
||||
if (power_meter_instance != NULL)
|
||||
{
|
||||
return power_meter_instance;
|
||||
}
|
||||
|
||||
// 分配内存
|
||||
power_meter_instance = (PowerMeterInstance *) malloc(sizeof(PowerMeterInstance));
|
||||
if (power_meter_instance == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset(power_meter_instance, 0, sizeof(PowerMeterInstance));
|
||||
|
||||
// 配置FDCAN初始化参数 - 完全适配您的FDCAN驱动
|
||||
FDCAN_Init_Config_s can_config = {
|
||||
.can_handle = can_handle,
|
||||
.rx_id = 0x213, // 功率计反馈标识符
|
||||
.tx_id = 0x000, // 不需要发送,设为0
|
||||
.can_module_callback = PowerMeterDecode,
|
||||
.id = power_meter_instance, // 将实例指针作为ID传递
|
||||
};
|
||||
|
||||
// 注册FDCAN实例 - 使用FDCANRegister函数
|
||||
power_meter_instance->can_instance = FDCANRegister(&can_config);
|
||||
if (power_meter_instance->can_instance == NULL)
|
||||
{
|
||||
free(power_meter_instance);
|
||||
power_meter_instance = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 注册守护进程
|
||||
// Daemon_Init_Config_s daemon_config = {
|
||||
// .callback = PowerMeterLostCallback,
|
||||
// .owner_id = power_meter_instance,
|
||||
// .reload_count = 5, // 50ms未收到数据则认为丢失 (1000Hz发送,5个周期)
|
||||
// };
|
||||
// power_meter_instance->daemon = DaemonRegister(&daemon_config);
|
||||
|
||||
return power_meter_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取电压值
|
||||
* @param power_meter 功率计实例指针
|
||||
* @return float 电压值 (V)
|
||||
*/
|
||||
float PowerMeterGetVoltage(PowerMeterInstance *power_meter)
|
||||
{
|
||||
if (power_meter == NULL)
|
||||
return 0.0f;
|
||||
return power_meter->measure.voltage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取电流值
|
||||
* @param power_meter 功率计实例指针
|
||||
* @return float 电流值 (A)
|
||||
*/
|
||||
float PowerMeterGetCurrent(PowerMeterInstance *power_meter)
|
||||
{
|
||||
if (power_meter == NULL)
|
||||
return 0.0f;
|
||||
return power_meter->measure.current;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取功率值
|
||||
* @param power_meter 功率计实例指针
|
||||
* @return float 功率值 (W)
|
||||
*/
|
||||
float PowerMeterGetPower(PowerMeterInstance *power_meter)
|
||||
{
|
||||
if (power_meter == NULL)
|
||||
return 0.0f;
|
||||
return power_meter->measure.power;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取累计能量
|
||||
* @param power_meter 功率计实例指针
|
||||
* @return float 累计能量 (J)
|
||||
*/
|
||||
float PowerMeterGetEnergy(PowerMeterInstance *power_meter)
|
||||
{
|
||||
if (power_meter == NULL)
|
||||
return 0.0f;
|
||||
return power_meter->measure.energy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 重置累计能量
|
||||
* @param power_meter 功率计实例指针
|
||||
*/
|
||||
void PowerMeterResetEnergy(PowerMeterInstance *power_meter)
|
||||
{
|
||||
if (power_meter != NULL)
|
||||
{
|
||||
power_meter->measure.energy = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取功率计实例(用于外部访问)
|
||||
* @return PowerMeterInstance* 功率计实例指针
|
||||
*/
|
||||
PowerMeterInstance *GetPowerMeterInstance(void)
|
||||
{
|
||||
return power_meter_instance;
|
||||
}
|
||||
|
||||
@@ -5,4 +5,47 @@
|
||||
#ifndef TRONONEH7_SCAFFOLD_XIDIPWMETER_H
|
||||
#define TRONONEH7_SCAFFOLD_XIDIPWMETER_H
|
||||
|
||||
#endif //TRONONEH7_SCAFFOLD_XIDIPWMETER_H
|
||||
#include "general_def.h"
|
||||
#include "bsp_dwt.h"
|
||||
#include "bsp_fdcan.h"
|
||||
|
||||
/* 功率计测量数据结构 */
|
||||
typedef struct
|
||||
{
|
||||
float voltage; // 电压 (V)
|
||||
float current; // 电流 (A)
|
||||
float power; // 功率 (W)
|
||||
float energy; // 累计能量 (J)
|
||||
uint32_t update_cnt; // 更新计数器
|
||||
float dt; // 更新时间间隔
|
||||
} PowerMeter_Measure_s;
|
||||
|
||||
/* 功率计实例结构 */
|
||||
typedef struct
|
||||
{
|
||||
FDCANInstance *can_instance; // FDCAN实例指针
|
||||
PowerMeter_Measure_s measure; // 测量数据
|
||||
// DaemonInstance *daemon; // 守护进程
|
||||
uint32_t feed_cnt; // 喂狗计数器
|
||||
} PowerMeterInstance;
|
||||
|
||||
/* 函数声明 */
|
||||
PowerMeterInstance *PowerMeterInit(FDCAN_HandleTypeDef *can_handle);
|
||||
|
||||
void PowerMeterDecode(FDCANInstance *instance);
|
||||
|
||||
void PowerMeterLostCallback(void *power_meter_ptr);
|
||||
|
||||
float PowerMeterGetVoltage(PowerMeterInstance *power_meter);
|
||||
|
||||
float PowerMeterGetCurrent(PowerMeterInstance *power_meter);
|
||||
|
||||
float PowerMeterGetPower(PowerMeterInstance *power_meter);
|
||||
|
||||
float PowerMeterGetEnergy(PowerMeterInstance *power_meter);
|
||||
|
||||
void PowerMeterResetEnergy(PowerMeterInstance *power_meter);
|
||||
|
||||
PowerMeterInstance *GetPowerMeterInstance(void);
|
||||
|
||||
#endif //TRONONEH7_SCAFFOLD_XIDIPWMETER_H
|
||||
|
||||
Reference in New Issue
Block a user