You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在STM32CubeIDE中通过标准CAN总线发送超8字节数据

如何在STM32CubeIDE中通过标准CAN发送超过8字节的多浮点数据

标准CAN单帧最大仅支持8字节数据,你需要发送的三个4字节浮点值(共12字节)必须拆分为两帧传输。以下是具体的代码改造方案,分发送端和接收端实现:

发送端改造

核心逻辑

将三个浮点值拆分为两帧:

  1. 第一帧发送电压+温度(合计8字节)
  2. 第二帧发送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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 06:55:55