《電子技術應用》
您所在的位置:首頁 > 可編程邏輯 > 設計應用 > Modbus通信協(xié)議的FPGA實現(xiàn)
Modbus通信協(xié)議的FPGA實現(xiàn)
摘要: 目前Modbus協(xié)議實現(xiàn)方式多為單片機和PLC,隨著FPGA的廣泛應用,研究Modbus現(xiàn)場總線的FPGA解決方案有很大的實用價值。
Abstract:
Key words :

  現(xiàn)場總線是一種應用于生產現(xiàn)場,在現(xiàn)場設備之間,現(xiàn)場設備與控制裝置之間實現(xiàn)雙向、串行、多節(jié)點數(shù)字通信的技術。Modbus協(xié)議其節(jié)點安裝數(shù)量非常多,安裝的地區(qū)遍及世界各地。

  今天的FPGA可包含內嵌乘法器、專用計算例程和片上RAM等,加上FPGA的并行性,其結果比最快的DSP芯片還要快上500倍乃至更多。隨著FPGA價格不斷下降,甚至最小的器件都足以實現(xiàn)一個集成可選定制I/O功能的軟處理器核。可見,F(xiàn)PGA對嵌入控制應用越來越具有吸引力。

  目前Modbus協(xié)議實現(xiàn)方式多為單片機和PLC,隨著FPGA的廣泛應用,研究Modbus現(xiàn)場總線的FPGA解決方案有很大的實用價值。

  1 Modbus協(xié)議簡介

  Modbus串行鏈路系統(tǒng)可以使用不同的物理接口(RS 485,RS 232),最常用的是RS 485兩線制接口。為了提高通信模塊在工業(yè)應用中的抗干擾性和穩(wěn)定性,接口芯片和FPGA核心模塊之間應加入高速光耦進行隔離,總線兩端處放置線路終端電阻,采用屏蔽雙絞線作為通信線等。

  在串行鏈路上,Modbus RTU(Remote Terminal Unit)模式報文中每8個位字節(jié)含有兩個4位十六進制字符,這種模式的主要優(yōu)點是較高的數(shù)據(jù)密度,在相同的波特率下比ASCII模式有更高的吞吐率。RTU模式每個字節(jié)(11位)的格式如圖1所示,支持奇、偶和無校驗,使用無校驗時要求2個停止位。Modbus RTU幀最大為256B,由發(fā)送設備將Modbus報文構造為帶有已知起始和結束標記的幀,報文幀由時長至少為3.5個字符時間的空閑間隔區(qū)分,整個報文幀必須以連續(xù)的字符流發(fā)送,如果兩個字符之間的空閑間隔大于1.5個字符時間,則報文幀被認為不完整被接收節(jié)點丟棄,如圖1所示。

RTU模式每個字節(jié)

  在應用層上,Modbus是一個請求/應答協(xié)議,并且提供功能碼規(guī)定的服務。有三類Modbus功能碼:公共碼、用戶定義碼和保留碼,大多數(shù)情況下只用公共碼,其主要包括比特(線圈)訪問、16 b(寄存器)訪問、文件記錄訪問、診斷和其他信息訪問。

  2 Modbus RTU通信協(xié)議接口設計

  2.1 接口功能及模塊劃分

  Modbus RTU接口框圖及輸入、輸出引腳示意圖如圖2所示。

Modbus RTU接口框圖及輸入、輸出引腳示意圖

  在某一確定的主時鐘頻率、通信波特率和奇偶校驗方式下,通過設置CE_Modbus和R_Tn的狀態(tài),可以控制該接口模塊處于接收Modbus協(xié)議幀模式、發(fā)送Modbus協(xié)議幀模式或輸入/輸出寄存器操作模式,如表1所示。

操作模式控制

  典型的波特率和奇偶校驗位設置如表2、表3所示。這兩組控制信號可以從端口引出接到撥碼開關,然后可以通過調節(jié)撥碼開關來靈活控制該設備奇偶性與波特率,也可以通過寄存器配置方式控制。

典型的波特率和奇偶校驗位設置

  2.2 接收過程

  (1)系統(tǒng)處于接收Modbus協(xié)議幀模式下之后,清零標志位和定時器,然后啟動定時器,如果檢測到有串口輸入數(shù)據(jù),則清零定時器,如果沒有檢測到串口輸入數(shù)據(jù)且定時器第一次計時到3.5個字符時間,置幀起始標志;

  (2)把接收到的第一個字符放入接收緩沖寄存器的0x00地址(協(xié)議幀最長為256 B,故接收緩沖大小為256 B,地址為8 b),置已開始接收標志;

  (3)將接收到的正確字符依次放入接收緩沖寄存器中,即地址每次加1,每接收完一個字符之后清零定時器;如果在接收字符時檢查到起始錯誤(起始位沒有持續(xù)波特率所對應bit時間的一半),奇偶校驗錯誤,或者幀錯誤(停止位為O),則丟棄該字符,重新同步起始位;

  (4)如果檢測到兩個字符時間間隔大于1.5個字符時間,則重置幀起始標志,把下一個接收到的字符放入接收緩沖寄存器的0x00地址,再繼續(xù)步驟(3);

  (5)當檢測到?jīng)]有字符輸入且定時器第二次檢測到3.5個字符時間,置協(xié)議幀接收完全標志;

  (6)把接收緩沖區(qū)接收的數(shù)據(jù)作CRC校驗,如果校驗不正確,置幀起始標志,轉到步驟(3),繼續(xù)等待接收;如果是基于該接口的主Modbus協(xié)議設備,一般應設置超時時間,以避免無限等待;如果校驗正確,則Re_finish發(fā)出一個脈沖,認為接收了一個在數(shù)據(jù)鏈路層上正確的Mod-bus協(xié)議幀。

  對于幀錯誤(停止位為0)標志FE,奇偶校驗錯誤標志PE,最后一個接收到的數(shù)據(jù)所在接收緩沖區(qū)中的位置Rebuf_end[7..O],對外并不必須,可以留出這些端口備用,所以用虛線表示。

  2.3 輸入/輸出寄存器操作

  接收緩沖數(shù)據(jù)寄存器和發(fā)送緩沖數(shù)據(jù)寄存器都采用雙口RAM實現(xiàn),這比寄存器實現(xiàn)要節(jié)省很多資源。為了保證對它們的操作是原子的,即為了避免同時對相同地址執(zhí)行寫操作,故要求當CE_Modbus置低時,外部才可以對輸入輸出寄存器執(zhí)行寫操作,此時接口內部不會對接收/輸出寄存器執(zhí)行任何讀寫操作。

  2.4 發(fā)送過程

  (1)在發(fā)送模式使能之前,應先處于輸入/輸出寄存器模式,通過Trbuf_data[7..0],Trbuf_add[7..0],Trbuf_wren把待發(fā)送的不包括兩位CRC校驗的Modbus協(xié)議幀從地址0x00依次寫入發(fā)送緩沖寄存器中,然后使能Ld_TbNCE信號(一個時鐘周期),同時存入發(fā)送緩存寄存器所裝最后一個數(shù)據(jù)的地址,然后把該接口置于發(fā)送Modbus協(xié)議幀模式。

  (2)發(fā)送模塊先對發(fā)送數(shù)據(jù)緩沖寄存器中的所有數(shù)做CRC-16校驗,然后把計算所得結果按低位在前高位在后的順序依次放到用Ld_TbNCE信號鎖存的地址的下兩個地址位置處。

  (3)發(fā)送模塊從發(fā)送數(shù)據(jù)緩沖寄存器Ox00開始,依次讀出數(shù)據(jù)并按所給的波特率發(fā)送出去,如果要求奇偶校驗,則發(fā)送完數(shù)據(jù)之后加上計算所得的奇偶校驗位發(fā)送出去。

  (4)當發(fā)送完最后一個數(shù)據(jù)即CRC-16的高8位數(shù)據(jù)之后,Tr_finish發(fā)出一個脈沖表示發(fā)送完畢。

  3 接口模塊實現(xiàn)

  3.1 波特率發(fā)生器

  波特率發(fā)生器就是一個分頻器,根據(jù)系統(tǒng)時鐘分別發(fā)出位時鐘(Tx_clk)和1/16位時鐘(RX_clkl6)。由于系統(tǒng)的時鐘周期可能不同,為了模塊的通用性,該模塊用一個類屬(Generic)語句產生各種分頻系數(shù)。為了保證同步設計,產生的位時鐘和1/16位時鐘作為控制信號在主時鐘的驅動下控制其他模塊。

  3.2 接收模塊

  接收模塊組包括同步濾波模塊、接收機模塊、接收控制模塊、接收狀態(tài)寄存器模塊、時間標志產生模塊等。

  Modbus網(wǎng)絡中設備是運行在不相關時鐘上的,為了避免亞穩(wěn)態(tài)現(xiàn)象,要求通信信號進入FPGA時通過兩個級聯(lián)的寄存器。異步輸入信號必須在足夠的時間內保持數(shù)據(jù)有效,從而保證被目標時鐘域檢測到,在接收端則認為最少是大于幾個脈沖寬度的信號才是應該被檢測到的信號,于是在接收端加入濾波模塊,具體算法如下:連續(xù)3次檢測到為高(或低)電平時,才往接收寄存器寫入高(或低)電平,否則保持原來檢測到的電平,不到3個脈沖寬度的信號被過濾。顯然,同步濾波模塊引入了5個時鐘的延遲,但這樣的延時對于Modbus協(xié)議來說可以忽略。

  接收機模塊是一個改進的UART接收模塊,其工作流程如下:

  (1)當檢測到起始位時,繼續(xù)讀取其他位并通過移位把它們移人接收移位寄存器RSR中;

  (2)當所有的數(shù)據(jù)位和停止位都接收完畢后,置RDR寄存器滿標志RDRF位為1;

  (3)檢測停止位和奇偶校驗位,如果發(fā)現(xiàn)錯誤置相關錯誤標志位;

  (4)如果所接收數(shù)據(jù)正確,RSR中數(shù)據(jù)載入到接收數(shù)據(jù)寄存器RDR中,清除錯誤標志。

  從Rxd_syn上進入的比特流與本地的位時鐘不是同步的,為了避免可能在錯誤的時間讀取一些位,在每個比特時間采樣16次,在時鐘Rx_-clkl6的每個上升沿采樣,為了保證最大可行度,在理想情況下將在每比特時間中間進行采樣。首先判斷起始位,當檢測Rxd_syn至少連續(xù)半個位時鐘為低電平時,即從第一次檢測到低電平之后,再連續(xù)9次檢測,如果Rxd_syn為低電平的次數(shù)大于等于8次,則認為起始位到來,此時應該在起始位中間后兩個Rx_clkl6處。之后每隔16個Rx_clkl6時鐘周期在14,15,16個上升沿到來時分別采樣,然后對3次采樣結果取至少兩次相等的數(shù)據(jù)作為所接收到的值,以保證接收數(shù)據(jù)的準確性。8個數(shù)據(jù)位采集完畢之后,根據(jù)Sel_parity[1..O]信號判斷是否奇偶校驗,如果有校驗需求,則對第9個數(shù)據(jù)位的數(shù)據(jù)同樣做3次采樣取兩次相同值作為接收到的奇偶校驗位,同時計算奇偶校驗結果。在停止位(不包括起始位,無校驗時為第9位,有校驗時為第10位)到來時,同樣經(jīng)過3次采樣,但是只要檢測到1位為高就認為停止位正確,為了減少狀態(tài)機數(shù)量,可以在停止位到來時比較計算所得奇偶校驗位和接收到的奇偶校驗位從而判定接收數(shù)據(jù)是否奇偶校驗錯誤。由于接收控制器一定會讀取前一個數(shù)據(jù)字節(jié)并清零RDRF,所以常見的UART里的超限(overrun)錯誤這里并沒有出現(xiàn)。圖3為用RTUsⅡ軟件自帶仿真器仿真結果。

用<a class=Quartus" border="0" height="199" hspace="0" src="http://files.chinaaet.com/images/20100823/6cffc0e2-f204-43f2-80f7-5ad0029d3c79.jpg" width="427" />

  3.3 發(fā)送模塊

  發(fā)送模塊包括發(fā)送控制模塊,發(fā)送機模塊,發(fā)送狀態(tài)寄存器模塊等。

  發(fā)送機模塊是基于普通UART發(fā)送原理設計,其發(fā)送過程如下:

  (1)等待TDRE=‘1’,即等待發(fā)送數(shù)據(jù)寄存器(TDR)為空,隨后TDR中載入一個字節(jié)數(shù)據(jù),并把TDRE清零。

  (2)根據(jù)波特率設置Sel_baud[1..0]對TDR里的數(shù)據(jù)進行奇偶校驗計算。

  (3)把TDR里的數(shù)據(jù)放入發(fā)送移位寄存器TSR的1~8位,TSR第O位放起始位(‘O’),TSR第9位放入奇偶校驗位或者停止位(‘1’)。

  (4)通過對TSR右移,一位一位地發(fā)送出9位數(shù)據(jù)比特,最后發(fā)送停止位(‘1’)。

 

  3.4 CRC模塊

  CRC模塊包括接收CRC控制模塊,發(fā)送CRC控制模塊,CRC產生模塊三部分。

發(fā)送仿真時序圖

  生成CRC的過程為:

  (1)將一個16位寄存器裝入十六進制FFFF(全1),將之稱作CRC寄存器。

  (2)將報文的第一個8位字節(jié)與16位CRC寄存器的低字節(jié)異或,結果置于CRC寄存器。

  (3)將CRC寄存器右移1位(向LSB方向),MSB充零,提取并檢測LSB。

  (4)如果LSB為0:重復步驟(3)(另一次移位);如果LSB為1:對CRC寄存器異或多項式值0xA00l(1010000000000001)。

  (5)重復步驟(3)和(4),直到完成8次移位。當做完此操作后,將完成對8位字節(jié)的完整操作。

  (6)對報文中的下一個字節(jié)重復步驟(2)~(5),繼續(xù)此操作直至所有報文被處理完畢。

  (7)CRC寄存器中的最終內容為CRC值。

  這種方式計算CRC值的時間比其他方式計算CRC(比如查表法等)的時間稍微要長,但是它節(jié)省了資源,比如查表法計算CRC需要一個數(shù)組來存放所有可能的CRC結果值。圖5為對數(shù)據(jù)串“010300000001”(十六進制)CRC-16運算的仿真時序圖,時鐘周期為50 MHz,由圖可見,整個計算時間在2.5 μs內,估算一個含有240個字符的消息,CRC校驗總時間約為2.5μs×(240/6)=100μs,這樣長的校驗計算時間對于Modbus協(xié)議來說是完全可以接受的。

對數(shù)據(jù)串

  4 基于該接口的MODBUS從站協(xié)處理器實現(xiàn)

  協(xié)處理器框圖如圖6所示。

協(xié)處理器框圖

  從站協(xié)處理器控制模塊程序控制過程如下:

  (1)置CE_Modbus為‘1’,把MAX485芯片公式信號輸出置低,即控制RS 485接口芯片處于接收狀態(tài)。

  (2)等待一段延遲時間(RS 485接口芯片穩(wěn)定時間),使能Modbus協(xié)議接口模塊即置CE_Modbus為‘1’,并置接收Modbus協(xié)議幀模式。

  (3)如果接收到一個完整的幀(消息),則轉到步驟(4),如果沒接收到一個完整的消息,一直處于等待狀態(tài)。

  (4)先置CE_Modbus為‘O’,再解釋接收緩沖寄存器里消息,等待消息處理完畢,如果消息不是發(fā)往該從站或者為廣播消息,則轉到步驟(2);否則把公式信號輸出置高,轉到步驟(5)。

  (5)等待一段延遲時間,使能Modbus協(xié)議接口模塊即置CE_Modbus為‘1’,并置發(fā)送Modbus協(xié)議幀模式。

  (6)等待發(fā)送完成,轉到步驟(1)。

  解釋模塊主要由解釋控制模塊、分析模塊、各功能碼解釋模塊、錯誤功能碼處理模塊組成。分析模塊首先分析接收消息起始兩個字節(jié),即地址碼和功能碼。如果地址為廣播消息地址(地址為0)或者地址碼和本從站地址不相等,則不處理本消息,解釋控制模塊發(fā)出解釋完畢并置不響應信號為“1”,頂層控制模塊繼續(xù)處于等待接收消息狀態(tài)。如果功能碼為非支持功能碼,則選擇錯誤功能代碼處理模塊;如果為某一支持的功能碼,則選擇相應的功能模塊解釋接收消息,按照功能碼要求解碼(例如讀/寫某一指定寄存器或者線圈)。處理完之后把相應的異常碼響應消息或者正常響應消息寫入Modbus協(xié)議接口模塊里的發(fā)送緩沖寄存器里,完畢之后通過Ld_TbNCE信號把發(fā)送緩沖寄存器鎖存消息的末地址(不帶CRC校驗位)Trbuf_add[7..O](保證在Ld_TbNCE有效時它為末地址)存入Modbus協(xié)議接口模塊,發(fā)出解釋完畢信號,不響應信號置“O”,之后由頂層控制模塊控制接口模塊發(fā)送響應消息。對于某些功能碼,比如01碼和02碼,03碼和04碼,由于對它們的解釋差別很小,可以共用一個模塊,達到節(jié)省資源的目的。對于特定的系統(tǒng),完全可以選擇某一些功能碼甚至某一個功能碼,而達到需求,故這里采用這種模塊化方式,可以很容易在不改變其他功能模塊的情況下刪除不需要的功能碼模塊或者增加新需要的功能碼模塊。

  該協(xié)處理器與從設備其他部分接口僅僅為雙口RAM,從設備完全被映射為寄存器組的抽象,這比啟用寄存器直接實現(xiàn)要節(jié)省邏輯資源。由于這些雙口RAM是完全透明的,用戶可以根據(jù)整個Modbus系統(tǒng)需要自定義各個寄存器的實際含義。Modbus主設備可以在任何時候隨機地訪問這些寄存器組。Modbus從設備控制、執(zhí)行模塊對這些寄存器組的訪問需要尋求一種較好的方式,由于FPGA的高速度及并行機制,一般情況下可以采取輪詢的機制即可滿足工業(yè)實時性需求。對于某些特殊情況需要更高優(yōu)先級的控制方式,也可以采取中斷方式。如圖7所示,可以通過雙口RAM的地址線和寫使能信號線進行中斷檢測和沖突檢測:當從站協(xié)處理模塊對某些特定寄存器讀/寫完畢之后,產生一個中斷信號,對某些可能存在從站協(xié)處理器模塊和從設備控制執(zhí)行模塊都要對其進行寫操作的寄存器,如果有寫操作同時發(fā)生,則從設備控制執(zhí)行模塊應該等待從站協(xié)處理器寫完再寫,以保證寫操作是原子的。圖8為03碼應答的完整仿真時序。

 

 從設備寄存器訪問抽象

03碼應答的完整仿真時序

  圖9為示波器在通信線路上檢測到的波形,圖9(a)展現(xiàn)了一系列連續(xù)幀通信實況;圖9(b)展現(xiàn)某一應答情況,可以看出主機和從機通信電平有差異,但都在RS 485范圍之內;圖9(c)展現(xiàn)了某一幀的具體情況。

示波器在通信線路上檢測到的波形

  5 結語

  該設計基于Altera公司FPGA,首先設計了一個可以通用于Modbus主設備和從設備的Modbus協(xié)議接口,然后基于該協(xié)議接口設計了一個通用的Modbus從設備協(xié)處理器,該接口也可以方便地用于主協(xié)議設備中。本設計通過了多款FPGA芯片的綜合驗證,并與WEINVIEW公司觸摸屏MT-506MV和INVT公司CHF1OO-5R5G/7R5P變頻器成功通信。目前該設計已在某工業(yè)EPS系統(tǒng)和某沖擊試驗臺中穩(wěn)定運行半年,可見其有一定應用前景。

此內容為AET網(wǎng)站原創(chuàng),未經(jīng)授權禁止轉載。