news 2026/6/10 20:23:16

qt开发的modbus-tcp远程控制主机上位机和stm32从机源码,实现了modbus 01...

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
qt开发的modbus-tcp远程控制主机上位机和stm32从机源码,实现了modbus 01...

qt开发的modbus-tcp远程控制主机上位机和stm32从机源码,实现了modbus 01 02 03 04 05 06 10 F功能码(modbus不是使用第三方库包括qmodbus,都是是自己写的),并在此基础上结合stm32从机实现了四遥功能:遥测遥控遥信遥调 stm32端采用野火指南者开发板和w5500以太网模块。 从机程序不限于野火板子只是四遥功能采用了板子的led灯按键和adc引脚,如换其他板子改一下引脚就可以。 后面有资料提供,四遥功能包括:远程采集adc数据实时刷新标准浮点数转换,感知远程按键信号,按键按上位机信号灯点亮,按键关闭信号灯关闭,点击三个自定义按钮控制三路led灯点亮(实时),遥调下发保持寄存器数值,通过自定义仪表盘读取设定值。

手搓Modbus-TCP协议的实战记录来咯!这次用Qt5撸了个上位机,搭配STM32F103+W5500搞定了工业控制领域常用的四遥功能。不用qmodbus库不靠现成轮子,从TCP报文解析到功能码实现全流程硬核开发,摸鱼时间都搭进去了(笑)


上位机核心:暴力拆解Modbus报文

自己实现协议栈最爽的就是完全掌控数据流。举个读取保持寄存器的03功能码处理:

QByteArray ModbusRequest::buildReadHoldingRegisters(int slaveID, int startAddr, int count) { QByteArray frame; QDataStream stream(&frame, QIODevice::WriteOnly); stream.setByteOrder(QDataStream::BigEndian); stream << quint8(slaveID) << quint8(0x03) // 功能码 << quint16(startAddr) << quint16(count); appendCRC16(frame); return frame; }

这段代码生成的报文结构绝对标准:设备地址+功能码+起始地址+寄存器数量+CRC校验。注意字节序必须用Big-Endian,否则设备端会直接丢包。当年在这里踩坑导致三天没收到正确响应...


从机端骚操作:寄存器映射黑科技

STM32端采用寄存器地址映射策略,把硬件状态直接挂到modbus地址空间:

// 保持寄存器映射表 __IO uint16_t holdingRegs[HOLDING_REG_NUM] = { 0x0000, // 设备状态 0x1388, // 初始阈值 //...其他寄存器 }; // ADC值自动更新 void UpdateHoldingRegisters(void) { holdingRegs[REG_ADC1_VAL] = (uint16_t)(get_adc_value(ADC1) * 100); // 浮点转定点 }

这里把ADC原始值放大100倍转为整数存储,上位机收到后除以100还原浮点数。实测比直接传浮点更稳定,尤其在一些老版本PLC上兼容性更好。


四遥功能落地实操

  1. 遥测:ADC采集线程500ms轮询
// Qt端定时拉取数据 connect(&timer, &QTimer::timeout, [=](){ sendReadRequest(SLAVE_ID, REG_ADC_BASE, 3); }); // 收到响应后更新UI仪表盘 void updateDashBoard(const ModbusResponse& resp) { double voltage = resp.getRegister(0) / 100.0; ui->voltageGauge->setValue(voltage); }
  1. 遥控:LED控制直接挂钩线圈状态
// STM32端线圈状态监听 if(coils[COIL_LED1] != led1_status){ HAL_GPIO_WritePin(LED1_GPIO, coils[COIL_LED1]); led1_status = coils[COIL_LED1]; }
  1. 遥信:按键状态通过离散输入上报
// 按键中断服务函数里置位标志 void EXTI0_IRQHandler(){ discreteInputs[DI_KEY1] = 1; __HAL_GPIO_EXTI_CLEAR_IT(KEY1_PIN); }
  1. 遥调:写保持寄存器实现参数下发
// 上位机下发设定值 void sendAdjustment(float value) { uint16_t raw = static_cast<uint16_t>(value * 100); sendWriteRequest(SLAVE_ID, REG_SET_VALUE, raw); }

避坑指南

  1. W5500硬件流控必须使能,否则大数据量会丢包
  2. STM32的HAL库ETH驱动需要调整RxBuffer数量,默认值太小
  3. Qt的TCP粘包处理要加超时机制,推荐使用状态机解析
  4. 寄存器地址记得做越界检查,防止设备跑飞

源码里还有自定义仪表盘控件和工业风UI设计,需要完整工程的老铁可以私信。下期准备分享如何用这套框架对接西门子PLC,想看的评论区扣个1~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 10:34:51

手把手教程:基于Modbus协议的上位机开发实战案例

手把手教你用 C# 实现 Modbus 上位机&#xff1a;从协议解析到工业实战你有没有遇到过这样的场景&#xff1f;工厂里一堆传感器、电表、PLC各自为政&#xff0c;数据散落一地&#xff0c;想做个监控系统却无从下手。别急——Modbus 协议就是为解决这个问题而生的。它不像 OPC U…

作者头像 李华
网站建设 2026/6/10 10:28:08

24B多模态Magistral 1.2:本地部署新突破

24B多模态Magistral 1.2&#xff1a;本地部署新突破 【免费下载链接】Magistral-Small-2509-bnb-4bit 项目地址: https://ai.gitcode.com/hf_mirrors/unsloth/Magistral-Small-2509-bnb-4bit 导语 Magistral 1.2多模态大模型实现240亿参数本地部署突破&#xff0c;通过…

作者头像 李华
网站建设 2026/6/10 10:33:26

SeedVR:7B扩散模型如何解锁视频修复新可能?

SeedVR&#xff1a;7B扩散模型如何解锁视频修复新可能&#xff1f; 【免费下载链接】SeedVR-7B 项目地址: https://ai.gitcode.com/hf_mirrors/ByteDance-Seed/SeedVR-7B 导语 字节跳动最新发布的SeedVR-7B扩散模型&#xff0c;以70亿参数规模突破传统视频修复技术瓶颈…

作者头像 李华
网站建设 2026/6/10 0:28:28

快速理解ARM64异常级别(EL0-EL3)切换原理

深入理解ARM64异常级别&#xff08;EL0-EL3&#xff09;的切换机制 你有没有想过&#xff0c;当你在手机上打开一个App时&#xff0c;这个程序是如何被“限制”住的&#xff1f;它为什么不能随意读取你的指纹数据、修改系统内存&#xff0c;甚至关掉整个操作系统&#xff1f;答…

作者头像 李华
网站建设 2026/6/10 10:31:01

Qwen2.5-7B多语言混合输入:复杂场景处理方案

Qwen2.5-7B多语言混合输入&#xff1a;复杂场景处理方案 1. 引言&#xff1a;为何需要多语言混合输入的复杂场景支持&#xff1f; 随着全球化业务的快速扩展&#xff0c;用户对大语言模型&#xff08;LLM&#xff09;在多语言环境下的无缝交互能力提出了更高要求。尤其是在跨境…

作者头像 李华
网站建设 2026/6/10 11:01:52

Qwen2.5-7B联邦学习:隐私保护训练

Qwen2.5-7B联邦学习&#xff1a;隐私保护训练 1. 引言&#xff1a;大模型时代下的隐私挑战与联邦学习的融合 随着大语言模型&#xff08;LLM&#xff09;在自然语言处理、代码生成、多模态理解等领域的广泛应用&#xff0c;以 Qwen2.5-7B 为代表的开源模型正逐步成为企业级AI应…

作者头像 李华