目录

qt-stm32-发送接受浮点数以及两字节数

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(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(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
            }
        }
    }
}