Modbus RTU協議及modbus庫函數使用

一、與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位停止位?無流控??無校驗

虛擬串口的使用:

  • 虛擬串口的安裝
  1. 將壓縮包解壓后,雙擊vspd.exe文件進行安裝

2.安裝完成后,找到安裝目錄,將Cracked下的文件復制到軟件安裝目錄

  1. 打開軟件,添加COM1COM2端口(用完之后記得刪除端口)

4.添加完端口后,打開設備管理器,這里出現如下圖所示即可。

二、虛擬機綁定端口

  1. ?將虛擬機在系統關機(必須是關機狀態,掛起不行)狀態下,點擊虛擬機->設置->硬件->添加串行端口,添加COM1
  2. 添加完成后,第一次使用需要將電腦重啟
  3. 重啟之后,打開虛擬機,點擊虛擬機->可移動設備->串行端口->連接
  4. 當連接上虛擬串口后,在終端輸入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)退出:ctrl+AZ,在彈出的界面里輸入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. 安裝庫
    1. 安裝配置

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,用于存放產生的頭文件、庫文件等

    1. 庫的使用

要想編譯方便,可以將頭文件和庫文件放到系統路徑下

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

  1. 函數接口
  1. 以TCP方式創建Modbus實例,并初始化

modbus_t*???modbus_new_tcp(const?char?*ip,?int?port)
功能:以TCP方式創建Modbus實例,并初始化
參數:
????ip???:ip地址
????port:端口號
返回值:成功:Modbus實例
??????失敗:NULL

  1. 設置從機ID

int?modbus_set_slave(modbus_t?*ctx,?int?slave)
功能:設置從機ID
參數:
????ctx???:Modbus實例
????slave:從機ID
返回值:成功:0
???????失敗:-1

  1. 和從機(slave)建立連接

一個modbus實例只能鏈接一個從機:根據提供的引用內容,一個modbus實例只能連接一個從機ID。因為modbus通信協議是基于主從模式的,每個從機都有一個唯一的從機地址,主機通過從機地址來訪問不同的從機。因此,一個modbus實例只能連接一個從機ID,如果需要連接多個從機,需要創建多個modbus實例。

int???modbus_connect(modbus_t?*ctx)
功能:和從機(slave)建立連接
參數:
????ctx:Modbus實例
返回值:成功:0
???????失敗:-1

  1. 釋放Modbus實例

void???modbus_free(modbus_t?*ctx)
功能:釋放Modbus實例
參數:ctx:Modbus實例

  1. 關閉套接字

void???modbus_close(modbus_t?*ctx)
功能:關閉套接字
參數:ctx:Modbus實例

  1. 讀取線圈狀態,可讀取多個連續線圈的狀態(對應功能碼為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的值

  1. 讀取保持寄存器的值,可讀取多個連續保持寄存器的值(對應功能碼為0x03

int??modbus_read_registers(modbus_t?*ctx,?int?addr,?int?nb,?uint16_t?*dest)
功能:讀取保持寄存器的值,可讀取多個連續保持寄存器的值(對應功能碼為0x03)
參數:
????ctx???:Modbus實例
????addr?:寄存器起始地址
????nb????:寄存器個數
????dest?:得到的寄存器的值
返回值:成功:讀到寄存器的個數
???????失敗:-1

  1. 讀輸入寄存器的值,可讀取多個連續輸入寄存器的值(對應功能碼為0x04

int???modbus_read_input_registers(modbus_t?*ctx, int?addr, int?nb,?uint16_t?*dest)
功能:讀輸入寄存器的值,可讀取多個連續輸入寄存器的值(對應功能碼為0x04)
參數:
????ctx???:Modbus實例
????addr?:寄存器起始地址
????nb????:寄存器個數
????dest?:得到的寄存器的值
返回值:成功:讀到寄存器的個數
???????失敗:-1

  1. 寫入單個線圈的狀態(對應功能碼為0x05

int??modbus_write_bit(modbus_t?*ctx,?int?addr,?int?status);
功能:寫入單個線圈的狀態(對應功能碼為0x05)
參數:
????ctx?????:Modbus實例
????addr??:線圈地址
????status:線圈狀態
返回值:成功:0
??????失敗:-1

  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

  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

  1. 編程流程
  1. 創建實例?modbus_new_tcp
  2. 設置從機id?modbus_set_slave
  3. 建立連接?modbus_connect
  4. 寄存器操作
  5. 關閉套接字?modbus_close
  6. 釋放實例?modbus_free
  1. 練習

通過庫函數實現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_slave
????ret?=?modbus_set_slave(md,?1);
????if?(ret?<?0)
????{
????????printf("set?err\n");
????}
????//?3.建立連接?modbus_connect
????ret?=?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_free
????modbus_free(md);
????return?0;
}

1.任務:編程實現采集傳感器數據和控制硬件設備(傳感器和硬件通過slave模擬)

傳感器:2個,光線傳感器、加速度傳感器(x\y\z)

硬件設備:2個,led燈、蜂鳴器

要求:

1.多任務編程:多線程

2.循環1s采集一次數據,并將數據打印至終端

3.同時從終端輸入指令控制硬件設備

0??1?:led燈打開

0??0:led燈關閉

1??1:蜂鳴器開

1?0?:??蜂鳴器關

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164213.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164213.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164213.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android之在RecyclerView列表中實現單選

一、實現效果 單選、可取消選中、列表數據可更新&#xff08;選擇狀態清空&#xff0c;可重新選擇&#xff09; RecyclerView列表單選 二、實現步驟 僅展示部分核心代碼&#xff0c;請主要參考適配器的定義 1、Item布局 selected_tip_list_item.xml文件 包含一個TextView和…

Spring Boot集成MyBatis實現多數據源訪問的“秘密”

文章目錄 為什么需要多數據源&#xff1f;Spring Boot集成MyBatis的基礎配置使用多數據源小結 &#x1f389;Spring Boot集成MyBatis實現多數據源訪問的“秘密” ☆* o(≧▽≦)o *☆嗨~我是IT陳寒&#x1f379;?博客主頁&#xff1a;IT陳寒的博客&#x1f388;該系列文章專欄&…

力扣:178. 分數排名(Python3)

題目&#xff1a; 表: Scores ---------------------- | Column Name | Type | ---------------------- | id | int | | score | decimal | ---------------------- 在 SQL 中&#xff0c;id 是該表的主鍵。 該表的每一行都包含了一場比賽的分數。Score …

TCP /UDP協議的 socket 調用的過程

在傳輸層有兩個主流的協議 TCP 和 UDP&#xff0c;socket 程序設計也是主要操作這兩個協議。這兩個協議的區別是什么呢&#xff1f;通常的答案是下面這樣的。 TCP 是面向連接的&#xff0c;UDP 是面向無連接的。TCP 提供可靠交付&#xff0c;無差錯、不丟失、不重復、并且按序…

Selenium介紹及基本使用方法

Selenium是一個開源、免費、簡單、靈活&#xff0c;對Web瀏覽器支持良好的自動化測試工具&#xff0c;在UI自動化、爬蟲等場景下是十分實用的&#xff0c;能夠熟練掌握并使用Selenium工具可以大大的提高效率。 Selenium簡介 Selenium支持多平臺、多瀏覽器、多語言去實現自動化…

深入理解強化學習——馬爾可夫決策過程:動作價值函數

分類目錄&#xff1a;《深入理解強化學習》總目錄 不同于馬爾可夫獎勵過程&#xff0c;在馬爾可夫決策過程中&#xff0c;由于動作的存在&#xff0c;我們額外定義一個動作價值函數&#xff08;Action-value Function&#xff09;。我們用 Q π ( s , a ) Q^\pi(s, a) Qπ(s,a)…

線程提交線程到線程池,有幾種方式,哪一種方式是工作中不能使用的,無法捕捉異常,線程池的拒絕策略,線程池的提交方式

線程池的工作原理 JDK中提交線程到線程池&#xff0c;有幾種方式&#xff0c;哪一種方式是工作中不能使用的&#xff0c;無法捕捉異常 兩種提交任務的方法 ExecutorService 提供了兩種提交任務的方法&#xff1a; execute()&#xff1a;提交不需要返回值的任務 submit()&a…

【C語言】多組輸入

C系列文章目錄 目錄 C系列文章目錄 一、什么是多組輸入&#xff1f; 二、如何使用多組輸入 2.1&#xff0c;試題舉例講解 2.2&#xff0c;錯誤解法 2.3&#xff0c;我們實現多組輸入的思路 2.4&#xff0c;第一種正確的解法 2.5&#xff0c;第二種正確的解法 2.6&…

Python入門教程 | Python3 字典(dict)

Python3 字典 字典是另一種可變容器模型&#xff0c;且可存儲任意類型對象。 Python3中的字典是一種無序、可變、可迭代的數據結構&#xff0c;它由鍵&#xff08;key&#xff09;和對應的值&#xff08;value&#xff09;組成。字典在Python中被視為可變對象&#xff0c;這意…

ES ElasticSearch安裝、可視化工具kibana安裝

1、安裝ES docker run -d --name es9200 -e "discovery.typesingle-node" -p 9200:9200 elasticsearch:7.12.1訪問測試&#xff1a; http://域名:9200/ 2、安裝kibana對es進行可視化操作 執行命令 docker run -d --name kibana5601 -p 5601:5601 kibana:7.1.12.修…

如何實現在公網下使用navicat圖形化工具遠程連接本地內網的MariaDB數據庫

公網遠程連接MariaDB數據庫【cpolar內網穿透】 文章目錄 公網遠程連接MariaDB數據庫【cpolar內網穿透】1. 配置MariaDB數據庫1.1 安裝MariaDB數據庫1.2 測試局域網內遠程連接 2. 內網穿透2.1 創建隧道映射2.2 測試隨機地址公網遠程訪問3. 配置固定TCP端口地址3.1 保留一個固定的…

Redis深入理解-Socket連接建立流程以及文件事件處理機制

Redis Server 運行原理圖 Redis 服務器中 Socket 網絡建立以及文件事件模型 一個 redis 單機&#xff0c;可以抗幾百上千的并發&#xff0c;這里的并發指的就是同時可以有幾百個 client 對這個 redis server 發起請求&#xff0c;都需要去建立網絡連接&#xff0c;同時間可能會…

利用 docker 實現JMeter分布式壓測

為什么需要分布式&#xff1f; 在工作中經常需要對一些關鍵接口做高QPS的壓測&#xff0c;JMeter是由Java 語言開發&#xff0c;沒創建一個線程&#xff08;虛擬用戶&#xff09;&#xff0c;JVM默認會為每個線程分配1M的堆棧內存空間。受限于單臺試壓機的配置很難實現太高的并…

YAML 深入解析:從語法到最佳實踐

什么是YAML YAML&#xff08;YAML Ain’t Markup Language&#xff09;是一種人類可讀的數據序列化語言。它的設計目標是使數據在不同編程語言之間交換和共享變得簡單。YAML采用了一種簡潔、直觀的語法&#xff0c;以易于閱讀和編寫的方式表示數據結構。 YAML廣泛應用于配置文…

【OpenCV實現圖像:制作酷炫的動畫效果】

文章目錄 概要生成背景圖添加點動畫添加文本顯示小結 概要 首先&#xff0c;通過導入必要的庫&#xff0c;包括NumPy用于數學運算和Matplotlib庫用于數據可視化。隨后&#xff0c;創建圖形和軸&#xff0c;初始化點的位置&#xff0c;以及編寫初始化函數和更新函數。 初始化函…

C語言歸并排序

以夢為馬&#xff0c;不負韶華 文章目錄 引入&#xff1a;實現原理問題引出&#xff1a;遞歸實現&#xff1a;迭代實現穩定性分析&#xff1a;總結&#xff1a; 引入&#xff1a; 如何將兩個有序數組&#xff08;假設為升序&#xff09;合并為一個有序數組&#xff1f; 雙指針…

yolov5/v7修改標簽和檢測框顯示【最全】

《記錄自己在使用yolov5遇到的一些問題》同時也供大家參考&#xff0c;如果對你們有幫助&#xff0c;希望大家可以給個點贊、收藏鼓勵下&#xff0c;非常感謝&#xff01; 以自帶的一張圖片作為示例,yolov5(6.1版本)的初始檢測框應該是如下圖所示 修改線條粗細、隱藏標簽、隱…

EI論文故障識別程序:DBN深度置信/信念網絡的故障識別Matlab程序,數據由Excel導入,直接運行!

?適用平臺&#xff1a;Matlab2021b版及以上 本程序參考中文EI期刊《基于變分模態分解和改進灰狼算法優化深度置信網絡的自動轉換開關故障識別》中的深度置信網絡&#xff08;Deep Belief Network&#xff0c;DBN&#xff09;部分進行故障識別&#xff0c;程序注釋清晰&#x…

Python之學生信息管理系統

目錄 一、基礎界面實現 1、主函數 2、保持循環&#xff0c;獲取用戶需求 二、函數實現模塊功能 1、添加學生信息 2、刪除學生信息 3、修改學生信息 4、查找全部學生信息 5、退出系統 三、整合代碼 1、 完整代碼 2、完整實現過程 實現 打印功能菜單、添加學生信息、刪…

想自學軟件測試?一般人我還是勸你算了吧。。。

&#x1f4e2;專注于分享軟件測試干貨內容&#xff0c;歡迎點贊 &#x1f44d; 收藏 ?留言 &#x1f4dd; 如有錯誤敬請指正&#xff01;&#x1f4e2;交流討論&#xff1a;歡迎加入我們一起學習&#xff01;&#x1f4e2;資源分享&#xff1a;耗時200小時精選的「軟件測試」資…