之前發表的Modbus通訊程式使用了QT自帶的Modbus庫,由於QT自帶庫的資料響應使用的是訊號和槽來實現的,所以在一些讀寫頻率較高的場景下,會引發很多異常問題,此篇文章使用C語言寫的第三方Modbus庫來實現modbus通訊。
經程式執行測試,呼叫該庫進行modbus通訊完虐QT自帶mosbus庫。
一、配置modbus庫
modbus-c庫下載連結:https://sourceforge.net/projects/libmodbus/
將下載的庫資料夾放入原始檔根目錄下(pro檔案中要記得新增LIBS += -Ldll -lws2_32)
[libmodbus資料夾和ws2_32.dll(依賴該動態庫)放入根目錄下 ]
二、使用modbus-c庫
1.modbusRTU
1 //1.初始化連線資料
2 char *pcom = "COM1"; //COM口
3 int Address = 1; //站號
4 modbus_t *mb;
5 mb = modbus_new_rtu(pcom,9600,'N',8,1);
6 modbus_set_slave(mb, Address); //從機地址
7 modbus_connect(mb); //
8
9 //2.設定通訊超時時間
10 struct timeval t;
11 t.tv_sec=0;
12 t.tv_usec=1000000; //設定modbus超時時間為1000毫秒,注意:經測試,如果沒有成功建立tcp連線,則該設定無效。
13 modbus_set_response_timeout(mb,t.tv_sec,t.tv_usec);
14
15
16 //3.讀資料
17 uint16_t tab_reg[128]={0};
18 int regs=modbus_read_input_registers(mb, 0, 2, tab_reg); //從0開始讀2個數
19 if(regs == -1){
20 //讀取失敗返回-1
21 }
22 else { //讀取成功返回0
23 tab_reg[0]; //input_registers的第1個數
24 tab_reg[1]; //input_registers的第2個數
25 }
26
27 uint8_t bits[128]={0};
28 int rbits = modbus_read_bits(mb, 0, 2, bits);
29 if(rbits == -1){
30 //讀取失敗返回-1
31 }
32 else { //讀取成功返回0
33 bits[0]; //bits的第1個數
34 bits[1]; //bits的第2個數
35 }
36 //...剩下的兩個讀取同理
37
38
39 //4.寫資料
40 uint8_t bitsw[128]={0};
41 bitsw[0]=1;bitsw[1]=1;
42 int wbits = modbus_write_bits(mb, 0, 2, bitsw); //寫兩個數進去
43 if(wbits == -1){
44 //寫入失敗返回-1
45 }
46 else { //寫入成功返回0
47 //
48 }
49
50 uint16_t registers[128];
51 registers[0] = 200;registers[1] = 203;
52 int wreg = modbus_write_registers(mb,0,2,registers);
53 if(wreg == -1){
54 //寫入失敗返回-1
55 }
56 else { //寫入成功返回0
57 //
58 }
59
60
61 //5.呼叫完成後釋放資源
62 modbus_close(mb);
63 modbus_free(mb);
2.modbusTCP
1 //與RTU不同的是將串列埠轉為網口初始化
2 //mb = modbus_new_rtu(pcom,9600,'N',8,1); //串列埠用
3 mb = modbus_new_tcp("127.0.0.1",502);