Modbus通信協(xié)議的FPGA實現(xiàn)
(4)如果檢測到兩個字符時間間隔大于1.5個字符時間,則重置幀起始標志,把下一個接收到的字符放入接收緩沖寄存器的0x00地址,再繼續(xù)步驟(3);
(5)當檢測到沒有字符輸入且定時器第二次檢測到3.5個字符時間,置協(xié)議幀接收完全標志;
(6)把接收緩沖區(qū)接收的數(shù)據作CRC校驗,如果校驗不正確,置幀起始標志,轉到步驟(3),繼續(xù)等待接收;如果是基于該接口的主Modbus協(xié)議設備,一般應設置超時時間,以避免無限等待;如果校驗正確,則Re_finish發(fā)出一個脈沖,認為接收了一個在數(shù)據鏈路層上正確的Mod-bus協(xié)議幀。
對于幀錯誤(停止位為0)標志FE,奇偶校驗錯誤標志PE,最后一個接收到的數(shù)據所在接收緩沖區(qū)中的位置Rebuf_end[7..O],對外并不必須,可以留出這些端口備用,所以用虛線表示。
2.3 輸入/輸出寄存器操作
接收緩沖數(shù)據寄存器和發(fā)送緩沖數(shù)據寄存器都采用雙口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ù)據的地址,然后把該接口置于發(fā)送Modbus協(xié)議幀模式。
(2)發(fā)送模塊先對發(fā)送數(shù)據緩沖寄存器中的所有數(shù)做CRC-16校驗,然后把計算所得結果按低位在前高位在后的順序依次放到用Ld_TbNCE信號鎖存的地址的下兩個地址位置處。
(3)發(fā)送模塊從發(fā)送數(shù)據緩沖寄存器Ox00開始,依次讀出數(shù)據并按所給的波特率發(fā)送出去,如果要求奇偶校驗,則發(fā)送完數(shù)據之后加上計算所得的奇偶校驗位發(fā)送出去。
(4)當發(fā)送完最后一個數(shù)據即CRC-16的高8位數(shù)據之后,Tr_finish發(fā)出一個脈沖表示發(fā)送完畢。
3 接口模塊實現(xiàn)
3.1 波特率發(fā)生器
波特率發(fā)生器就是一個分頻器,根據系統(tǒng)時鐘分別發(fā)出位時鐘(Tx_clk)和1/16位時鐘(RX_clkl6)。由于系統(tǒng)的時鐘周期可能不同,為了模塊的通用性,該模塊用一個類屬(Generic)語句產生各種分頻系數(shù)。為了保證同步設計,產生的位時鐘和1/16位時鐘作為控制信號在主時鐘的驅動下控制其他模塊。
3.2 接收模塊
接收模塊組包括同步濾波模塊、接收機模塊、接收控制模塊、接收狀態(tài)寄存器模塊、時間標志產生模塊等。
Modbus網絡中設備是運行在不相關時鐘上的,為了避免亞穩(wěn)態(tài)現(xiàn)象,要求通信信號進入FPGA時通過兩個級聯(lián)的寄存器。異步輸入信號必須在足夠的時間內保持數(shù)據有效,從而保證被目標時鐘域檢測到,在接收端則認為最少是大于幾個脈沖寬度的信號才是應該被檢測到的信號,于是在接收端加入濾波模塊,具體算法如下:連續(xù)3次檢測到為高(或低)電平時,才往接收寄存器寫入高(或低)電平,否則保持原來檢測到的電平,不到3個脈沖寬度的信號被過濾。顯然,同步濾波模塊引入了5個時鐘的延遲,但這樣的延時對于Modbus協(xié)議來說可以忽略。
接收機模塊是一個改進的UART接收模塊,其工作流程如下:
(1)當檢測到起始位時,繼續(xù)讀取其他位并通過移位把它們移人接收移位寄存器RSR中;
(2)當所有的數(shù)據位和停止位都接收完畢后,置RDR寄存器滿標志RDRF位為1;
(3)檢測停止位和奇偶校驗位,如果發(fā)現(xiàn)錯誤置相關錯誤標志位;
(4)如果所接收數(shù)據正確,RSR中數(shù)據載入到接收數(shù)據寄存器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ù)據作為所接收到的值,以保證接收數(shù)據的準確性。8個數(shù)據位采集完畢之后,根據Sel_parity[1..O]信號判斷是否奇偶校驗,如果有校驗需求,則對第9個數(shù)據位的數(shù)據同樣做3次采樣取兩次相同值作為接收到的奇偶校驗位,同時計算奇偶校驗結果。在停止位(不包括起始位,無校驗時為第9位,有校驗時為第10位)到來時,同樣經過3次采樣,但是只要檢測到1位為高就認為停止位正確,為了減少狀態(tài)機數(shù)量,可以在停止位到來時比較計算所得奇偶校驗位和接收到的奇偶校驗位從而判定接收數(shù)據是否奇偶校驗錯誤。由于接收控制器一定會讀取前一個數(shù)據字節(jié)并清零RDRF,所以常見的UART里的超限(overrun)錯誤這里并沒有出現(xiàn)。圖3為用QuartusⅡ軟件自帶仿真器仿真結果。
評論