主要测试读保持寄存器,地址4xxxx开始。不废话直接上代码

下面是从站(server)代码:


#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
#include <iostream>#include "modbus.h"
#include "modbus-tcp.h"
#include "modbus-version.h"#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define NB_CONNECTION    5//读保持寄存器地址数据的定义
const uint16_t UT_REGISTERS_ADDRESS = 0;
/* Raise a manual exception when this adress is used for the first byte */
const uint16_t UT_REGISTERS_ADDRESS_SPECIAL = 0;
const uint16_t UT_REGISTERS_NB = 0x10;
const int UT_REGISTERS_TAB[] = { 0x022B, 0x0001, 0x0064 };
const float test[] = { 123.123, 4.012, 5.789, 12345.34, 223.4, 34.2, 33.44, 234.204};
/* If the following value is used, a bad response is sent.It's better to test with a lower value thanUT_REGISTERS_NB_POINTS to try to raise a segfault. */
const uint16_t UT_REGISTERS_NB_SPECIAL = 0x2;modbus_t *ctx = NULL;
int server_socket;
modbus_mapping_t *mb_mapping;static void close_sigint(int dummy)
{close(server_socket);modbus_free(ctx);modbus_mapping_free(mb_mapping);exit(dummy);
}int FloatTohex(float HEX)//浮点数到十六进制转换
{return *( int *)&HEX;
}int main(void)
{int master_socket;int rc;int header_length;fd_set refset;fd_set rdset;/* Maximum file descriptor number */int fdmax;ctx = modbus_new_tcp("10.88.33.26", 10086);header_length = modbus_get_header_length(ctx);//new一个modbus的映射空间Amb_mapping = modbus_mapping_new(0,//读线圈0,//读离散量输入UT_REGISTERS_ADDRESS + UT_REGISTERS_NB,//读保持寄存器0);//读输入寄存器if (mb_mapping == NULL){fprintf(stderr, "Failed to allocate the mapping: %s\n",modbus_strerror(errno));modbus_free(ctx);return -1;}/**初始化读保持寄存器**/for(int i=0; i<8; i++){uint16_t aimReg[2] = { 0 };MODBUS_SET_INT32_TO_INT16(aimReg, 0, FloatTohex(test[i]));std::cout<<std::hex<<FloatTohex(test[i])<<"; " << std::hex<<aimReg[0]<<", "<<std::hex<<aimReg[1]<<"\n";for(int j = 0; j< 2; j++){mb_mapping->tab_registers[UT_REGISTERS_ADDRESS+i*2+j]= aimReg[j];}}server_socket = modbus_tcp_listen(ctx, NB_CONNECTION);signal(SIGINT, close_sigint);/* Clear the reference set of socket */FD_ZERO(&refset);/* Add the server socket */FD_SET(server_socket, &refset);/* Keep track of the max file descriptor */fdmax = server_socket;for (;;){rdset = refset;if (select(fdmax+1, &rdset, NULL, NULL, NULL) == -1){perror("Server select() failure.");close_sigint(1);}/* Run through the existing connections looking for data to be* read */for (master_socket = 0; master_socket <= fdmax; master_socket++){if (FD_ISSET(master_socket, &rdset)){if (master_socket == server_socket){/* A client is asking a new connection */socklen_t addrlen;struct sockaddr_in clientaddr;int newfd;/* Handle new connections */addrlen = sizeof(clientaddr);memset(&clientaddr, 0, sizeof(clientaddr));newfd = accept(server_socket, (struct sockaddr *)&clientaddr, &addrlen);if (newfd == -1){perror("Server accept() error");}else{FD_SET(newfd, &refset);if (newfd > fdmax){/* Keep track of the maximum */fdmax = newfd;}printf("New connection from %s:%d on socket %d\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port, newfd);}}else{/* An already connected master has sent a new query */uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];modbus_set_socket(ctx, master_socket);rc = modbus_receive(ctx, query);if (rc != -1){modbus_reply(ctx, query, rc, mb_mapping);}else{/* Connection closed by the client, end of server */printf("Connection closed on socket %d\n", master_socket);close(master_socket);/* Remove from reference set */FD_CLR(master_socket, &refset);if (master_socket == fdmax){fdmax--;}}}}}}return 0;
}

我们可以通过modscan32工具来读取数据测试。

下面是主站(client)代码:

#include <stdio.h>#ifndef _MSC_VER
#include <unistd.h>
#endif#include <string.h>
#include <stdlib.h>
#include <errno.h>//包含Modbus相关头文件
#include "modbus.h"
#include "time.h"//相关参数设置
#define LOOP    1           //循环次数
#define ADDRESS_START   0       //测试寄存器起始地址
#define ADDRESS_END 15  //测试寄存器结束地址int FloatTohex(float HEX){ return *( int *)&HEX; }int main(void)
{modbus_t* ctx = NULL;int ret = -1;int nums = 0;int addr = 0;int i = 0;int tmp = 0;uint16_t* tab_rq_registers = NULL;uint16_t* tab_rp_registers = NULL;//设置随机种子srand((int)time(0));//1. 创建一个TCP类型的变量ctx = modbus_new_tcp("10.88.33.26", 10086);if (NULL == ctx){fprintf(stderr, "Error: %s\n", modbus_strerror(errno));return 1;}else{printf("设置TCP成功\n");}//2. 设置Debug模式ret = modbus_set_debug(ctx, TRUE);if (-1 == ret){fprintf(stderr, "Error: 设置Debug模式失败");modbus_free(ctx);return 1;}//3. 连接Serverret = modbus_connect(ctx);if (-1 == ret){fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));modbus_free(ctx);return 1;}//4. 计算需测试的寄存器个数nums = ADDRESS_END - ADDRESS_START;//5. 申请内存 保存发送和接收的数据tab_rq_registers = (uint16_t*)malloc((nums + 1) * sizeof(uint16_t));if (NULL == tab_rq_registers){fprintf(stderr, "malloc failed\n");modbus_free(ctx);return 1;}else{memset(tab_rq_registers, 0, (nums + 1) * sizeof(uint16_t));}//7. 测试保持寄存器的单个读写
//随机数字const float test[] = { 13.123, 24.012, 5.789, 233.23,11.22,33.44,55.66, 77.88};for(int i=0; i< 8; i++){uint16_t aimReg[2] = { 0 };MODBUS_SET_INT32_TO_INT16(aimReg, 0, FloatTohex(test[i]));for(int j = 0; j< 2; j++){tab_rq_registers[i*2+j]= aimReg[j];}}//换行printf("\n");addr = ADDRESS_START;ret = modbus_write_registers(ctx, addr, nums + 1, tab_rq_registers);if (nums + 1 != ret){printf("Error modbus_write_registers: %d\n", ret);printf("Address: %d nums: %d\n", addr, nums + 1);}else{//读取printf("success to write");}//8. 释放内存free(tab_rq_registers);//9. 断开连接modbus_close(ctx);modbus_free(ctx);return 0;
}

modbusTcp 从站和主站相关推荐

  1. 西门子Smart 485数据通讯读取和写入程序,modbustcp,modbus主站从站通讯

    西门子Smart 485数据通讯读取和写入程序,modbustcp,modbus主站从站通讯id=636632419056&

  2. 西门子、三菱、欧姆龙等PLC不编写程序实现ModbusTCP从站功能的案例

    案例所使用的IGT-SER智能网关可将几乎所有PLC的协议转成Modbus协议,不用PLC编程,只需通过网关的配置软件设置一下PLC寄存器地址与Modbus地址的对应关系即可:更详细的应用案例    ...

  3. python modbus-tk 实现三菱FX5U modbus-tcp 从站通讯

    一.三菱FX5U 从站设置 1. 打开GX works3 软件 2. 新建项目 3.按向导流程指示设置modbus-tcp从站功能                                   ...

  4. 西门子PLC S7-1200作为ModbusTCP从站数据交互

    设备类型 S7-1215C 协议 Modbus TCP  PLC作为服务端 测试工具:以太网调试助手 数据发送 00310000000608030000000E 0031 流水号 0000 固定 00 ...

  5. 基于STM32F767通过STM32CubeMX实现ModbusTCP从站(后续)

    基于STM32F767通过STM32CubeMX实现ModbusTCP读多为寄存器操作(后续) 由于上篇着重介绍了实现功能的代码,以至于我没有和大家讲清楚FreeModbus应该怎么移植,在此先抱歉浪 ...

  6. delphi tclientsocket接收不到返回数据_RS—485中教你主站发送报文结构、从站返回报文结构?系列11...

    作者:马乐 1.主站发送报文结构 大家可以看到我之前写的文章中的程序都是没有什么具体功能的,都是两个站点之间互相传递数据,这些数据我们只是看看是否可以正常接收发送,数据本身是没有任何含义的.很明显在实 ...

  7. modbus tcp主站和从站_Modbus-RTU 一主多从PLC无线通讯经典案例

    一.无线方案简介 该方案可适用于 3 台以上西门子 PLC,S7-200 或 S7-200Smart 之间实现一主多从Modbus 通讯协议的无线通讯. 适用 PLC 型号:S7-200 和 S7-2 ...

  8. modbus tcp主站和从站_ModBus的加深理解与实际应用举例

    今天主要讲一下怎么更加用简单的方式去理解ModBus协议. (一)什么是协议ModBus是一种协议,可以理解成一种语言.比如小王说的是汉语,小张说的是英语,如果小王和小张路上碰见了,那小王说了一堆,小 ...

  9. 1200PLC和Modbus485主站DCS系统通讯

    序言:西门子S7-1200.1500等网口PLC,与Modbus458主站DCS系统通讯.通过桥接器模块,无需编程,无需硬件组态,直接将Modbus的数据映射到PLC的DB块. 1.产品介绍 工业通讯 ...

最新文章

  1. MATLAB【七】———— matlab 高斯核使用,超像素图像模拟,矩阵转图像,深度相机模型实践实现
  2. jhipster 配置 mysql_JHipster技术栈定制 - JHipster Registry配置信息加密
  3. 数据库Sharding的基本思想和切分策略
  4. python中栈的描述是_数据结构与算法:Python语言描述 栈和队列.ppt
  5. Vue + webpack 项目实践
  6. Java数据库连接(JDBC)之二:Statement对象和PreparedStatement对象的使用
  7. 【Boost】系列02:内存管理之scoped_ptr智能指针
  8. Ruby Variable Scope 简单讲解
  9. 互斥锁和条件变量【原创总结】
  10. 西塘游(2007-08-14)
  11. Mysql的共享锁和排他锁(转载)
  12. python逻辑运算优先级_测试误区《二》 python逻辑运算和关系运算优先级
  13. Dynamic Web Module to 3.0 报错
  14. WPS插件开发流程(1)
  15. IDEA插件系列(81):Shifter插件——字符串操作
  16. linux编译mmplay,mplay编译与移植
  17. 山东省大学生软件设计大赛
  18. 程序员必知的8个Java开源IDE工具!你最钟意哪个?
  19. Hi3516开发笔记(十一):通过HiTools使用网口将uboot、kernel、roofts烧写进eMMC
  20. 写php程序出现乱码怎么办?

热门文章

  1. 决明子是一种中草药材
  2. 【软件测试】从企业版BOSS直聘,看求职简历,你没被面上是有原因的
  3. 专题---自定义实体类
  4. 华为交换机主备命令_华为交换机的配基命令大全
  5. python中ln怎么表示_Python基础篇(六)
  6. 定时任务Quartz的基本使用
  7. ArcGIS API for JavaScript 如何下载最新版
  8. 产品团队例会安排及流程
  9. 我的第一个C程序:冒险岛上星
  10. 基于大数据(Hadoop+Java+MySQL)的数码商城购物推荐系统设计与实现 文档+任务书+开题报告+文献综述+答辩PPT+项目源码及数据库文件