如何在STM32CubeIDE中通过标准CAN总线发送超8字节数据
如何在STM32CubeIDE中通过标准CAN发送超过8字节的多浮点数据
标准CAN单帧最大仅支持8字节数据,你需要发送的三个4字节浮点值(共12字节)必须拆分为两帧传输。以下是具体的代码改造方案,分发送端和接收端实现:
发送端改造
核心逻辑
将三个浮点值拆分为两帧:
- 第一帧发送电压+温度(合计8字节)
- 第二帧发送SOC(4字节,DLC设为4)
通过不同的标准帧ID(StdId)区分两帧数据,确保接收端能正确识别对应的数据块。
完整发送代码
// 确保已定义全局/局部变量(根据你的工程结构调整) CAN_TxHeaderTypeDef TxHeader; uint32_t TxMailbox; uint8_t TxData[8]; // 临时存储待发送的字节数据 void SendFloatsOverCAN(CAN_HandleTypeDef *hcan, float voltageVal, float temperatureVal, float socVal){ // -------------------------- 发送第一帧:电压 + 温度 -------------------------- TxHeader.DLC = 8; // 数据长度:8字节(2个浮点) TxHeader.ExtId = 0; // 标准CAN模式,扩展ID置0 TxHeader.IDE = CAN_ID_STD; // 使用标准ID TxHeader.RTR = CAN_RTR_DATA; // 发送数据帧 TxHeader.StdId = 0x102; // 第一帧标识ID TxHeader.TransmitGlobalTime = DISABLE; // 将浮点值转换为字节数组存入TxData memcpy(&TxData[0], &voltageVal, sizeof(float)); memcpy(&TxData[4], &temperatureVal, sizeof(float)); // 发送第一帧,等待发送完成(可选,避免邮箱溢出) HAL_CAN_AddTxMessage(hcan, &TxHeader, TxData, &TxMailbox); while(HAL_CAN_IsTxMessagePending(hcan, TxMailbox)); // -------------------------- 发送第二帧:SOC -------------------------- TxHeader.DLC = 4; // 数据长度:4字节(1个浮点) TxHeader.StdId = 0x103; // 第二帧标识ID memcpy(&TxData[0], &socVal, sizeof(float)); HAL_CAN_AddTxMessage(hcan, &TxHeader, TxData, &TxMailbox); while(HAL_CAN_IsTxMessagePending(hcan, TxMailbox)); }
主函数调用
你的原调用代码无需修改,现在函数已支持传入三个浮点参数:
main_function(dev_address); SendFloatsOverCAN(&hcan2, voltage, temperature, SOC); HAL_Delay(500);
接收端改造
核心逻辑
在CAN接收回调中,根据帧的StdId判断当前接收的是哪部分数据,将字节数组还原为浮点值。
完整接收代码
// 全局/局部变量定义 CAN_RxHeaderTypeDef RxHeader; uint8_t RxData[8]; float receivedVoltage; float receivedTemperature; float receivedSOC; void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) { HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData); // 根据帧ID匹配对应的数据块 switch(RxHeader.StdId){ case 0x102: // 接收第一帧:电压+温度 memcpy(&receivedVoltage, &RxData[0], sizeof(float)); memcpy(&receivedTemperature, &RxData[4], sizeof(float)); break; case 0x103: // 接收第二帧:SOC memcpy(&receivedSOC, &RxData[0], sizeof(float)); break; default: // 处理未知帧(可选) break; } }
额外注意事项
- 字节序一致性:STM32默认采用小端模式,若接收端为大端设备,需手动转换字节顺序后再还原浮点值。
- 发送等待逻辑:代码中的
while循环用于等待当前帧发送完成,避免CAN发送邮箱溢出;若你的工程对实时性要求高,可改用中断方式判断发送完成。 - 帧ID规划:可根据实际需求调整
StdId,只要发送端和接收端保持一致即可。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

