本文筆者最近的項(xiàng)目是設(shè)計(jì)一款運(yùn)動(dòng)控制器,MCU使用的是STM32F429,要求是通過Modbus TCP協(xié)議實(shí)現(xiàn)與示教器通訊,并通過ModbusRTU實(shí)現(xiàn)與觸摸屏通訊。
本文將介紹在STM32F4上實(shí)現(xiàn) ModbusTCP和ModbusRTU通訊 的過程。筆者才疏學(xué)淺,如有錯(cuò)誤還請(qǐng)指正。
一、FreeModbus介紹
1.1?FreeModbus的獲取
Modbus協(xié)議是典型的主-從通訊結(jié)構(gòu),鏈路中只能有一臺(tái)主設(shè)備,可以有多臺(tái)從設(shè)備。主設(shè)備向從設(shè)備發(fā)送請(qǐng)求指令,從設(shè)備對(duì)該指令進(jìn)行響應(yīng)。從設(shè)備不能主動(dòng)向主設(shè)備發(fā)送指令,并且從設(shè)備之間也不能進(jìn)行通信。
FreeModbus是一個(gè)開源的Modbus通信協(xié)議實(shí)現(xiàn)庫(kù)??梢杂糜谠谇度胧较到y(tǒng)中實(shí)現(xiàn)Modbus通信協(xié)議,支持Modbus RTU、Modbus TCP和ModBus-ASSCII。目前,F(xiàn)reeModbus最新版本是V1.6,可以通過官網(wǎng)下載,鏈接如下:
FreeMODBUS - A free MODBUS ASCII/RTU and TCP implementation
1.2?FreeModbus文件介紹
解壓下載的文件,我們主要關(guān)注兩個(gè)文件夾。一是modbus文件夾(FreeModbus 的協(xié)議棧源碼),二是demo文件夾(不同平臺(tái)上移植FreeModbus的案例)
打開ModBus文件夾,里面有五個(gè)文件夾和一個(gè)C文件,說明如下:
名稱 | 說明/描述 |
---|---|
ascii | 這個(gè)文件夾包含Modbus-ASCII協(xié)議的實(shí)現(xiàn)代碼 |
functions | 這個(gè)文件夾主要包括一些功能碼對(duì)應(yīng)的處理函數(shù) |
include | 里面主要是Modbus協(xié)議需要使用的一些頭文件和配置文件 |
rtu | 這個(gè)文件夾包含Modbus-RTU協(xié)議的實(shí)現(xiàn)代碼 |
tcp | 這個(gè)文件夾包含Modbus-TCP協(xié)議的實(shí)現(xiàn)代碼 |
mb.c | 這個(gè)是MODBUS協(xié)議棧的主文件,這個(gè)文件夾只是一個(gè)框架,與具體的協(xié)議無關(guān)。因?yàn)镸odbus有三種具體的協(xié)議,分別為RTU、ASCII和TCP,具體的實(shí)現(xiàn)在1、4、5文件夾中,而mb.c在初始化的時(shí)候會(huì)根據(jù)使用情況將指針指向具體的處理函數(shù) |
在STM32F4平臺(tái)實(shí)現(xiàn)ModbusTCP和ModbusRTU通訊,并不需要ascii這個(gè)文件夾,該文件對(duì)應(yīng)ModBus-asscii開發(fā)。
1.3?Modbus幀結(jié)構(gòu)
Modbus RTU數(shù)據(jù)幀由四部分組成,設(shè)備地址,功能碼,數(shù)據(jù)和校驗(yàn)。具體介紹見下圖。
ModbusTCP的數(shù)據(jù)幀可分為三部分:報(bào)文頭(MBAP)+功能代碼+數(shù)據(jù)。相比Modbus RTU數(shù)據(jù)幀沒有校驗(yàn)。各部分分布見下圖。
ModbusTCP報(bào)文頭分為4個(gè)域,共7字節(jié),其組成如下:
域 | 長(zhǎng)度 | 描述 |
---|---|---|
事務(wù)源標(biāo)識(shí)符 | 2字節(jié) | Modbus請(qǐng)求/相應(yīng)事務(wù)處理的識(shí)別碼 |
協(xié)議標(biāo)識(shí)符 | 2字節(jié) | 0x00:Modbus協(xié)議 |
長(zhǎng)度 | 2字節(jié) | 數(shù)據(jù)長(zhǎng)度,單位為字節(jié) |
單元標(biāo)識(shí)符 | 1字節(jié) | 以太網(wǎng)總線上遠(yuǎn)程從站的識(shí)別碼 |
二、FreeModbus在STM32上的移植
ModbusTCP和ModbusRTU參考博主 ASWaterbenben?在STM32F767的移植案例,博主的介紹很詳細(xì),參考博客移植就可以,筆者在這不展開闡述。
基于STM32F767通過STM32CubeMX實(shí)現(xiàn)ModbusTCP從站(后續(xù))_str71xtcp_ASWaterbenben的博客-CSDN博客https://blog.csdn.net/ASWaterbenben/article/details/97685006
基于STM32CubeMX移植freeModbusRTU(從站)_embregcoilscb_ASWaterbenben的博客-CSDN博客https://blog.csdn.net/ASWaterbenben/article/details/105549750?ops_request_misc=&request_id=3fbbd9c11cc9443e9ee54cd4256b04d0&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~koosearch~default-5-105549750-null-null.268^v1^control&utm_term=Modbus&spm=1018.2226.3001.4450
三、Modbus TCP的使用方式
3.1?Modbus TCP的工作流程
在Modbus TCP初始化和使能之后,在程序主循環(huán)任務(wù)中調(diào)用調(diào)用 eMBPoll() 進(jìn)行輪詢,當(dāng)獲取Modbus TCP事件后(即 xMBPortEventGet( &eEvent ) == TRUE?),根據(jù)接收到的功能碼對(duì)應(yīng)啟動(dòng)?xFuncHandlers.pxHandler 中相應(yīng)的功能函數(shù),主要功能碼與RTU一樣,詳見下表:
功能碼 | 名稱 | 位/字操作 | 操作數(shù)量 |
---|---|---|---|
0x01 | 讀線圈狀態(tài) | 位操作 | 單個(gè)或多個(gè) |
0x02 | 讀離散輸入狀態(tài) | 位操作 | 單個(gè)或多個(gè) |
0x03 | 讀保持寄存器 | 字操作 | 單個(gè)或多個(gè) |
0x04 | 讀輸入寄存器 | 字操作 | 單個(gè)或多個(gè) |
0x05 | 寫線圈狀態(tài) | 位操作 | 單個(gè) |
0x06 | 寫單個(gè)保持寄存器 | 字操作 | 單個(gè) |
0x0F | 寫多個(gè)線圈 | 位操作 | 多個(gè) |
0x10 | 寫多個(gè)保持寄存器 | 字操作 | 多個(gè) |
表中?涉及到線圈、離散輸入、保持、輸入四種寄存器,各寄存器介紹如下:
名稱 | 介紹 | 操作函數(shù) |
---|---|---|
線圈寄存器 | 可以類比為開關(guān)量(繼電器狀態(tài)),每一個(gè)bit對(duì)應(yīng)一個(gè)信號(hào)的開關(guān)狀態(tài)。所以一個(gè)byte就可以同時(shí)控制8路的信號(hào)。比如控制外部8路io的高低。 為可讀可寫。 | eMBRegCoilsCB |
離散輸入寄存器 | 離散輸入寄存器就相當(dāng)于線圈寄存器的只讀模式,他也是每個(gè)bit表示一個(gè)開關(guān)量,而他的開關(guān)量只能讀取輸入的開關(guān)信號(hào) | eMBRegDiscreteCB |
保持寄存器 | 寄存器單位為兩個(gè)byte,可以存放具體的數(shù)據(jù)量,為可讀可寫。一般對(duì)應(yīng)參數(shù)設(shè)置 | eMBRegHoldingCB |
?輸入寄存器 | 與保持寄存器類似,只支持讀而不能寫,一般是讀取各種實(shí)時(shí)數(shù)據(jù) | eMBRegInputCB |
?在 modbus_CB.c 文件中,有以下的聲明,建立了以上四種寄存器,在?eMBRegInputCB 、eMBRegHoldingCB、?eMBRegCoilsCB 、eMBRegDiscreteCB 函數(shù)中有相關(guān)的調(diào)用。
uint16_t DB_R[88]; //保持寄存器數(shù)值存儲(chǔ)空間
uint16_t DB_C[88]; //線圈寄存器數(shù)值存儲(chǔ)空間
uint16_t DB_I[88]; //輸入流數(shù)值存儲(chǔ)空間
uint16_t DB_D[88]; //離散量數(shù)值存儲(chǔ)空間
3.2?Modbus TCP測(cè)試
第二章節(jié)分享的博客中,博主 ASWaterbenben 已經(jīng)介紹ModbusTool工具的使用過程。筆者在此介紹使用 Matlab 軟件進(jìn)行測(cè)試。
將工程編譯后下載到開發(fā)板,用網(wǎng)線連接開發(fā)版和計(jì)算機(jī)。MATLAB - Modbus TCP客戶端中幾個(gè)關(guān)鍵的函數(shù)如下所示:
函數(shù) | 說明 |
---|---|
modbus | 創(chuàng)建MODBUS對(duì)象 |
read | 從MODBUS服務(wù)器讀取數(shù)據(jù) |
write | 對(duì)連接的MODBUS服務(wù)器執(zhí)行寫操作 |
writeRead | 在單個(gè)MODBUS事務(wù)中對(duì)一組保持寄存器執(zhí)行寫然后讀操作 |
maskWrite | 在保持寄存器上執(zhí)行掩碼寫入操作 |
直接上MATLAB操作代碼,方便理解:
mbConnector = modbus('tcpip','127.0.0.1',502); % 創(chuàng)建modbus連接對(duì)象
mbConnector.Timeout = 20; % 設(shè)置連接超時(shí)時(shí)間
set(mbConnector,'WordOrder','little-endian'); % 設(shè)置為小端模式
% modbus保持寄存器寫入數(shù)據(jù)
% 參數(shù)依次為 (modbus對(duì)象、寄存器類型、開始地址、寫入數(shù)據(jù)、數(shù)據(jù)類型)
% 下列代碼表示在保持寄存器的第10個(gè)寄存器寫入"123",數(shù)據(jù)類型為int16
write(mbConnector, 'holdingregs', 10, 123, 'int16');
% 下列代碼表示在保持寄存器的第20個(gè)寄存器依次寫入"1 2 3",數(shù)據(jù)類型為int16
write(mbConnector,'holdingregs',20,[1 2 3],'int16')
% modbus讀取保持寄存器數(shù)據(jù)
% 參數(shù)依次為 (modbus對(duì)象、寄存器類型、開始地址、讀取數(shù)據(jù)個(gè)數(shù)、數(shù)據(jù)類型)
% 下列代碼表示從保持寄存器的第10個(gè)寄存器起,讀取1個(gè)數(shù)據(jù),數(shù)據(jù)類型為int16
data1 = read(mbConnector,'holdingregs',10,1,'int16')
% 下列代碼表示從保持寄存器的第20個(gè)寄存器起,讀取3個(gè)數(shù)據(jù),數(shù)據(jù)類型為int16
data2 = read(mbConnector,'holdingregs',20,3,'int16')
% modbus線圈寄存器寫入數(shù)據(jù)
% 下列代碼表示從線圈寄存器的第1個(gè)寄存器寫入1
write(mbConnector, 'coils', 1, 1);
% modbus讀取線圈寄存器數(shù)據(jù)
% 下列代碼表示從線圈寄存器的第1個(gè)寄存器起,讀取16bit
data3 = read(mbConnector,'coils',1,16)
% modbus讀取輸入寄存器數(shù)據(jù)
% 下列代碼表示從輸入寄存器的第1個(gè)寄存器起,讀取3個(gè)數(shù)據(jù),數(shù)據(jù)類型為int16
data4 = read(mbConnector,'inputregs',1,3,'int16')
% modbus讀取離散輸入寄存器數(shù)據(jù)
% 下列代碼表示從離散輸入寄存器的第1個(gè)寄存器起,讀取16bit
data5 = read(mbConnector,'input',1,16)
% 斷開并清除Modbus連接
clear mbConnector
四、結(jié)語
本文介紹了基于FreeModbus在STM32F4平臺(tái)實(shí)現(xiàn)ModbusTCP,為筆者運(yùn)動(dòng)控制器項(xiàng)目中的一環(huán),關(guān)于運(yùn)動(dòng)控制器的設(shè)計(jì)可參考本博客。文章來源:http://www.zghlxwxcb.cn/news/detail-755373.html
基于STM32F429 + ECM-XFU搭建運(yùn)動(dòng)控制平臺(tái),實(shí)現(xiàn)EtherCAT通訊_河貍打撈員的博客-CSDN博客https://blog.csdn.net/weixin_48501028/article/details/132272572?spm=1001.2014.3001.5501筆者剛接觸數(shù)控,相關(guān)知識(shí)欠缺,如有錯(cuò)誤還請(qǐng)指正,歡迎一同交流進(jìn)步!?。?span toymoban-style="hidden">文章來源地址http://www.zghlxwxcb.cn/news/detail-755373.html
到了這里,關(guān)于運(yùn)動(dòng)控制器設(shè)計(jì)——基于FreeModbus在STM32F4平臺(tái)實(shí)現(xiàn)ModbusTCP和ModbusRTU的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!