libmodbus使用說明

2021-08-14 19:57:06 字數 4083 閱讀 6065

modbus協議是應用於電子控制器上的一種通用語言。通過此協議,控制器相互之間、控制器經由網路(例如乙太網)和其它裝置之間可以通訊。它已經成為一種通用工業標準。有了它,不同廠商生產的控制裝置可以連成工業網路,進行集中監控。此協議定義了乙個控制器能認識使用的訊息結構,而不管它們是經過何種網路進行通訊的。它描述了乙個控制器請求訪問其它裝置的過程,如何回應來自其它裝置的請求,以及怎樣偵測錯誤並記錄。它制定了訊息域格局和內容的公共格式。

當在同一modbus網路上通訊時,此協議決定了每個控制器需要知道它們的裝置位址,識別按位址發來的訊息,決定要產生何種行動。如果需要回應,控制器將生成反饋資訊並用modbus協議發出。在其它網路上,包含了modbus協議的訊息轉換為在此網路上使用的幀或包結構。這種轉換也擴充套件了根據具體的網路解決節位址、路由路徑及錯誤檢測的方法。

此協議支援傳統的rs-232、rs-422、rs-485和乙太網裝置。許多任務業裝置,包括plc,dcs,智慧型儀表等都在使用modbus協議作為他們之間的通訊標準。

專案中經常需要和各式各樣的plc進行通訊,開始的時候是三菱q系列的5u,用的是slmp協議,後面又對接了安川的plc,指不定以後會用哪家的plc,所以考慮到是不是應該換乙個通用性比較強的介面協議,可以省去大量時間和精力。

網上搜了一下,發現modbus算是比較通用的協議了,也搜到了很多資料,因為對c++ 比較熟悉,所以搜的都是c++ 的modbus資源。正好找到了libmodbus這個開源庫,通讀了一遍**,覺得很不錯,很強大,所以有了這篇文章。

引入到工程之後,就需要了解幾個主要的函式了。

/* 

以tcp的方式建立libmobus例項

int port: 連線的ip埠

*/modbus_t *

modbus_new_tcp

(const

char

*ip,

int port)

;/*

以串列埠的方式建立libmobus例項

onst char *device:連線的串口號,類似是這樣'\\\\.\\com10'

int baud: 波特率

char parity:奇偶校驗

int data_bit:資料位

int stop_bit:停止位

*/modbus_t *

modbus_new_rtu

(const

char

*device,

int baud,

char parity,

int data_bit,

int stop_bit)

;/*

釋放libmodbus例項,使用完libmodbus需要釋放掉

modbus_t *ctx:libmodbus例項

*/void

modbus_free

(modbus_t *ctx)

;

/* 

讀取線圈狀態,可讀取多個連續線圈的狀態

modbus_t *ctx:modbus例項

int addr: 線圈位址

int nb:讀取線圈的個數

uint8_t *dest: 傳出的狀態值

*/int

modbus_read_bits

(modbus_t *ctx,

int addr,

int nb,

uint8_t

*dest)

;/*

讀取輸入狀態,可讀取多個連續輸入的狀態

modbus_t *ctx:modbus例項

int nb:讀取輸入的個數

uint8_t *dest:傳出的狀態值

*/int

modbus_read_input_bits

(modbus_t *ctx,

int addr,

int nb,

uint8_t

*dest)

;/*

讀取輸入暫存器的值,可讀取多個連續輸入輸入暫存器

modbus_t *ctx:modbus例項

int nb:讀取輸入暫存器的個數

uint8_t *dest:傳出的暫存器值

*/int

modbus_read_input_registers

(modbus_t *ctx,

int addr,

int nb,

uint16_t

*dest)

;/*

讀取保持暫存器的值,可讀取多個連續輸入保持暫存器

modbus_t *ctx:modbus例項

int nb:讀取保持暫存器的個數

uint8_t *dest:傳出的暫存器值

*/int

modbus_read_registers

(modbus_t *ctx,

int addr,

int nb,

uint16_t

*dest)

;

/*

寫入單個線圈的狀態

modbus_t *ctx:modbus例項

int status:線圈狀態

*/int modbus_write_bit(modbus_t *ctx, int addr, int status);

/* 寫入多個連續線圈的狀態

modbus_t *ctx:modbus例項

int nb:線圈個數

const uint8_t *src:多個線圈狀態

*/int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);

/* 寫入單個暫存器

modbus_t *ctx:modbus例項

int value:暫存器的值

*/int modbus_write_register(modbus_t *ctx, int addr, int value);

/* 寫入多個連續暫存器

int nb:暫存器的個數

const uint16_t *src:多個暫存器的值

*/int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);

libmodbus下處理浮點型真的是異常方便,我之前用的協議都是需要我自己轉換的,在得到的暫存器的資料後,發現plc的數解析的時候,可能分16位和32位的,拿16位舉例,每4位一組就像abcd,我們需要解析出來的是dcba。

後來我發現了libmodbus裡面有這兩個函式

float modbus_get_float(const uint16_t *src);

void modbus_set_float(float f, uint16_t *dest)

這個兩個函式主要是將整型資料轉換成float,和將float轉換成整型的。

在用modbus_read_registers或者modbus_read_input_registers得到暫存器的值int16_t *dest,如果裡面存的是浮點數,把dest當做引數傳入到modbus_get_float裡面,如果得到的值不對,你需要弄清楚plc對應傳出資料的模式是dcba還是badc,cdab,abcd。

libmodbus還提供了其他函式

modbus_get_float_abcd

modbus_get_float_badc

modbus_get_float_cdab

modbus_get_float_dcba

modbus_set_float_abcd

modbus_set_float_badc

modbus_set_float_cdab

modbus_set_float_dcba

下圖是我在工作中常用的三菱5u plc modbus對應暫存器線圈輸入等的位址。

使用說明 附註工具使用說明

附註工具使用說明 附註工具用途 附註工具主要用於更新利用word附註應用程式生成的帶域 的附註,該工具在word右鍵 更新鏈結 的基礎上進行了優化,故在使用時,不能再利用word右鍵 更新鏈結 而要用本工具的 更新當前鏈結 或 更新所有鏈結 使用說明 一 更換路徑 當利用word附註應用程式生成帶域...

使用說明 農用遮光網使用說明

農用遮光網使用說明 建築防塵網購買方 建築施工企業 在購買建築防塵網時,應該對 作出比較,可以分辨品牌 型號,且購買時應該在一定程度上了解信譽良莠。建築防塵網購買方 市場售賣方 在選購建築防塵網時,可以把 作為基礎,好的 可以用來彌補信譽不足,而差的 則需要按照你的服務收費。農用遮光網使用說明 用途...

Hibernate tools 使用說明

05年的8月份第一次接觸hibernate tools,使用起來感覺還不錯,但也沒有深入研究,後來由於一直在做乙個專案,再後來用了一陣myeclipse,現在換了公司,使用wtp all in one eclipse的乙個版本 生成domain的時候使用了hibernate tools,發現都不知怎...