文中介紹了Modbus RTU通訊協(xié)議的特點(diǎn),闡述了該協(xié)議在VC2005編程環(huán)境下申口調(diào)試軟件的具體實(shí)現(xiàn)方法。并編制了相關(guān)的程序,該程序采用了模塊化思想,結(jié)構(gòu)清晰,操作簡(jiǎn)便,實(shí)現(xiàn)了良好的ModbusRTU報(bào)文儲(chǔ)存及管理機(jī)制,使用多線程兼顧界面顯示和數(shù)據(jù)通訊,完全兼容ModbuaRTU通訊協(xié)議,可用于自定義功能碼的Modbus兼容設(shè)備的調(diào)試,克服了普通Modbus調(diào)試軟件僅能用于Modbus標(biāo)準(zhǔn)功能碼調(diào)試的不足。實(shí)踐證明,該程序編制思想合理、運(yùn)行穩(wěn)定、操作簡(jiǎn)便易行,為工業(yè)自動(dòng)化中Modbus設(shè)備的調(diào)試帶來(lái)方便。
Modbus通信協(xié)議是Modieon公司開(kāi)發(fā)的一種通信協(xié)議,它采用主從問(wèn)答方式工作,是一種真正開(kāi)放、標(biāo)準(zhǔn)的、免收許可費(fèi)的網(wǎng)絡(luò)通信協(xié)議。廣泛用于自動(dòng)化控制器和測(cè)控儀表,現(xiàn)已成為一種公認(rèn)的通用工業(yè)標(biāo)準(zhǔn)。如今Modbus協(xié)議已經(jīng)成為我國(guó)工業(yè)自動(dòng)化網(wǎng)絡(luò)協(xié)議規(guī)范的國(guó)家標(biāo)準(zhǔn)之一。不同廠商生產(chǎn)的控制設(shè)備可以籍此連成工業(yè)網(wǎng)絡(luò)。進(jìn)行集中監(jiān)控。該協(xié)議有2種傳輸模式,即RTU模式和ASCII模式。對(duì)于ASCII模式,一個(gè)信息幀中的每8位的字節(jié)作為2個(gè)ASCII字符傳輸;而對(duì)于RTU模式。信息幀中的8位數(shù)據(jù)作為2個(gè)4位16進(jìn)制字符,相對(duì)于ASCII模式,RTU模式表達(dá)相同的信息需要較少的位數(shù),且在相同通信速率下具有更大的數(shù)據(jù)流量。因此通常情況下,一般工業(yè)智能儀表儀器都是采用RTU模式的Modbus規(guī)約。
信息傳輸為異步方式,并以字節(jié)為單位。在主站和從站之間傳遞的通訊報(bào)文的信息幀格式如表1所示。
ModbusRTU采用主從方式,若主機(jī)設(shè)備發(fā)送一個(gè)信息,則可從一臺(tái)從機(jī)設(shè)備返回一個(gè)響應(yīng),類似的,當(dāng)一臺(tái)從機(jī)設(shè)備接受信息時(shí),它就組織一個(gè)從機(jī)設(shè)備的響應(yīng)信息,并返回至原發(fā)送信息的主機(jī)設(shè)備。
當(dāng)通訊命令由主機(jī)發(fā)送至從機(jī)時(shí),符合相應(yīng)地址碼的從機(jī)接收通訊命令,并根據(jù)功能碼及相關(guān)要求讀取信息,如果CRC校驗(yàn)無(wú)誤,則執(zhí)行相應(yīng)的任務(wù),然后把執(zhí)行結(jié)果返送給主機(jī)。
表1 Modbus RTU信息幀格式
Modbus RTU的查詢響應(yīng)周期如圖1所示。
3.1主體架構(gòu)
軟件采用兩個(gè)線程,主線程顯示主界面,用來(lái)設(shè)置數(shù)據(jù)。報(bào)文處理線程用來(lái)監(jiān)聽(tīng)報(bào)文幀、分析報(bào)文、取出主界面設(shè)置的數(shù)據(jù)并打包作出回應(yīng)[6l。
對(duì)于各部分的功能用類進(jìn)行封裝處理,力求使程序簡(jiǎn)潔易懂、便于移植。程序中所用的各種模塊如下[7,8]:
(1)線程問(wèn)數(shù)據(jù)傳送模塊:用于主線程與子線程間傳送主界面所設(shè)置的數(shù)據(jù),采用全局變量進(jìn)行線程間通信,使用互斥體(CMutex)進(jìn)行線程同步。
(2)串口數(shù)據(jù)收發(fā)模塊:用于串口打開(kāi)、關(guān)閉等常用操作及串口數(shù)據(jù)的收發(fā),為保證串口收發(fā)模塊的靈活性,模塊中串口數(shù)據(jù)的收發(fā)程序采用了串口操作相關(guān)的WindowsAPI函數(shù)。
(3)Modbus協(xié)議模塊:對(duì)串口數(shù)據(jù)收發(fā)模塊再次封裝并實(shí)現(xiàn)了ModbusR,rU的各種報(bào)文規(guī)范。定義了報(bào)文格式的兩種結(jié)構(gòu)——PDU(協(xié)議數(shù)據(jù)單元)和ADU(應(yīng)用數(shù)據(jù)單元),及兩者相互轉(zhuǎn)化的方法。并在此基礎(chǔ)上實(shí)現(xiàn)了對(duì)接受報(bào)文的判斷解析和對(duì)欲發(fā)送報(bào)文組織打包。
(4)CRC校驗(yàn)?zāi)K:用于生成發(fā)送報(bào)文的16位CRC校驗(yàn)碼,并對(duì)接受的報(bào)文再次生成CRC校驗(yàn)碼以便于與原校驗(yàn)碼進(jìn)行比對(duì)。
報(bào)文處理線程的流程圖如圖2所示。
3.2報(bào)文數(shù)據(jù)的存儲(chǔ)及管理
為了存儲(chǔ)報(bào)文中的數(shù)據(jù),在內(nèi)存中劃分出來(lái)一個(gè)256Bytes大小的報(bào)文緩沖區(qū)。收到的報(bào)文和打包好的報(bào)文都暫存在該區(qū)域中。也就是說(shuō)對(duì)報(bào)文的解析和打包就變成了對(duì)報(bào)文緩沖區(qū)的操作[9,10]。為了更好地管理報(bào)文緩沖區(qū),定義了兩個(gè)結(jié)構(gòu)PDU一HANDLE模擬是PDU(報(bào)文數(shù)據(jù)單元),其中PDU—HANDLE模擬的是PDU(報(bào)文數(shù)據(jù)單元),ADU一CONTROI模擬的是ADU(協(xié)議數(shù)據(jù)單元)[11l。二者定義如下:
struet PDU—HANDLE
{
unsignedchar*PDUBuffPtr;//PUD數(shù)據(jù)指針
urlsigned
char FunctionCode;//請(qǐng)求功能代碼
umigrled$l'92rt PD‰h;//PDU字節(jié)長(zhǎng)度
unsigned
char Exeeptiong硝e;//異常代碼
};
Sta"uct ADU_CONTROL,
{
unsigned char*ADUBuffPtr;//ADU緩沖區(qū)指針,指向報(bào)文緩沖區(qū)
unsigned char ADULength;//設(shè)備地址
unsigned short ADULength;//ADU字節(jié)長(zhǎng)度
};
對(duì)PDU_HANDIE和ADU_CONTROL操作的函數(shù)主要有PackDU2PDU()、ClearPDUBuf()、PackP_DU2ADU()。其主要流程是:
1)收到合法的報(bào)文后,對(duì)結(jié)構(gòu)ADU-CONTROL進(jìn)行填充。報(bào)文被存儲(chǔ)在ADU—CoNTROL的成員AD切3uffPtr指向的內(nèi)存單元中。報(bào)文其它相關(guān)信息(從機(jī)地址,報(bào)文長(zhǎng)度)填充到ADU—CONTRoI.的剩余成員中。
2)執(zhí)行PackADU2PDU()。完成ADU向PDU的轉(zhuǎn)換。此步主要完成CRCl6校驗(yàn)碼比對(duì),并依據(jù)ADU—CONTRoI的成員完成對(duì)PDU_HANDLE的填充,以便于后續(xù)對(duì)PDU內(nèi)容的分析處理。
3)執(zhí)行ClearPDUBuf() ,清空PDU數(shù)據(jù)緩沖區(qū)內(nèi)容。此時(shí)已經(jīng)完成對(duì)接受報(bào)文的分析,要清空PDU數(shù)據(jù)緩沖區(qū)內(nèi)容.以裝填欲發(fā)送的PDU數(shù)據(jù)。
4)執(zhí)行PackPDU2ADU()。使PDU頭部加上設(shè)備地址,尾部附加CRcl6校驗(yàn)碼。此時(shí)封裝成了完整的報(bào)文,以便發(fā)送。
3.3功能碼及相應(yīng)處理函數(shù)本程序?qū)Σ煌墓δ艽a設(shè)置了不同的處理函數(shù)。
出了部分標(biāo)準(zhǔn)功能碼及相應(yīng)的處理函數(shù)。Modbus調(diào)試軟件一般作為從機(jī)。對(duì)主機(jī)發(fā)來(lái)的符合Modbus協(xié)議的報(bào)文進(jìn)行解析回應(yīng)。普通的Modbus調(diào)試軟件一般只能對(duì)上述四種標(biāo)準(zhǔn)功能碼進(jìn)行解析回應(yīng)。但是對(duì)于實(shí)際的Modbus設(shè)備來(lái)說(shuō)。這四種功能碼是遠(yuǎn)遠(yuǎn)不夠的,更多的時(shí)候需要自定義功能碼來(lái)完成相關(guān)的功能。為了完成對(duì)自定義功能碼的調(diào)試??梢栽谡{(diào)試軟件中加入自定義功能碼處理函數(shù)。這樣便可以使此程序有更強(qiáng)的針對(duì)性[7]。
表2部分標(biāo)準(zhǔn)Modbus功能碼及其處理函數(shù)
功能碼 | 對(duì)應(yīng)函數(shù) | 功能描述 |
0x01 | ReadCoils | 讀線圈 |
0x02 | ReadDiscretlnputs | 讀離散輸入量 |
0x03 | ReadHoldReg | 讀保持繼存器 |
0x04 | ReadInputReg | 讀輸入繼存器 |
3.4程序的界面
圖3所示為MoDbusRTU串日調(diào)試軟件的主界面。圖4為上位機(jī)軟件與ModbosRTU串口調(diào)試軟件的通信界面。可以看出該Modbus RTU調(diào)試軟件工作正常。
圖3 ModbusRTU串口調(diào)試軟件界面
圖4上位機(jī)軟件與ModbusRTU串口調(diào)試軟件的通信界面
利用上述方法,在VC2005環(huán)境下編制的基于ModbusRTU的串口調(diào)試軟件,在某自動(dòng)化企業(yè)小型PLC研發(fā)項(xiàng)目的上位機(jī)與下位機(jī)通信調(diào)試中得到應(yīng)用。既能對(duì)標(biāo)準(zhǔn)Modbus功能碼進(jìn)行調(diào)試,也可對(duì)自定義功能碼進(jìn)行調(diào)試。實(shí)踐證明程序運(yùn)行穩(wěn)定、可靠,操作簡(jiǎn)便、易行。為自定義功能碼的Modbus RTU串口調(diào)試提供了一條簡(jiǎn)潔、可行的解決方法。