IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> Win10编译和测试libModbus -> 正文阅读

[嵌入式]Win10编译和测试libModbus

前题

项目需要使用到 Modbus 协议,不想自己写一个协议栈,虽然 Modbus 协议比较简单。

可用的 Modbus 协议栈

libModubs

开源代码。官网地址为:https://libmodbus.org

freeModubs

开源代码。官网地址为:https://www.embedded-solutions.at/en/freemodbus/。可以从 github 中下载,https://github.com/cwalter-at/freemodbus

emModubs

segger 公司的。商业代码。不出钱是没法用的。https://www.segger.com/downloads/emmodbus/

个人选择

emModbus,商业代码。穷逼买不起,放弃。
freeModbus以前用过,但是好久没有更新了,放弃。最近更新是三年前。
libModbus还在正常维护。最新版本是 3.1.6,更新日期为 2019 年 9 月。

编译 libModbus

环境

Win10系统,编译器为 Visual Studio 2019。没有使用 MSYS2 或者 CYGWin 来编译。

生成 sln

这个不是我手动生成的,老版本里有。从老版本中拷贝过来即可。对应的文件在 libmodbus-3.1.6/src/win32 这个目录。

编译 DLL

错误1:缺少 config.h

将 libmodbus-3.1.6 目录下 config.h.in 拷贝过来,改名为 config.in 即可。

错误2:LNK111

如下:
在这里插入图片描述
是因为设置的版本号为 1.0.0 导致的语法错误。

解决方案

删除版本号就可以解决问题。在设置(项目>设置>链接器)上删除“版本”条目。如下图。
在这里插入图片描述
删除上图中的 1.0.0,即可解决这个问题。

结果

在这里插入图片描述
如上图所示,modbus.dll 和 modbus.lib 就生成成功。

测试libModbus

必须软件

Modbus Master

推荐使用 Modbus Poll 软件。

Modbus Slave

推荐使用 Modbus Slave 软件。

虚拟串口

如果没有现成的 Modbus 设备或者第二台计算机。那么虚拟串口就是必须的。
推荐使用:vspd虚拟串口软件。该软件可以虚拟出配对的两个串口。这样我们就可以运行 Modbus 软件来测试了。
软件安装好,运行起来如下图:
在这里插入图片描述
如上图,我的工控机有物理串口 7 7 7 个。虚拟串口一对。如果没有虚拟串口,选择添加即可。

虚拟串口测试
Modbus Master

在这里插入图片描述
如上图,打开 COM9,配置为 9600 N 8 1,使用 Modbus RTU 协议。

Modbus Slave

在这里插入图片描述
如上图,使用 COM10,9600 N 8 1,Modbus RTU 协议。
这样就可以发现两个软件成功开始通信。
在这里插入图片描述

Modbus Master 测试

VSDP + Modbus Poll + 自己的程序作为一个主机。这样我们只需要向串口发送 03 00 00 00 0A C5 CD 这个指令就可以了。

添加 Modbus Master RTU 项目

在 Visual Studio 2019 中选择“文件”->“新建”->“项目”。选择 C++ 空项目。配置如下图所示:
在这里插入图片描述
项目建立后。如下图所示。
在这里插入图片描述

RTU代码

在 RTU_Master 中添加一个空白的 cpp 文件,名字为 rtu_master.cpp,并加入到项目中。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
//#include <windows.h>
#include "modbus.h"

#pragma comment(lib, "modbus.lib")
#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[]) {
    modbus_t* ctx;
    int rc;
    uint16_t tab_reg[64];

    //打开
    ctx = modbus_new_rtu("COM9", 9600, 'N', 8, 1);
    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n",
            modbus_strerror(errno));
        modbus_free(ctx);

    }
    //打开调试模式
    modbus_set_debug(ctx, 1);
    modbus_set_response_timeout(ctx, 1, 0);//设置响应时间

    //设置从机地址
    modbus_set_slave(ctx, 1);
    for (int i = 1; i <= 100; i++) {
        rc = modbus_read_registers(ctx, 0x00, 0x0A, tab_reg);
        //rc = modbus_read_input_registers(ctx, 0x00, 0x0A, tab_reg);
        if (rc == -1) {
            fprintf(stderr, "%s\n", modbus_strerror(errno));
            return -1;
        }
        //输出结果
        for (int j = 0; j < rc; j++) {
            printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
        }
        Sleep(1000);
    }

    //关闭设备
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}


配置头文件路径

这个程序中,我们需要使用到 modbus.h。所以需要指定对应的路径。如下图所示。
在这里插入图片描述

配置库文件路径

这个程序中,我们需要使用到 modbus.lib。所以需要指定对应的路径。如下图所示。
在这里插入图片描述

配置DLL文件路径

这个程序中,我们需要使用到 modbus.dll。所以需要指定对应的路径。如下图所示。
在这里插入图片描述

运行结果

在这里插入图片描述
上图的数据解码有问题。先不管了。

添加 Modbus Master TCP 项目

TCP代码
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
//#include <windows.h>
#include "modbus.h"
#ifdef _WIN32
# include <winsock2.h>
#else
# include <sys/socket.h>
#endif

#pragma comment(lib, "modbus.lib")
#pragma comment(lib, "ws2_32.lib")

int main(int argc, char* argv[]) {
    modbus_t* ctx;
    int rc;
    uint16_t tab_reg[64];

    //打开
    ctx = modbus_new_tcp("127.0.0.1", 1502);
    //打开调试模式
    modbus_set_debug(ctx, 1);
    modbus_set_response_timeout(ctx, 1, 0);//设置响应时间
    //设置从机地址
    modbus_set_slave(ctx, 1);

    if (modbus_connect(ctx) == -1) {
        fprintf(stderr, "Connection failed: %s\n",
            modbus_strerror(errno));
        modbus_free(ctx);
    }

#if 0
    int server_socket = modbus_tcp_listen(ctx, 1);
    if (server_socket == -1) {
        fprintf(stderr, "Unable to listen TCP: %s\n",
            modbus_strerror(errno));
        modbus_free(ctx);
    }
    //modbus_tcp_accept(ctx, &server_socket);
#endif

    for (int i = 1; i <= 100; i++) {
        rc = modbus_read_registers(ctx, 0x00, 0x0A, tab_reg);
        //rc = modbus_read_input_registers(ctx, 0x00, 0x0A, tab_reg);
        if (rc == -1) {
            fprintf(stderr, "%s\n", modbus_strerror(errno));
            return -1;
        }
        //输出结果
        for (int j = 0; j < rc; j++) {
            printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
        }
        Sleep(1000);
    }

    //if (server_socket != -1) {
        //close(server_socket);
    //}

    //关闭设备
    modbus_close(ctx);
    modbus_free(ctx);

    return 0;
}

运行结果

在这里插入图片描述
上图的数据解码有问题。先不管了。

Modbus Slave 测试

待补充。今天先测试到这里,还有别的事情需要去搬砖。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-09-18 10:20:30  更:2021-09-18 10:21:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:52:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码