0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看威廉希尔官方网站 视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Modbus TCP编程与实验

瑞萨MCU小百科 来源:瑞萨MCU小百科 2025-01-03 09:27 次阅读

11.7 Modbus TCP编程与实验

本课程并没有支持Modbus TCP协议的传感器,所以使用将会编写2个程序:

①modbus_server_tcp.c:interwetten与威廉的赔率体系 一个Modbus TCP传感器

②modbus_client_tcp.c:操作传感器

程序结构如下图所示:

9c14dd12-c8be-11ef-9310-92fbcf53809c.png

在硬件上无需进行任何特殊的连接。

本节源码位于如下目录:

9c34e8b4-c8be-11ef-9310-92fbcf53809c.png

下面以情景分析的方法讲解代码。假设在开发板上执行如下命令:

左右滑动查看完整内容

# ./modbus_server_tcp 127.0.0.1 &
# ./modbus_client_tcp 127.0.0.1 led1 on

11.7.1 server初始化与等待连接

在“modbus_server_tcp.c”中,代码如下:

左右滑动查看完整内容

41 ctx = modbus_new_tcp(argv[1], 1502);
42 if (ctx == NULL) {
43 fprintf(stderr, "Unable to allocate libmodbus context
");
44 return -1;
45 }
46
47 //modbus_set_slave(ctx, SERVER_ID);
48
49 mb_mapping = modbus_mapping_new_start_address(0,
50 NB_BITS, /* 5 个 DO 寄存器,对应 beep1,beep2,led1,led2,led3 */
51 0,
52 NB_INPUT_BITS,
53 0,
54 NB_REGISTERS,
55 0,
56 NB_INPUT_REGISTERS); /* 2 个 AI 寄存器,对应温度和湿度 */
57 memset(mb_mapping->tab_bits, 0, NB_BITS);
58 memset(mb_mapping->tab_input_registers, 0, NB_INPUT_REGISTERS*2);
59
60 memset(old_bits, 0, NB_BITS);
61 memset(old_regs, 0, NB_INPUT_REGISTERS*2);
62
63 s = modbus_tcp_listen(ctx, 1);
64 modbus_tcp_accept(ctx, &s);

第41行:分配一个modbus_t结构体,里面含有IP和端口

第47行:设置自己的传感器地址,这行被注释掉了,在Modbus TCP协议里,即使客户端使用不同的设备地址发来请求,server端都会接收到这些所有请求(它忽略设备地址)。

第49~56行:分配Modbus寄存器。它根据《11.5.2 传感器点表》来模拟一个传感器。

第57~58行:设置DO、AI寄存器初始值为0。

第60~61行:设置2个数组的值为0,这2个数组将用来跟Modbus寄存器进行比较,这样才能知道Client 程序有没有修改这些值。

第63~64行:这是跟Modbus RTU协议不同的地方,它们初始化socket,等待客户端连接。

11.7.2 client初始化与发起连接

在“modbus_client_tcp.c”中,代码如下:

左右滑动查看完整内容

33 ctx = modbus_new_tcp(argv[1], 1502);
34 if (ctx == NULL) {
35 fprintf(stderr, "Unable to allocate libmodbus context
");
36 return -1;
37 }
38
39 modbus_set_slave(ctx, SERVER_ID);
40
41 if (modbus_connect(ctx) == -1) {
42 fprintf(stderr, "Connection failed: %s
", modbus_strerror(errno));
43 modbus_free(ctx);
44 return -1;
45 }

第33行:分配一个modbus_t结构体,设置IP和端口。

第39行:设置要访问的Modbus传感器地址。

第41行:发出连接请求。

11.7.3 server等待请求

在“modbus_server_tcp.c”中,代码如下:

左右滑动查看完整内容

66 while (1)
67 {
68 do {
69 rc = modbus_receive(ctx, query);
70 /* Filtered queries return 0 */
71 } while (rc == 0);
72

第69行:等待client发来请求。

11.7.4 client 发出请求

在“modbus_client_tcp.c”中,代码如下:

左右滑动查看完整内容

65 if (!strcmp(argv[2], "beep1"))
66 addr = 0;
67 if (!strcmp(argv[2], "beep2"))
68 addr = 1;
69 if (!strcmp(argv[2], "led1"))
70 addr = 2;
71 if (!strcmp(argv[2], "led2"))
72 addr = 3;
73 if (!strcmp(argv[2], "led3"))
74 addr = 4;
75
76 if (addr == -1)
77 {
78 usage(argv[0]);
79 return -1;
80 }
81
82 if (!strcmp(argv[3], "on"))
83 status = 1;
84 else
85 status = 0;
86
87 rc = modbus_write_bit(ctx, addr, status);
88 if (rc == 1)
89 {
90 printf("modbus_write_bit ok
");
91 }
92 else
93 {
94 printf("modbus_write_bit err: %d, %s
", rc, strerror(errno));
95 }

第65~85行:根据参数设置addr、status。

第87行:发出“写AO寄存器的请求”。

11.7.5 server处理请求并回应

在“modbus_server_tcp.c”中,代码如下:

左右滑动查看完整内容

75 if (rc >= 0) {
76
77 printf("Get query for UID %d
", query[6]);
78
79 /* 使用随机数模拟温度、湿度 */
80 mb_mapping->tab_input_registers[0] = rand() % 1000; /* 温度,单位:0.1C */
81 mb_mapping->tab_input_registers[1] = rand() % 1000; /* 湿度,单位:0.1% */
82
83 rc = modbus_reply(ctx, query, rc, mb_mapping);
84 }
85 if (rc == -1) {
86 printf("Connection closed!
");
87 modbus_close(ctx);
88 modbus_tcp_accept(ctx, &s);
89 }
90
91 /* 根据 client 设置的数值,假装操作蜂鸣器和 LED */
92 if (mb_mapping->tab_bits[0] != old_bits[0])
93 {
94 printf("set beep1 %s
", mb_mapping->tab_bits[0] ? "on" : "off");
95 old_bits[0] = mb_mapping->tab_bits[0];
96 }
97
98 if (mb_mapping->tab_bits[1] != old_bits[1])
99 {
100 printf("set beep2 %s
", mb_mapping->tab_bits[1] ? "on" : "off");
101 old_bits[1] = mb_mapping->tab_bits[1];
102 }
103
104 if (mb_mapping->tab_bits[2] != old_bits[2])
105 {
106 printf("set led1 %s
", mb_mapping->tab_bits[2] ? "on" : "off");
107 old_bits[2] = mb_mapping->tab_bits[2];
108 }
109
110 if (mb_mapping->tab_bits[3] != old_bits[4])
111 {
112 printf("set led2 %s
", mb_mapping->tab_bits[4] ? "on" : "off");
113 old_bits[3] = mb_mapping->tab_bits[4];
114 }
115
116 if (mb_mapping->tab_bits[4] != old_bits[4])
117 {
118 printf("set led3 %s
", mb_mapping->tab_bits[4] ? "on" : "off");
119 old_bits[4] = mb_mapping->tab_bits[4];
120 }

第77行:打印client端发来的请求包里的“设备地址”,你可以根据这个“设备地址”去操作不同的设备,本程序未使用它。

第80~81行:使用随机数填充AO寄存器模拟温湿度。如果client读取温湿度的话,下面第83行的“modbus_reply”就会回复这些温湿度值。

第83行:使用“modbus_reply”发出回复包给client。

第85~89行:如果出错,重新等待client建立连接。

第91~120行:根据client发来的数据,操作硬件(这里仅仅是打印信息)。

11.7.6 上机实验

把代码上传到Ubuntu。

然后,在Ubuntu下执行如下命令进行编译:

左右滑动查看完整内容

$ source /opt/remi-sdk/environment-setup-aarch64-poky-linux
$ make
$ scp modbus_client_tcp root@192.168.5.9:/home/root
$ scp modbus_server_tcp root@192.168.5.9:/home/root

最后,在开发板上执行如下命令(先执行 modbus_server):

左右滑动查看完整内容

# cd /home/root
# ./modbus_server_tcp 127.0.0.1 &
# ./modbus_client_tcp 127.0.0.1 led1 on
Get query for UID 4
set led1 on
modbus_write_bit ok
Connection closed!
# ./modbus_client_tcp 127.0.0.1 read
Get query for UID 4
Temprature = 38.6C, Humity = 49.2%
Get query for UID 4
Temprature = 64.9C, Humity = 42.1%
Get query for UID 4
Temprature = 36.2C, Humity = 2.7%

需要产品及方案支持

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2551

    文章

    51191

    浏览量

    754356
  • MODBUS
    +关注

    关注

    28

    文章

    1810

    浏览量

    77069
  • 编程
    +关注

    关注

    88

    文章

    3623

    浏览量

    93796
  • TCP
    TCP
    +关注

    关注

    8

    文章

    1370

    浏览量

    79127

原文标题:Modbus TCP编程与实验 - RZ MPU工业控制教程连载(44)

文章出处:【微信号:瑞萨MCU小百科,微信公众号:瑞萨MCU小百科】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Modbus TCP通信报文解析

    Modbus TCP是在TCP/IP网络上运行的Modbus的实现,旨在允许Modbus ASCII/RTU协议在基于
    发表于 09-20 15:55 3w次阅读
    <b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>通信报文解析

    LabVIEW Modbus TCP通讯

    触摸屏与上位机通讯,HMI支持Modbus TCP,上位机是LabVIEW编程实现,下载了Modbus library,但是无法通讯,请高手指教 1、硬件如何连接,是不是用网线直接将电
    发表于 12-14 08:49

    Modbus TCPModbus RTU的实现

    使用ZLSN2040、NETCOM2040实现Modbus TCPModbus RTU的转化。1.Modbus TCP
    发表于 08-10 10:04

    Modbus TCP如何使用

    大家好。我有ApIC32 MX575 F512L,它使用了Modbus TCP在从配置(它完美地工作)。现在,我需要实现另一个软件(也就是FPIC32 MX575 F512L),使主板工作在主模式中
    发表于 01-08 14:25

    如何快速实现Modbus RTU和Modbus TCP协议转换?

    采集多种设备边缘计算过滤、报警、跳变、公式、本地编程等云端适配接入各种平台,支持定制化适配远程运维远程管理、远程运维网关及现场设备特色功能串口转发、Modbus TCP转发、设备校时、防拆锁定
    发表于 08-18 18:36

    Modbus/TCP通讯配置

    MODBUSTCP 是简单的、中立厂商的用于管理和控制自动化设备的MODBUS 系列通讯协议的派生产品,它覆盖了使用TCP/IP 协议的Intranet和Internet环境中MODBUS 报文
    发表于 09-30 09:13 38次下载
    <b class='flag-5'>Modbus</b>/<b class='flag-5'>TCP</b>通讯配置

    Modbus TCP通讯协议概述

    Modbus TCP通讯概述 MODBUS/TCP是简单的、中立厂商的用于管理和控制自动化设备的MODBUS系列讯协议的派生产品,显而
    的头像 发表于 01-04 17:51 3w次阅读
    <b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>通讯协议概述

    Modbus RTU和Modbus TCP的区别

    Modbus RTU和Modbus TCP的区别: 1.概念不同:MODBUS是一种标准的工业控制数据交换协议,可以通过RTU和ASCII交换协议数据。RTU通过二进制数据直接传输数据
    发表于 08-03 17:00 5.4w次阅读

    S7-1200 Modbus TCP通信指令块编程教程

    S7-1200 Modbus TCP通信指令块编程教程免费下载。
    发表于 03-28 16:08 10次下载

    Modbus TCP常见问题

    Modbus RTU和 Modbus TCP的区别?
    的头像 发表于 12-19 14:57 3362次阅读

    ModBus RTU 与 ModBus TCP

    一、两个密切相关的协议:RTU 与 TCP ModBus RTU和ModBus TCP作为ModBus协议的两个主要变体,传统上,
    的头像 发表于 02-07 10:05 3037次阅读

    如何仿真Modbus_TCP

    仿真Modbus_TCP
    的头像 发表于 02-07 10:16 5050次阅读
    如何仿真<b class='flag-5'>Modbus_TCP</b>

    Ethernet/IP转Modbus TCP网关

    Ethernet/IP转Modbus TCP网关,YC-EIP-TCP工业级EtherNet/IP 网关,支持ModBus主从站,即插即用 无需编程
    的头像 发表于 02-27 17:50 492次阅读
    Ethernet/IP转<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>网关

    EtherCAT转Modbus TCP协议网关(JM-ECT-TCP

    JM-ECT-TCP网关实现EtherCAT网络与Modbus TCP网络之间的数据通讯,即将Modbus TCP设备转换为EtherCAT
    的头像 发表于 09-07 17:05 355次阅读
    EtherCAT转<b class='flag-5'>Modbus</b> <b class='flag-5'>TCP</b>协议网关(JM-ECT-<b class='flag-5'>TCP</b>)

    MODBUS TCP 转 CANOpen

    产品概述 SG-TCP-COE-210 网关可以实现将 CANOpen 接口设备连接到 MODBUS TCP 网络中。用户不需要了解具体的 CANOpen 和 Modbus
    的头像 发表于 09-24 13:59 286次阅读
    <b class='flag-5'>MODBUS</b> <b class='flag-5'>TCP</b> 转 CANOpen