资讯动态

用 DeepSeek 将 Modbus 协议文档自动化为 Qt 枚举与寄存器结构体?「文档解析+AI生成+编译验证」的代码工厂实践

发布时间:2026/8/29 20:55:24 来源:尧图企业网站定制
第一步把 PDF 或 Excel 寄存器表转成CSV先人工用 Python 脚本或者 WPS 另存为把寄存器表转成统一 CSV列名固定register_addr, register_name, register_type, enum_values, description保持数据干净。# 假设你已经从 PDF 复制粘贴到了 excel.csv import pandas as pd df pd.read_excel(modbus_table.xlsx) # 清洗去空行、去注释、统一列名 df df.dropna(subset[register_addr]) df.to_csv(modbus_clean.csv, indexFalse) print(f清洗完成共 {len(df)} 个寄存器)注意现场表格里经常有合并单元格地址列是空的但下面几行都引用。清洗时务必 fillna(methodffill)否则 AI 拿到错地址生成的代码会出错。第二步写个 Prompt让 DeepSeek产生Qt 头文件把 prompt 写成「合同」清晰列出输入 CSV 路径、输出头文件格式、枚举命名规则、结构体对齐方式。以下是稳定的 prompt 模板// 你的项目里放个 prompt_template.txt // 内容如下用你实际 CSV 路径替换 /* 你是 Qt 嵌入式专家。读取 modbus_clean.csv生成 modbus_regs.h。 要求 1. 每个 register_name 生成一个枚举常量按地址升序排列。 2. 枚举名用驼峰前缀 MODBUS_REG_。 3. 每个寄存器生成一个结构体成员类型 uint16_t注释写 description。 4. 枚举值与寄存器地址一一对应禁止跳变。 5. 生成一个寄存表数组按地址顺序排列。 6. 代码风格Qt 5.15C17带 #pragma once。 7. 如果 enum_values 列非空额外生成一个子枚举名字为 寄存器名_Value。 */把 prompt 和 CSV 一起发给 DeepSeek API拿到返回的 .h 文件内容。我通常直接存成 modbus_regs.h。第三步CMake 编译验证脚本# CMakeLists.txt 放在同目录下 cmake_minimum_required(VERSION 3.16) project(modbus_gen_check) set(CMAKE_CXX_STANDARD 17) find_package(Qt5 REQUIRED COMPONENTS Core) add_executable(check_main main.cpp) target_include_directories(check_main PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(check_main Qt5::Core)// main.cpp —— 只包含头文件静态断言检查枚举连续性 #include modbus_regs.h #include type_traits // 编译期检查枚举按地址升序且无重复 static_assert(MODBUS_REG_OFFSET MODBUS_REG_MODE, 地址乱序); static_assert(MODBUS_REG_MODE MODBUS_REG_STATUS, 地址乱序); int main() { // 故意引用一次防止编译器优化掉 volatile auto x sizeof(modbus_reg_table); return x 0; // 返回1表示表为空会报错 }如果编译出错把错误信息返 DeepSeek修改两轮后基本稳定。注意如果 AI 生成了大括号初始化数组检查 C11 的列表初始化是否满足别用 C14 特性老编译器编译不过。第四步集成到 Qt 工程加互斥锁和缓存别让 UI 卡死代码生成验证通过后别直接裸奔。工业现场寄存器读得太勤UI 线程会卡。咱们包一层单例带 QReadWriteLock 和 100ms 缓存保证 7x24 稳定。// ModbusRegCache.h class ModbusRegCache { public: static ModbusRegCache instance() { static ModbusRegCache c; return c; } uint16_t read(uint16_t addr) { QReadLocker locker(m_lock); auto it m_cache.find(addr); if (it ! m_cache.end() m_lastUpdate.elapsed() 100) { return it.value(); } // 实际走 Modbus 请求这里省略 uint16_t val m_modbus-readRegister(addr); m_cache[addr] val; m_lastUpdate.restart(); return val; } private: ModbusRegCache() : m_modbus(nullptr) {} QModbusClient* m_modbus; // 你自己的通信对象 QHashuint16_t, uint16_t m_cache; QReadWriteLock m_lock; QElapsedTimer m_lastUpdate; };第五步整个流程挂到 Git Hook 上以后改文档自动触发#!/bin/bash # auto_gen.sh —— 一键生成验证 python3 clean.py \ python3 call_deepseek.py \ cd build cmake .. make -j4 if [ $? -ne 0 ]; then echo Modbus 头文件生成或编译失败禁止提交 exit 1 fi

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价