modbus協議是應用於電子控制器上的一種通用語言。通過此協議,控制器相互之間、控制器經由網路(例如乙太網)和其它裝置之間可以通訊。它已經成為一種通用工業標準。有了它,不同廠商生產的控制裝置可以連成工業網路,進行集中監控。此協議定義了乙個控制器能認識使用的訊息結構,而不管它們是經過何種網路進行通訊的。它描述了乙個控制器請求訪問其它裝置的過程,如何回應來自其它裝置的請求,以及怎樣偵測錯誤並記錄。它制定了訊息域格局和內容的公共格式。專案中經常需要和各式各樣的plc進行通訊,開始的時候是三菱q系列的5u,用的是slmp協議,後面又對接了安川的plc,指不定以後會用哪家的plc,所以考慮到是不是應該換乙個通用性比較強的介面協議,可以省去大量時間和精力。當在同一modbus網路上通訊時,此協議決定了每個控制器需要知道它們的裝置位址,識別按位址發來的訊息,決定要產生何種行動。如果需要回應,控制器將生成反饋資訊並用modbus協議發出。在其它網路上,包含了modbus協議的訊息轉換為在此網路上使用的幀或包結構。這種轉換也擴充套件了根據具體的網路解決節位址、路由路徑及錯誤檢測的方法。
此協議支援傳統的rs-232、rs-422、rs-485和乙太網裝置。許多任務業裝置,包括plc,dcs,智慧型儀表等都在使用modbus協議作為他們之間的通訊標準。
網上搜了一下,發現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下圖是我在工作中常用的三菱5u plc modbus對應暫存器線圈輸入等的位址。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
使用說明 附註工具使用說明
附註工具使用說明 附註工具用途 附註工具主要用於更新利用word附註應用程式生成的帶域 的附註,該工具在word右鍵 更新鏈結 的基礎上進行了優化,故在使用時,不能再利用word右鍵 更新鏈結 而要用本工具的 更新當前鏈結 或 更新所有鏈結 使用說明 一 更換路徑 當利用word附註應用程式生成帶域...
使用說明 農用遮光網使用說明
農用遮光網使用說明 建築防塵網購買方 建築施工企業 在購買建築防塵網時,應該對 作出比較,可以分辨品牌 型號,且購買時應該在一定程度上了解信譽良莠。建築防塵網購買方 市場售賣方 在選購建築防塵網時,可以把 作為基礎,好的 可以用來彌補信譽不足,而差的 則需要按照你的服務收費。農用遮光網使用說明 用途...
Hibernate tools 使用說明
05年的8月份第一次接觸hibernate tools,使用起來感覺還不錯,但也沒有深入研究,後來由於一直在做乙個專案,再後來用了一陣myeclipse,現在換了公司,使用wtp all in one eclipse的乙個版本 生成domain的時候使用了hibernate tools,發現都不知怎...