二十五、W5100S/W5500+RP2040树莓派Pico<Modebus TCP Server示例>

2023-11-11 02:28

本文主要是介绍二十五、W5100S/W5500+RP2040树莓派Pico<Modebus TCP Server示例>,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1 前言
  • 2 简介
    • 2 .1 什么是Modbus TCP?
    • 2.2 Modbus TCP指令介绍
    • 2.3 请求数据过程
    • 2.4 Modbus TCP协议优点
    • 2.5 Modbus TCP应用场景
  • 3 WIZnet以太网芯片
  • 4 Modbus TCP示例概述以及使用
    • 4.1 流程图
    • 4.2 准备工作核心
    • 4.3 连接方式
    • 4.4 主要代码概述
    • 4.5 结果演示
  • 5 注意事项
  • 6 相关链接

1 前言

  Modbus TCP协议是一种广泛应用于工业自动化、楼宇自控、能源管理等领域的数据通信协议。它基于TCP/IP网络,将Modbus协议封装在TCP/IP协议栈中,使用以太网作为物理层,通过TCP连接来实现设备之间的通信。

  W5100S/W5500是一款集成全硬件 TCP/IP 协议栈的嵌入式以太网控制器,同时也是一颗工业级以太网控制芯片。本教程将介绍W5100S/W5500以太网FTP应用的基本原理、使用步骤、应用实例以及注意事项,帮助读者更好地掌握这一技术。

2 简介

2 .1 什么是Modbus TCP?

  Modbus TCP实质上是Modbus协议(或Modbus RTU)在以太网TCP/IP网络上的运行。像Modbus RTU一样,Modbus TCP也采用客户端/服务器原理,但在这种情况下,客户端(主设备)会启动来自服务器(从设备)的请求和响应。任何设备都可以成为客户端或服务器。

  Modbus TCP不需要计算校验和,因为较低层已经提供了校验和保护。它使用10 Mbps的以太网标准来传输Modbus消息的整个结构。Modbus TCP协议提供了在单个网络中的许多设备之间的快速通信。

在这里插入图片描述

2.2 Modbus TCP指令介绍

Modbus TCP协议的数据帧可以分为两部分:MBAP和PDU。

MBAP(Modbus应用协议报文头):

  事务处理标识:一个递增的数字,每次发送消息递增一下,尽量不重复,因为占用2个字节,所以范围是:0~65535。
  协议标识:固定值0,表示Modbus TCP协议。
  长度:等于后面字段的长度。
  单元标识符:从机地址,也就是slave id。
PDU(协议数据单元):

  功能码:Modbus规定了多个功能,每个功能都设定一个功能码。你要对从机做什么操作,那么就在这里设定好,从机读取到这个数据就知道要做什么。
  数据:对于主机来说就是想要操作从机寄存器里的哪些数据。

在这里插入图片描述

Modbus TCP协议中定义了多种功能码,包括:

  0x01:读线圈
  0x05:写单个线圈
  0x0F:写多个线圈
  0x02:读离散量输入
  0x04:读输入寄存器
  0x03:读保持寄存器
  0x06:写单个保持寄存器
  0x10:写多个保持寄存器
每种功能码对应的操作和数据格式都有所不同。

例如,功能码0x01用于读取线圈,请求格式为“MBAP 功能码 起始地址H 起始地址L 数量H 数量L”

响应格式为“MBAP 功能码 数据长度 数据”。

2.3 请求数据过程

在典型的Modbus TCP通信过程中:

  1. Modbus TCP客户端(也称为主设备)向Modbus TCP服务器(也称为从设备)发送请求。这个请求包含功能码(指示要执行的操作类型),并且可能还包括数据地址和值,具体取决于功能码。
  2. 收到请求后,Modbus TCP服务器根据功能码处理它。例如,如果功能码指示读取操作,服务器将访问其内存中的指定数据地址,并准备相应的数据以进行响应。
  3. 然后,Modbus TCP服务器向客户端发送响应。这个响应包含功能码和请求的数据(对于读取操作)或对执行的操作的确认(对于写入操作)。
  4. Modbus TCP客户端接收到服务器的响应,并根据需要处理数据。

在这里插入图片描述

2.4 Modbus TCP协议优点

MODBUS TCP协议的优点包括:

  1. 灵活的网络拓扑结构:MODBUS TCP基于以太网通信,因此其网络拓扑结构更为灵活。从串行链路上一主多从的构造,演变为多客户端/多服务器端的构造模型。
  2. 易于寻址:使用MODBUS TCP,主站设备(客户端)可以通过IP地址找到MODBUS从设备(服务器),并通过MODBUS网关连接到另一个MODBUS RTU网络。
  3. 主从模式:MODBUS协议的工作原理是基于主从模式。在一个网络中,MODBUS协议通过主设备(客户端)和从设备(服务器)之间的请求-应答机制来交换信息。这种模式使得通信过程清晰且易于理解。
  4. 开放性:MODBUS是一种开放的协议,这意味着它可以被任何厂商的设备所支持,从而提高了设备间的互操作性。
  5. 简单性:MODBUS协议简单易懂,易于实现和维护。
  6. 高效性:MODBUS TCP协议在TCP/IP网络上运行,利用了TCP/IP协议的优点,如高效的数据传输、错误检测和修复等。

2.5 Modbus TCP应用场景

Modbus TCP协议的应用场景广泛,以下是一些主要的领域:

  1. 工业自动化:Modbus TCP协议在工业自动化领域被广泛应用,特别是在智能制造和工业物联网中。它允许设备之间进行可靠的通信,以实现生产过程的自动化和控制。
  2. 楼宇自动化:在楼宇自动化领域,Modbus TCP协议可以用于连接楼宇设备(如温度控制器、照明系统、安全系统等)以实现节能和舒适的室内环境。
  3. 能源管理:在能源管理领域,Modbus TCP协议可以用于监测和控制系统中的能源使用。通过连接能源测量设备和控制系统,可以实现实时能源监测和优化控制,降低能源消耗并提高能源效率。
  4. 过程控制:在过程控制领域,Modbus TCP协议可以用于连接传感器和执行器,以实现实时监控和控制。它可以应用于各种工业过程,如化工、制药、食品加工等。
  5. 智能家居:在智能家居领域,Modbus TCP协议可以用于连接智能家居设备(如智能灯泡、智能插座、智能安防等)以实现家庭自动化和智能控制。

3 WIZnet以太网芯片

WIZnet 主流硬件协议栈以太网芯片参数对比

ModelEmbedded CoreHost I/FTX/RX BufferHW SocketNetwork Performance
W5100STCP/IPv4, MAC & PHY8bit BUS, SPI16KB4Max.25Mbps
W6100TCP/IPv4/IPv6, MAC & PHY8bit BUS, Fast SPI32KB8Max.25Mbps
W5500TCP/IPv4, MAC & PHYFast SPI32KB8Max 15Mbps
  1. W5100S/W6100 支持 8bit数据总线接口,网络传输速度会优于W5500。
  2. W6100 支持IPV6,与W5100S 硬件兼容,若已使用W5100S的用户需要支持IPv6,可以Pin to Pin兼容。
  3. W5500 拥有比 W5100S更多的 Socket数量以及发送与接收缓存。

4 Modbus TCP示例概述以及使用

4.1 流程图

  程序的运行框图如下所示:

在这里插入图片描述

4.2 准备工作核心

软件

  • Visual Studio Code
  • WIZnet UartTool
  • Modbus Poll

硬件

  • W5100S IO模块 + RP2040 树莓派Pico开发板 或者 WIZnet W5100S-EVB-Pico开发板
  • Micro USB 接口的数据线
  • TTL 转 USB
  • 网线

4.3 连接方式

  • 通过数据线连接PC的USB口(主要用于烧录程序,也可以虚拟出串口使用)

  • 通过TTL串口转USB,连接UART0 的默认引脚:

    • RP2040 GPIO0(UART0 TX) <----> USB_TTL_RX
    • RP2040 GPIO1(UART0 RX) <----> USB_TTL_TX
  • 使用模块连接RP2040 进行接线时

    • RP2040 GPIO16 <----> W5100S MISO
    • RP2040 GPIO17 <----> W5100S CS
    • RP2040 GPIO18 <----> W5100S SCK
    • RP2040 GPIO19 <----> W5100S MOSI
    • RP2040 GPIO20 <----> W5100S RST
  • 通过PC和设备都通过网线连接路由器LAN口

4.4 主要代码概述

  我们使用的是WIZnet官方的ioLibrary_Driver库。该库支持的协议丰富,操作简单,芯片在硬件上集成了TCP/IP协议栈,该库又封装好了TCP/IP层之上的协议,我们只需简单调用相应函数即可完成协议的应用。

第一步:在modbus_tcp.c文件中引用对应的库文件。

第二步:宏定义常量和定义全局变量。

第三步:定义两个函数,包括一个1秒定时器回调函数(用于处理DHCP超时处理),一个设置网络地址函数。

第四步:主函数首先是对串口和SPI进行初始化以及链路检测。然后是设置W5100S的网络地址,首先使用DHCP的方式进行获取,失败后使用预设的静态IP地址。然后将LED GPIO的初始化。最后则是在主循环里面跑Modbus TCP状态机程序。

第五步:在状态机中,首先是打开一个TCP Server模式的socket,然后等待客户端连接。在连接成功之后,会等待客户端的请求信息,接收到请求信息之后,会对包内容解析并作出响应的操作以及回复。

/* main function */
int main()
{struct repeating_timer timer; // Define the timer structure/*mcu init*/stdio_init_all();     // Initialize the main control peripherawizchip_initialize(); // spi initializationwizchip_setnetinfo(&net_info); // Configure once first/*dhcp init*/DHCP_init(SOCKET_ID, ethernet_buf);                                        // DHCP initializationadd_repeating_timer_ms(1000, repeating_timer_callback, NULL, &timer); // Add DHCP 1s Tick Timer handlerprintf("wiznet chip modbus tcp server example.\r\n");network_init(&net_info);              // Configuring Network Informationprint_network_information(&get_info); // Read back the configuration information and print it/* LED gpio init */gpio_init(PICO_DEFAULT_LED_PIN);gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);while (true){do_Modbus(SOCKET_ID);}
}/* Do_Modubs function */
void do_Modbus(uint8_t sn)
{uint8_t state = 0;uint16_t len;getSIPR(lip);state = getSn_SR(sn);switch (state){case SOCK_SYNSENT:break;case SOCK_INIT:listen(sn);if (!b_listening_printed){b_listening_printed = 1;printf("Listening on %d.%d.%d.%d:%d\r\n",lip[0], lip[1], lip[2], lip[3], local_port);}break;case SOCK_LISTEN:break;case SOCK_ESTABLISHED:if (getSn_IR(sn) & Sn_IR_CON){setSn_IR(sn, Sn_IR_CON);printf("Connected\r\n");getSn_DIPR(sn, rip);port = getSn_DPORT(sn);printf("RemoteIP:%d.%d.%d.%d Port:%d\r\n", rip[0], rip[1], rip[2], rip[3], port);if (b_listening_printed)b_listening_printed = 0;}len = getSn_RX_RSR(sn);if (len > 0){mbTCPtoEVB(sn);}break;case SOCK_CLOSE_WAIT:disconnect(sn);break;case SOCK_CLOSED:case SOCK_FIN_WAIT:close(sn);socket(sn, Sn_MR_TCP, local_port, Sn_MR_ND); // Sn_MR_NDbreak;default:break;}
}/* mbTCPtoEVB function */
void mbTCPtoEVB(uint8_t sn)
{int32_t ret;if (MBtcp2evbFrame() != 0) // Frame received complete{uint16_t maxsize = 0;if (pucASCIIBufferCur[0] == 0x01)//Check whether the device address is 0x01{if ((uint8_t)pucASCIIBufferCur[1] == 0x05)//Write to a single device{if ((uint8_t)pucASCIIBufferCur[4] == 0xff){gpio_put(PICO_DEFAULT_LED_PIN, 1);printf("LED ON\r\n");}else if ((uint8_t)pucASCIIBufferCur[4] == 0x00){printf("LED OFF\r\n");gpio_put(PICO_DEFAULT_LED_PIN, 0);}send(sn, recv_data, recv_len);}else if ((uint8_t)pucASCIIBufferCur[1] == 0x01)//Read Write to a single device{if (recv_data[recv_len - 1] != 0x01){printf("len error!\r\n");}else{printf("Read OK!\r\n");send_data[0] = recv_data[0];send_data[1] = recv_data[1];send_data[2] = recv_data[2];send_data[3] = recv_data[3];send_data[4] = 0x00;send_data[5] = 0x04;send_data[6] = 0x01;send_data[7] = 0x01;send_data[8] = 0x01;send_data[9] = gpio_get(PICO_DEFAULT_LED_PIN);send_len = 10;send(sn, (uint8_t *)send_data, send_len);memset(send_data, 0, send_len);}}else{printf("error code!\r\n");}}else{printf("address error!\r\n");}}
}

4.5 结果演示

1.用Modbus Poll连接到W5100S上

在这里插入图片描述

2.发送写指令,打开LED灯

在这里插入图片描述

在这里插入图片描述

3.设置读指令为0x01,读取个数为1

在这里插入图片描述

4.发送读取一次指令

在这里插入图片描述

5.读取成功,并在Modbus Poll上显示出LED的状态

在这里插入图片描述

5 注意事项

  • 设置和读取的地址必须为1,并且读取个数必须为1,否则无法写入或读取信息。如需修改,请修改app/MODBUS_TCP_SERVER目录下的mb.c文件中的mbTCPtoEVB函数。
  • 如果想用WIZnet的W5500来实现本章的示例,我们只需修改两个地方即可:

​ (1)在library/ioLibrary_Driver/Ethernet/下找到wizchip_conf.h这个头文件,将_WIZCHIP_ 宏定义修改为W5500。

​ (2)在library下找到CMakeLists.txt文件,将COMPILE_SEL设置为ON即可,OFF为W5100S,ON为W5500。

6 相关链接

WIZnet官网

WIZnet官方库链接

本章例程链接

想了解更多,评论留言哦!

这篇关于二十五、W5100S/W5500+RP2040树莓派Pico<Modebus TCP Server示例>的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/386899

相关文章

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

Redis延迟队列的实现示例

《Redis延迟队列的实现示例》Redis延迟队列是一种使用Redis实现的消息队列,本文主要介绍了Redis延迟队列的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、什么是 Redis 延迟队列二、实现原理三、Java 代码示例四、注意事项五、使用 Redi

在Pandas中进行数据重命名的方法示例

《在Pandas中进行数据重命名的方法示例》Pandas作为Python中最流行的数据处理库,提供了强大的数据操作功能,其中数据重命名是常见且基础的操作之一,本文将通过简洁明了的讲解和丰富的代码示例,... 目录一、引言二、Pandas rename方法简介三、列名重命名3.1 使用字典进行列名重命名3.编

Python使用Colorama库美化终端输出的操作示例

《Python使用Colorama库美化终端输出的操作示例》在开发命令行工具或调试程序时,我们可能会希望通过颜色来区分重要信息,比如警告、错误、提示等,而Colorama是一个简单易用的Python库... 目录python Colorama 库详解:终端输出美化的神器1. Colorama 是什么?2.

Go Gorm 示例详解

《GoGorm示例详解》Gorm是一款高性能的GolangORM库,便于开发人员提高效率,本文介绍了Gorm的基本概念、数据库连接、基本操作(创建表、新增记录、查询记录、修改记录、删除记录)等,本... 目录1. 概念2. 数据库连接2.1 安装依赖2.2 连接数据库3. 数据库基本操作3.1 创建表(表关

Python视频剪辑合并操作的实现示例

《Python视频剪辑合并操作的实现示例》很多人在创作视频时都需要进行剪辑,本文主要介绍了Python视频剪辑合并操作的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录介绍安装FFmpegWindowsMACOS安装MoviePy剪切视频合并视频转换视频结论介绍

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是