久免费域名注册网站,水土保持与生态建设网站,炫酷特效网站,做网站比特币钱包一、与Modbus TCP的区别 在一般工业场景使用modbus RTU的场景还是更多一些#xff0c;modbus RTU基于串行协议进行收发数据#xff0c;包括RS232/485等工业总线协议。 与modbus TCP不同的是RTU没有报文头MBAP字段#xff0c;但是在尾部增加了两个CRC检验字节#xff08;CRC… 一、与Modbus TCP的区别 在一般工业场景使用modbus RTU的场景还是更多一些modbus RTU基于串行协议进行收发数据包括RS232/485等工业总线协议。 与modbus TCP不同的是RTU没有报文头MBAP字段但是在尾部增加了两个CRC检验字节CRC16因为网络协议中自带校验所以在TCP协议中不需要使用CRC校验码。 RTU和TCP的总体使用方法基本一致只是在创建modbus对象时有所不同TCP需要传入网络socket信息而RTU需要传入串口相关信息。 二、Modbus RTU特点 Modbus RTU也是主从问答协议由主机发起一问一答 Modbus RTU通过串口进行通信 设置串口参数 设置串口参数时要求 波特率为9600 8位数据位 1位停止位 无流控 三、Modbus RTU协议格式 ModbusRTU数据帧包含地址码 功能码 数据 校验码 地址码一个字节 从机ID 功能码一个字节 同TCP八种 数据起始地址 数量 数据 校验码2个字节对 地址码功能码数据进行校验可以通过函数自动生成。 四、报文详解 03功能码为例 主机---》从机 01 03 00 00 00 01 84 0a 01地址码 03功能码 00 00 起始地址 00 01读的数量 84 0a :校验码 从机--》主机 01 03 02 00 14 b8 44 01地址码 03功能码 02字节计数只计算数据的个数 00 14数据 b8 44校验码 参考示例 值得收藏 Modbus RTU 协议详解-CSDN博客 五、模拟器的使用 由于实际硬件产品成本较高我们这里可以使用Modbus软件模拟器进行数据模拟从而分析Modbus协议。 使用工具 1. ModbusPoll模拟主机和ModbusSlave模拟从机 2. vspd虚拟串口 3. UartAssist串口调试工具 设置串口参数要求波特率为9600 8位数据位 1位停止位 无流控 无校验 虚拟串口的使用 虚拟串口的安装 将压缩包解压后双击vspd.exe文件进行安装 2.安装完成后找到安装目录将Cracked下的文件复制到软件安装目录 打开软件添加COM1和COM2端口用完之后记得删除端口 4.添加完端口后打开设备管理器这里出现如下图所示即可。 或 二、虚拟机绑定端口 将虚拟机在系统关机必须是关机状态挂起不行状态下点击虚拟机-设置-硬件-添加串行端口添加COM1添加完成后第一次使用需要将电脑重启重启之后打开虚拟机点击虚拟机-可移动设备-串行端口-连接当连接上虚拟串口后在终端输入dmesg | grep tty可以查看到对应的设备文件其中默认的会有ttyS0文件剩下的就是虚拟串口对应的设备文件 测试通信 1.Windows打开串口调试工具选择好串口COM2-COM1,设置对应的波特率 2. 在虚拟机运行minicom 在虚拟机安装minicom软件 sudo apt-get install minicom 在终端执行sudo minicom -s 1选择serial port setup回车 2设置设备文件波特率关闭流控按如下图设置文件改成自己的 dmesg | grep tty 查看文件名 3修改完成后回车保存修改选择save setup as dfl敲回车再次选择exit回车 4退出后就可以和windows下的串口调试工具进行通信测试 5也可以在这个界面输入字符查看串口助手的显示情况。 6退出ctrlA、Z在弹出的界面里输入X即可退出。 四、将Modbus Slave模拟器作为RTU设备的从机 虚拟机绑定COM1端口slave连接COM2端口虚拟机通过编程测试串口通信 Modbus Slave端的配置如下 五、可能会遇到的问题 1. 虚拟串口完成主机与vmware下虚拟机进行串口通信 虚拟串口完成主机与vmware下虚拟机进行串口通信_xcom2v2.0怎么用-CSDN博客 2. VSPD虚拟串口工具——从此告别硬件串口调试 『实用教程』VSPD虚拟串口工具——从此告别硬件串口调试_虚拟串口vspd-CSDN博客 3. vmware虚拟机检测不到vspd虚拟串口问题 vmware虚拟机检测不到vspd虚拟串口问题_vmware虚拟机 串口 vspd-CSDN博客 练习代码完成通过串口读取slave端 串口初始化与校验码获取函数一起编译管理员身份执行命令 六、Modbus库 安装库 安装配置 1. 在linux中解压压缩包 tar -xvf libmodbus-3.1.7.tar.gz 2. 进入源码目录创建文件夹(存放头文件、库文件) cd libmodbus-3.1.7 mkdir install 3. 执行脚本configure进行安装配置指定安装目录 ./configure --prefix$PWD/install 4. 执行make和make install make//编译 make install//安装 执行完成后会在install文件夹下生产对应的头文件、库文件件夹install用于存放产生的头文件、库文件等 库的使用 要想编译方便可以将头文件和库文件放到系统路径下 sudo cp install/include/modbus/*.h /usr/include sudo cp install/lib/* -r /lib -d 后期编译时可以直接gcc xx.c -lmodbus 头文件默认搜索路径/usr/include 、/usr/local/include 库文件默认搜索路径/lib、/usr/lib 函数接口 以TCP方式创建Modbus实例并初始化 modbus_t* modbus_new_tcp(const char *ip, int port)
功能以TCP方式创建Modbus实例并初始化
参数ip ip地址port端口号
返回值成功Modbus实例失败NULL 设置从机ID int modbus_set_slave(modbus_t *ctx, int slave)
功能设置从机ID
参数ctx Modbus实例slave从机ID
返回值成功0失败-1 和从机slave建立连接 一个modbus实例只能链接一个从机根据提供的引用内容一个modbus实例只能连接一个从机ID。因为modbus通信协议是基于主从模式的每个从机都有一个唯一的从机地址主机通过从机地址来访问不同的从机。因此一个modbus实例只能连接一个从机ID如果需要连接多个从机需要创建多个modbus实例。 int modbus_connect(modbus_t *ctx)
功能和从机slave建立连接
参数ctxModbus实例
返回值成功0失败-1 释放Modbus实例 void modbus_free(modbus_t *ctx)
功能释放Modbus实例
参数ctxModbus实例 关闭套接字 void modbus_close(modbus_t *ctx)
功能关闭套接字
参数ctxModbus实例 读取线圈状态可读取多个连续线圈的状态对应功能码为0x01 int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能读取线圈状态可读取多个连续线圈的状态对应功能码为0x01
参数ctx Modbus实例addr 寄存器起始地址nb 寄存器个数dest 得到的状态值7)读取输入状态可读取多个连续输入的状态对应功能码为0x02 int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest)
功能读取输入状态可读取多个连续输入的状态对应功能码为0x02
参数ctx Modbus实例addr 寄存器起始地址nb 寄存器个数dest 得到的状态值
返回值成功返回nb的值 读取保持寄存器的值可读取多个连续保持寄存器的值对应功能码为0x03 int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能读取保持寄存器的值可读取多个连续保持寄存器的值对应功能码为0x03
参数ctx Modbus实例addr 寄存器起始地址nb 寄存器个数dest 得到的寄存器的值
返回值成功读到寄存器的个数失败-1 读输入寄存器的值可读取多个连续输入寄存器的值对应功能码为0x04 int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest)
功能读输入寄存器的值可读取多个连续输入寄存器的值对应功能码为0x04
参数ctx Modbus实例addr 寄存器起始地址nb 寄存器个数dest 得到的寄存器的值
返回值成功读到寄存器的个数失败-1 写入单个线圈的状态对应功能码为0x05 int modbus_write_bit(modbus_t *ctx, int addr, int status);
功能写入单个线圈的状态对应功能码为0x05
参数ctx Modbus实例addr 线圈地址status线圈状态
返回值成功0失败-1 写入多个连续线圈的状态对应功能码为15 int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);
功能写入多个连续线圈的状态对应功能码为15
参数ctx Modbus实例addr 线圈地址nb 线圈个数src 多个线圈状态
返回值成功0失败-1 写入单个寄存器对应功能码为0x06 int modbus_write_register(modbus_t *ctx, int addr, int value);
功能 写入单个寄存器对应功能码为0x06
参数 ctx Modbus实例addr 寄存器地址value 寄存器的值
返回值成功0失败-1 12)写入多个连续寄存器对应功能码为16 int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);
功能写入多个连续寄存器对应功能码为16
参数ctx Modbus实例addr 寄存器地址nb 寄存器的个数src 多个寄存器的值
返回值成功0失败-1编程流程 创建实例 modbus_new_tcp设置从机id modbus_set_slave建立连接 modbus_connect寄存器操作关闭套接字 modbus_close释放实例 modbus_free 练习 通过库函数实现03功能码采集数据 注意编译不要忘了链接库、查看网络是否能用查看slave端协议是否正确查看slave端是否有对应的寄存器类型查看slave id是否一致 gcc modbus.c -lmodbus #include stdio.h
#include sys/types.h /* See NOTES */
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h /* superset of previous */
#include arpa/inet.h
#include unistd.h
#include stdlib.h
#include string.h
#include modbus.h
int main(int argc, char const *argv[])
{int ret;uint16_t buf[32];// 1.创建实例 modbus_new_tcp,端口号字符型转整型modbus_t* md modbus_new_tcp(argv[1],atoi(argv[2]));// 2.设置从机id modbus_set_slaveret modbus_set_slave(md, 1);if (ret 0){printf(set err\n);}// 3.建立连接 modbus_connectret modbus_connect(md);if (ret 0){printf(connect err.\n);}// 4.寄存器操作//从0开始读十个寄存器值ret modbus_read_registers(md, 0, 10, buf);for (int i 0; i 10; i){printf(%#x , buf[i]);}// 5.关闭套接字 modbus_close,先关闭套接字,再释放实例modbus_close(md); // 6.释放实例 modbus_freemodbus_free(md);return 0;
}1.任务编程实现采集传感器数据和控制硬件设备传感器和硬件通过slave模拟 传感器2个光线传感器、加速度传感器x\y\z 硬件设备2个led灯、蜂鸣器 要求 1.多任务编程多线程 2.循环1s采集一次数据并将数据打印至终端 3.同时从终端输入指令控制硬件设备 0 1 led灯打开 0 0led灯关闭 1 1蜂鸣器开 1 0 : 蜂鸣器关