#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; }