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(¤t, 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, ×tamp) == 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}}}
}