Qt与STM32间浮点数及两字节数的发送与接收指南

void MainWindow::on_pushButton_4_clicked()
{
    TPCANMsg msg;
    bool ok;
    float dianliu = ui->lineEditdianliu->text().toFloat(&ok);
    
    // 输入验证
    if (!ok) {
        ui->status->setText("电流输入无效,请重新输入");
        return;
    }

    // 设置CAN消息参数
    msg.MSGTYPE = static_cast<BYTE>(ui->framegeshi->currentIndex());
    msg.ID = (ui->frameid->text().toUInt(&ok, 16)) & 0x7FF;
    msg.LEN = 5;  // 1字节信号 + 4字节浮点数
    
    // 固定信号字节
    msg.DATA[0] = 0xDD;

    // 将浮点数转换为4字节(考虑字节序)
    unsigned char* ptr = reinterpret_cast<unsigned char*>(&dianliu);
    
    // 假设接收端使用小端模式(默认与x86兼容)
    // 如果接收端是大端模式,需要反转字节顺序
    msg.DATA[1] = ptr[0];
    msg.DATA[2] = ptr[1];
    msg.DATA[3] = ptr[2];
    msg.DATA[4] = ptr[3];

    // 调试输出字节内容
    qDebug() << "发送电流数据 (HEX):"
             << QString::number(msg.DATA[0], 16)
             << QString::number(msg.DATA[1], 16)
             << QString::number(msg.DATA[2], 16)
             << QString::number(msg.DATA[3], 16)
             << QString::number(msg.DATA[4], 16);

    // 发送CAN消息
    TPCANStatus status = CAN_Write(PCAN_USBBUS1, &msg);

    if (status != PCAN_ERROR_OK) {
        QString error = QString("电流发送失败,错误代码: 0x%1").arg(status, 0, 16);
        ui->status->setText(error);
        return;
    }

    ui->status->setText(QString("电流设置成功: %1 A").arg(dianliu));
}

 下位机接受;

// 假设接收数据存储在 rxData[5]
if (rxData[0] == 0xDD) {
    // 提取浮点数字节
    unsigned char bytes[4] = {rxData[1], rxData[2], rxData[3], rxData[4]};
    float current;
    memcpy(&current, bytes, 4);
    printf("接收电流值: %f A\n", current);
}

 TPCANMsg msg;
    bool ok;
    int time=ui->lineEdittime->text().toInt(&ok,10);
    if (!ok || time< 0 || time > 9999) {
        ui->status->setText("占空比输入无效,请输入0~9999的整数");
        return;
    }
     msg.DATA[0] = 0xCC;
    msg.MSGTYPE = static_cast<BYTE>(ui->framegeshi->currentIndex());
    msg.ID = (ui->frameid->text().toUInt(&ok, 16)) & 0x7FF;
    msg.LEN = 3;
    msg.DATA[1]=(time>>8)&0xff;
    msg.DATA[2] = time& 0xFF;
    TPCANStatus status = CAN_Write(PCAN_USBBUS1, &msg);
    
    if (status != PCAN_ERROR_OK) {
        QString error = QString("发送失败,错误代码: 0x%1").arg(status, 0, 16);
        ui->status->setText(error);
        return;
    }
    
    qDebug() << "占空比设置成功: 信号=0xcc 数值=" << time<< "%";
    ui->status->setText(QString("占空比设置成功: 数值=%1%").arg(time));

上位机(Qt)接收代码


cpp

// 在MainWindow类中定义CAN接收线程或槽函数
void MainWindow::initCANReceiver() {
    // 启动定时器或线程持续读取CAN消息
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::readCANData);
    timer->start(10); // 每10ms读取一次
}

void MainWindow::readCANData() {
    TPCANMsg msg;
    TPCANStatus status;
    DWORD timestamp;

    // 读取CAN消息
    while (CAN_Read(PCAN_USBBUS1, &msg, &timestamp) == PCAN_ERROR_OK) {
        // 过滤特定ID的消息(假设目标ID为用户输入的ID)
        bool ok;
        uint targetID = ui->frameid->text().toUInt(&ok, 16) & 0x7FF;
        if (msg.ID != targetID) continue;

        // 解析数据(假设数据格式为3字节:[信号][高字节][低字节])
        if (msg.LEN >= 3 && msg.DATA[0] == 0xA1) {
            uint16_t dutyCycle = (msg.DATA[1] << 8) | msg.DATA[2];
            ui->status->setText(QString("接收占空比: %1%").arg(dutyCycle));
            qDebug() << "Received duty cycle:" << dutyCycle << "%";
        }
    }
}

下位机(STM32 HAL库)接收代码


c

// 在main.c中定义CAN接收回调函数
#include "stm32f1xx_hal.h"

CAN_HandleTypeDef hcan;
CAN_RxHeaderTypeDef rxHeader;
uint8_t rxData[8];

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) {
    // 读取CAN消息
    if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &rxHeader, rxData) == HAL_OK) {
        // 过滤特定ID的消息(假设目标ID为0x123)
        if (rxHeader.StdId == 0x123) {
            // 解析数据(假设数据格式为3字节:[信号][高字节][低字节])
            if (rxData[0] == 0xA1 && rxHeader.DLC >= 3) {
                uint16_t dutyCycle = (rxData[1] << 8) | rxData[2];
                // 应用占空比到PWM(示例代码)
                TIM1->CCR1 = dutyCycle; // 假设使用TIM1通道1输出PWM
            }
        }
    }
}

作者:Alan316

物联沃分享整理
物联沃-IOTWORD物联网 » Qt与STM32间浮点数及两字节数的发送与接收指南

发表回复