Modbus簡介參考:Modbus?協(xié)議?深入?講解 https://www./zh-cn/innovations/white-papers/14/the-modbus-protocol-in-depth.html http://www.sohu.com/a/230628953_315598 官方文檔:http://www./docs/Modbus_Application_Protocol_V1_1b3.pdf Modbus協(xié)議包括ASCII、RTU、TCP等,并沒有規(guī)定物理層。此協(xié)議定義了控制器能夠認(rèn)識(shí)和使用的消息結(jié)構(gòu),而不管它們是經(jīng)過何種網(wǎng)絡(luò)進(jìn)行通信的。標(biāo)準(zhǔn)的Modicon控制器使用RS232C實(shí)現(xiàn)串行的Modbus。Modbus的ASCII、RTU協(xié)議規(guī)定了消息、數(shù)據(jù)的結(jié)構(gòu)、命令和就答的方式,數(shù)據(jù)通訊采用Maser/Slave方式,Master端發(fā)出數(shù)據(jù)請(qǐng)求消息,Slave端接收到正確消息后就可以發(fā)送數(shù)據(jù)到Master端以響應(yīng)請(qǐng)求;Master端也可以直接發(fā)消息修改Slave端的數(shù)據(jù),實(shí)現(xiàn)雙向讀寫。 其通信協(xié)議理解也比較簡單,其幀結(jié)構(gòu)如下 地址碼 + 功能碼 + 數(shù)據(jù)區(qū) + 錯(cuò)誤校驗(yàn) 常用功能碼 最常使用的讀寫功能碼如下; 01 讀取單個(gè)/多個(gè)線圈狀態(tài)(類似DO:數(shù)字輸出) 02 讀取單個(gè)/多個(gè)離散輸入(類似DI:數(shù)字輸入) 03 讀取單個(gè)/多個(gè)保存寄存器 04 讀取單個(gè)/多個(gè)輸入寄存器(類似AI:模擬輸入) 05 寫單個(gè)線圈狀態(tài) 06 寫單個(gè)保存寄存器 15 寫多個(gè)線圈 16 寫多個(gè)保存寄存器
FreeModbus簡析FreeMODBUS 提供了RTU/ASCII 傳輸模式及TCP協(xié)議支持。 FreeModbus協(xié)議對(duì)硬件的需求非常少——基本上任何具有串行接口,并且有一些能夠容納modbus數(shù)據(jù)幀的RAM的微控制器都足夠了。 現(xiàn)支持如下功能碼:
FreeModbus源碼解析參考:https://blog.csdn.net/u014748120/article/details/80313215
待續(xù)。。。
Modbus通信實(shí)現(xiàn)本文測試主機(jī)為 arm-linux,可以使用 libmodbus 靜態(tài)庫實(shí)現(xiàn)modbus通信,為追求可移植性,本文主要使用 freemodbus 來實(shí)現(xiàn)。 1. libmodbus使用ubuntu系統(tǒng)使用libmodbus可以使用以下命令安裝 sudo apt-get install libmodbus-dev # 或者 sudo apt-get install libmodbus5 使用文檔參考:https://lib/documentation/ 庫參考手冊(cè):https://lib/docs/v3.1.4/ 移植到arm的話則需下載源碼進(jìn)行交叉編譯 http://lib/releases/libmodbus-3.1.4.tar.gz 解壓安裝 tar -xzvf libmodbus-3.1.4.tar.gz cd libmodbus-3.1.4 # 新建安裝文件夾 mkdir -p install chmod 777 install ./configure --prefix=$(pwd)/install --host=arm-linux --enable-static ac_cv_func_malloc_0_nonnull=yes CC=arm-fsl-linux-gnueabi-gcc 在我的應(yīng)用程序工程里面新建一個(gè) libmodbus 文件夾,將上面安裝 install目錄下的 include和lib文件夾拷貝過來 我的工程總體結(jié)構(gòu)如下所示 在 mys_src 里面添加 modbus 主機(jī)測試程序 modbus_test.c makefile編寫如下所示: #編譯配置,使能為1 CONFIG_MODBUS_BUILD = 1 #當(dāng)前路徑 CUR_DIR := $(shell pwd) #libmodbus目錄 LIBMODBUS_DIR := $(CUR_DIR)/../libmodbus # 頭文件路徑 INCLUDE := INCLUDE += -I$(CUR_DIR)/../include/ ifeq ($(CONFIG_MODBUS_BUILD), 1) INCLUDE += -I$(LIBMODBUS_DIR)/include/modbus/ endif #C編譯器的選項(xiàng) CFLAGS := CFLAGS += -g -Wall CFLAGS += -std=gnu99 CFLAGS += $(INCLUDE) #庫文件參數(shù) LDFLAGS := #libmodbus共享庫鏈接 #LDFLAGS += -L$(LIBMODBUS_DIR)/lib #libmodbus靜態(tài)庫鏈接 ifeq ($(CONFIG_MODBUS_BUILD), 1) LDFLAGS += $(LIBMODBUS_DIR)/lib/libmodbus.a endif SRCS += modbus_test.c OBJS += modbus_test.o BINS += modbus_test all:$(OBJS) $(BINS) $(OBJS):%.o:%.c $(CC) -c $(CFLAGS) $^ -o $(OBJ_DIR)/$@ $(BINS):$(OBJS) $(CC) -o $(BIN_DIR)/$@ $(OBJ_DIR)/$^ $(LDFLAGS) modbus_test.c #include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <modbus.h> #define MODBUS_DEV_NAME "/dev/ttymxc3" ///< 串口設(shè)備 int main(void) { modbus_t *ctx =NULL; // 以串口的方式創(chuàng)建libmobus實(shí)例,并設(shè)置參數(shù) ctx = modbus_new_rtu(MODBUS_DEV_NAME, 115200, 'N', 8, 1); if (ctx == NULL) //使用UART4,對(duì)應(yīng)的設(shè)備描述符為ttymxc3 { fprintf(stderr, "Unable to allocate libmodbus contex\n"); return -1; } // 使用RS485時(shí)需考慮設(shè)置串口模式、RTS引腳等 // modbus_rtu_set_serial_mode(MODBUS_RTU_RS485); //設(shè)置串口模式 modbus_set_debug(ctx, 1); //設(shè)置1可看到調(diào)試信息 modbus_set_slave(ctx, 1); //設(shè)置slave ID if (modbus_connect(ctx) == -1) //等待連接設(shè)備 { fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno)); return -1; } int i,rc; uint16_t tab_reg[64] = {0}; //定義存放數(shù)據(jù)的數(shù)組 while (1) { printf("\n----------------\n"); //讀取保持寄存器的值,可讀取多個(gè)連續(xù)輸入保持寄存器 rc = modbus_read_registers(ctx, 0, 10, tab_reg); if (rc == -1) { fprintf(stderr,"%s\n", modbus_strerror(errno)); return -1; } for (i=0; i<10; i++) { printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]); } usleep(5000000); } modbus_close(ctx); //關(guān)閉modbus連接 modbus_free(ctx); //釋放modbus資源,使用完libmodbus需要釋放掉 return 0; } 編譯之后可通過nfs掛載進(jìn)行測試 modbus從機(jī)模擬 Modbus slave測試工具可以用來做modbus從機(jī)設(shè)備,從而實(shí)現(xiàn)arm控制板通過串口與PC端模擬的modbus從機(jī)進(jìn)行通信測試。 Modbus slave下載地址:https://www./download/ModbusSlaveSetup64Bit.exe 然后設(shè)置 setup->slave definition 從機(jī)ID、設(shè)置為保存寄存器,10條 同時(shí)我們也給寄存器設(shè)置一些值 開發(fā)板運(yùn)行測試程序后,成功讀取modbus從機(jī)寄存器值
2.freemodbus在linux上的使用 |
|