目录
Modbus RTU
与Modbus TCP的区别
在一般工业场景使用modbus RTU的场景还是更多一些,modbus RTU基于串行协议进行收发数据,包括RS232/485等工业总线协议。
与modbus TCP不同的是RTU没有报文头MBAP字段,保留从机地址,在尾部增加了两个CRC检验字节(CRC16),因为网络协议中自带校验,所以在 ModbusTCP协议中不需要使用CRC校验码。
RTU和TCP的总体使用方法基本一致,只是在创建modbus对象时有所不同,TCP需要传入网络socket信息;而RTU需要传入串口相关信息。
Modbus RTU特点
Modbus RTU也是主从问答协议,由主机发起,一问一答
Modbus RTU协议格式
ModbusRTU数据帧包含:从站地址 功能码 数据 CRC校验码
地址码:从机ID
功能码:同TCP
数据:起始地址 数量 数据
校验码:2个字节,对 地址码 功能码 数据进行校验,可以通过函数自动生成
报文详解
03功能码为例
主机--》从机
01 03 00 00 00 01 84 0A
01 : 从机地址
03:功能码,读取保持寄存器
00 00 :起始地址
00 01:读取的个数,1个。
84 0A:CRC校验码
从机---》主机
01 03 02 00 14 B4 44
01:从机地址
03:功能码
02:字节计数
00 14:数据
B4 44 :CRC校验码
模拟器的使用
由于实际硬件产品成本较高,我们这里可以使用Modbus软件模拟器,进行数据模拟从而分析Modbus协议。
使用工具:
1. ModbusPoll(模拟主机)和ModbusSlave(模拟从机)
2. vspd虚拟串口
3. UartAssist串口调试工具
设置串口参数要求:波特率为9600 8位数据位 1位停止位 无流控 无校验
虚拟串口的使用:
- 虚拟串口的安装
- 将压缩包解压后,双击vspd.exe文件进行安装
2.安装完成后,找到安装目录,将Cracked下的文件复制到软件安装目录
3.打开软件,添加COM1和COM2端口(用完之后记得删除端口)
4.添加完端口后,打开设备管理器,这里出现如下图所示即可。
或
二、虚拟机绑定端口
- 将虚拟机在系统关机(必须是关机状态,挂起不行)状态下,点击虚拟机->设置->硬件->添加-->添加串行端口,添加COM1,找不到的COM1的话重启电脑
- 添加完成后,第一次使用需要将电脑重启
- 重启之后,打开虚拟机,点击虚拟机 ubuntu->可移动设备->串行端口->连接
- 当连接上虚拟串口后,在终端输入dmesg | grep tty,可以查看到对应的设备文件,其中默认的会有ttyS0文件,剩下的就是虚拟串口对应的设备文件,记好这个文件名,一会设置会用到。
- 测试通信
1.Windows打开串口调试工具,选择好串口COM2->COM1,设置对应的波特率
2. 在虚拟机运行minicom
在虚拟机安装minicom软件
sudo apt-get install minicom
在终端执行sudo minicom -s
1)选择serial port setup,回车
2)设置设备文件,波特率,关闭流控,按如下图设置(文件改成自己的)
如果刚刚找到的是ttyS1那需要改成ttyS1
3)修改完成后,回车,保存修改,选择save setup as dfl,敲回车,再次选择exit回车
4)退出后就可以和windows下的串口调试工具进行通信测试
5)也可以在这个界面输入字符,查看串口助手的显示情况。
6)退出:ctrl+A、Z,在弹出的界面里输入X,即可退出。
到这就可
将Modbus Slave模拟器作为RTU设备的从机
虚拟机绑定COM1端口,slave连接COM2端口,虚拟机通过编程测试串口通信
Modbus Slave端的配置如下:
没有COM2的话选COM2->COM1
通信前的约定:
- 双方约定好同样的通信速度:波特率 单位是:bit/s 115200 9600
- 起始位:1位,低电平
- 停止位:1位 高电平
- 数据位 8位
- 校验:不校验
- 流控制:不用
串口的初始化配置:使用串口初始化函数实现
代码实现RTU通信
打开模拟的RTU从机
linux端使用代码实现和串口连接
框架搭建
1.打开COM1口
打开串口文件( /dev/ttyS1)
2.串口初始化
使用专用函数即可
3.创建要发送的03功能数组
4.根据所要实现的功能,拼接好数组
5.加上CRC校验码
6.串口发送----向串口文件写数据
7.串口接收----读取串口文件
8.打印收到的数据
代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include "Crc_Calc.h"
#include <unistd.h>
int main(int argc, char const *argv[])
{
// 1.打开COM1口
// 打开串口文件( /dev/ttyS1)
int fd=open("/dev/ttyS1",O_RDWR);
if (fd < 0)
{
perror("open err");
return -1;
}
// 2.串口初始化
uart_init(fd);// 使用专用函数即可
// 3.创建要发送的03功能数组
// 4.根据所要实现的功能,拼接好数组
//RTU 01 03 00 00 00 01
uint8_t req[12]={0x01,0x03,0x00,0x00,0x00,0x01};
uint8_t buf[32]={0};
// 5.加上CRC校验码
uint16_t Crc;
Crc=GetCRC16(req,6);//CRC=5;
req[6]=Crc >> 8; // y=CRC+1;
req[7]=Crc;
// 6.串口发送----向串口文件写数据
write(fd,req,8);
// 7.串口接收----读取串口文件
int ret=read(fd,buf,sizeof(buf));
// 8.打印收到的数据
for (int i = 0; i < ret; i++)
{
printf("%02x ",buf[i]);
}
putchar(10);
return 0;
}
标签:RTU,00,day02,虚拟机,Modbus,从机,串口
From: https://blog.csdn.net/QR70892/article/details/142368773