god-yuan-hero/User/device/supercap.c
2025-12-07 14:35:28 +08:00

159 lines
4.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "device/supercap.h"
/* 全局变量 */
CAN_SuperCapRXDataTypeDef CAN_SuperCapRXData = {0};
uint8_t PowerOffset =0;
uint32_t LastCapTick = 0; //上一次收到超电信号的时间戳
uint32_t NowCapTick = 0; //现在收到超电信号的时间戳
uint32_t chassis_energy_in_gamming =0;
/* 静态变量 - 用于CAN接收管理 */
static bool supercap_inited = false;
static osMessageQueueId_t supercap_rx_queue = NULL;
/**
* @brief 获取超级电容在线状态1在线0离线
*/
uint8_t get_supercap_online_state(void){
NowCapTick = HAL_GetTick(); //更新时间戳
uint32_t DeltaCapTick = 0;
DeltaCapTick = NowCapTick - LastCapTick; //计算时间差
// if(get_game_progress() == 4){
// //比赛开始的时候,开始统计消耗的能量
chassis_energy_in_gamming += CAN_SuperCapRXData.BatPower * DeltaCapTick *0.001f;
// 因为STM32的系统定时器是1ms的周期所以*0.001单位化为秒S能量单位才是焦耳J
// }
if(DeltaCapTick > 1000){
//如果时间差大于1s说明超电信号丢失返回超电离线的标志
return 0;
}else {
//如果时间差小于1s说明超电信号正常返回超电在线的标志
return 1;
}
}
/**
* @brief 获取根据超级电容功率统计的底盘消耗能量单位焦耳J
*/
uint32_t get_chassis_energy_from_supercap(void){
return chassis_energy_in_gamming;
}
/******************超级电容数据从CAN传到结构体******************/
int8_t SuperCap_Init(void)
{
if (supercap_inited) {
return DEVICE_OK; // 已经初始化过
}
if (BSP_CAN_RegisterId( SUPERCAP_CAN , SUPERCAP_RX_ID, 3) != BSP_OK) {
return DEVICE_ERR;
}
supercap_inited = true;
return DEVICE_OK;
}
int8_t SuperCap_Update(void)
{
if (!supercap_inited) {
return DEVICE_ERR;
}
BSP_CAN_Message_t rx_msg;
// 从CAN队列获取数据
if (BSP_CAN_GetMessage( SUPERCAP_CAN , SUPERCAP_RX_ID, &rx_msg, BSP_CAN_TIMEOUT_IMMEDIATE) == BSP_OK) {
// 处理接收到的数据
transfer_SuperCap_measure(rx_msg.data);
return DEVICE_OK;
}
return DEVICE_ERR; // 没有新数据
}
void transfer_SuperCap_measure(uint8_t *data)
{
LastCapTick = HAL_GetTick();
CAN_SuperCapRXData.SuperCapReady = (SuperCap_Status_t)data[0];
CAN_SuperCapRXData.SuperCapState = (SuperCap_Status_t)data[1];
CAN_SuperCapRXData.SuperCapEnergy = data[2];
CAN_SuperCapRXData.ChassisPower = data[3] << 1; //左移一位是为了扩大范围,超电发出来的的时候右移了一位
CAN_SuperCapRXData.BatVoltage = data[4];
CAN_SuperCapRXData.BatPower = data[5];
}
/**
* @brief 获取超级电容的运行状态具体查看枚举SuperCapStateEnum
* @retval none
*/
SuperCapStateEnum get_supercap_state(void){
return (SuperCapStateEnum)CAN_SuperCapRXData.SuperCapState;
}
/**
* @brief 获取超级电容读到的电池电压单位伏V
* @retval none
*/
float get_battery_voltage_from_supercap(void){
return (float)CAN_SuperCapRXData.BatVoltage * 0.1f;
}
/**
* @brief 获取超级电容可用能量范围0-100%
* @retval none
*/
uint8_t get_supercap_energy(void){
return CAN_SuperCapRXData.SuperCapEnergy;
}
/**
* @brief 设置超级电容功率补偿
* @retval none
*/
void set_supercap_power_offset(uint8_t offset){
PowerOffset = offset;
}
/**
* @brief 发送超级电容数据
* @param[in] Enable: 超级电容使能
* @param[in] Charge: 超级电容充电在PLUS版本中无效
* @param[in] PowerLimit: 裁判系统功率限制
* @param[in] Chargepower: 超级电容充电功率在PLUS版本中无效
* @retval none
*/
int8_t CAN_TX_SuperCapData(CAN_SuperCapTXDataTypeDef * TX_Temp)
{
if (TX_Temp == NULL) return DEVICE_ERR_NULL;
BSP_CAN_StdDataFrame_t tx_frame;
tx_frame.id = SUPERCAP_TX_ID;
tx_frame.dlc = 0x08;
tx_frame.data[0] = TX_Temp-> Enable;
tx_frame.data[1] = TX_Temp-> Charge;//PLUS disabled
tx_frame.data[2] = TX_Temp-> Powerlimit - PowerOffset;
tx_frame.data[3] = TX_Temp-> ChargePower;//PLUS disabled
tx_frame.data[4] = 0;
tx_frame.data[5] = 0;
tx_frame.data[6] = 0;
tx_frame.data[7] = 0;
return BSP_CAN_TransmitStdDataFrame( SUPERCAP_CAN , &tx_frame) == BSP_OK ? DEVICE_OK : DEVICE_ERR;
}