#include "bsp_dwt.h" #include "bsp_fdcan.h" #include "xidipwmeter.h" #include #include 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) auto current_raw = (int16_t) ((rxbuff[1] << 8) | rxbuff[0]); measure->current = (float) current_raw / 100.0f; // 解析电压数据 (放大100倍,需要除以100) auto 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; }