燕伯峰 董永樂 余 佳 劉宇鵬 黃 欣 石浩淵
(1.內(nèi)蒙古電力(集團)有限責任公司,內(nèi)蒙古 呼和浩特 010020;2.內(nèi)蒙古電力科學研究院,內(nèi)蒙古 呼和浩特 010020)
RS-232 接口是1970 年由美國電子工業(yè)協(xié)會(EIA)聯(lián)合貝爾系統(tǒng)、調(diào)制解調(diào)器廠家及計算機終端生產(chǎn)廠家共同制定的用于串行通信的標準[1]。常見的RS-232 串口有DB25 和DB9 2種,接口定義如圖1 所示。RS-232 通信協(xié)議因其低成本和高可靠性而被廣泛應(yīng)用,加上其占用的I/O 口數(shù)量少,許多以嵌入式微處理器為核心的控制系統(tǒng)中常常采用該技術(shù)[2]。工業(yè)控制的RS-232 口一般只使用RXD、TXD、GND 3 條線,使用簡單方便。FPGA 即現(xiàn)場可編程門陣列,是在PAL、GAL、CPLD等可編程器件的基礎(chǔ)上發(fā)展而來,作為專用集成電路領(lǐng)域中的一種半定制電路,它既解決了定制電路生成周期長且內(nèi)部電路不能更改的不足,又克服了原有的可編程器件門電路有限的缺點[3]。該文的邏輯設(shè)計是基于Altera 公司的Cyclone V 系列FPGA,型號為DE10-Nano,開發(fā)板上同時集成了Cortex-A9 ARM 處理器,提高了設(shè)計的靈活性。
RS-232 電平是負邏輯,即邏輯‘1’是-15V~ -5V,邏輯‘0’是+5 V~+15 V,與TTL 電平相反,使用時需要注意。RS-232 為串行異步通信,每一數(shù)據(jù)幀由起始位、數(shù)據(jù)位、奇偶校驗位(可省略)、停止位和線路空閑位組成[4],如圖2 所示。一般情況下,起始位為1 位,數(shù)據(jù)位為5、6、7或8 位,奇偶校驗位為1 位,停止位為1、1.5 或2 位。在無數(shù)據(jù)傳送時,傳送線為邏輯‘1’,處于空閑狀態(tài),當檢測到低電平后,為數(shù)據(jù)傳輸?shù)摹捌鹗嘉弧保箝_始傳送數(shù)據(jù)位,低位在前,高位在后,發(fā)完數(shù)據(jù)位后,根據(jù)所發(fā)數(shù)據(jù)發(fā)送奇校驗位或偶校驗位,最后以一位高電平作為停止位結(jié)束該次數(shù)據(jù)傳送[5]。傳送的速率一般為9 600 bps 或115 200 bps 等。該文在RS-232 串口通信協(xié)議的基礎(chǔ)上,利用FPGA 對該協(xié)議進行模擬仿真,進行數(shù)據(jù)的接收與發(fā)送,并利用串口調(diào)試助手進行在線測試。之后,再利用FPGA 模擬一款電表計量芯片的數(shù)據(jù)存儲與交換的過程。
圖1 25 針及9 針串口引腳圖
串口發(fā)送的程序?qū)懺趗art_x 模塊中。在主程序模塊中首先調(diào)用gen_divd 模塊,在50M 主時鐘的基礎(chǔ)上分頻出115 200 bps 的時鐘作為串口數(shù)據(jù)發(fā)送的波特率。接著,調(diào)用uart_x 模塊以BCLK,Xmit cmdp,TxdBuf 為輸入,其中BCLK 為115 200 bps 的時鐘信號,作為發(fā)送數(shù)據(jù)的時鐘,Xmit cmdp 為wire 類型數(shù)據(jù),作為一個數(shù)據(jù)傳輸?shù)臉酥?,在Xmit cmdp 由高變低的下一個上升沿開始發(fā)送數(shù)據(jù),在TxdBuf 中為要發(fā)送的數(shù)據(jù),從主模塊中傳遞過來。
在uart_x模塊中定義了6位狀態(tài)機,其中TXIDLE為空閑狀態(tài),當無數(shù)據(jù)發(fā)送時處于該狀態(tài),此時無操作。TXLode為裝載數(shù)據(jù)狀態(tài),當接收到主模塊發(fā)來的Xmit cmdp 信號由0 轉(zhuǎn)到1 時,進入數(shù)據(jù)裝載狀態(tài),將主模塊發(fā)過來的需要發(fā)送的數(shù)據(jù)裝載到TxdBufTmp 寄存器中,之后轉(zhuǎn)入TXStartBit 狀態(tài)中,發(fā)送0 到數(shù)據(jù)線中,作為起始信號。接著轉(zhuǎn)入TXDataBit 狀態(tài),將TxdBufTmp 中的數(shù)據(jù)發(fā)送到數(shù)據(jù)線中,一位一位發(fā)送,低位在前,高位在后,發(fā)送完8位數(shù)據(jù)后,進入TXStopBit 狀態(tài),發(fā)送1 到數(shù)據(jù)線,作為數(shù)據(jù)幀的停止位。最后進入TXDone 狀態(tài),給TxDone 寄存器置1,表示發(fā)送完成,再進入TXIDLE 狀態(tài),等待數(shù)據(jù)幀的到來。
串口接收程序主要在uart_r 模塊中實現(xiàn)。在主模塊中首先調(diào)用gen_divd 模塊,將主頻50M 時鐘分頻得到115 200×16 bps 的時鐘信號。該信號為串口通信波特率的16倍,方便將數(shù)據(jù)線上發(fā)送過來的數(shù)據(jù)在合適的位置接收進來,避免錯亂或出現(xiàn)毛刺影響數(shù)據(jù)接收。
在uart_r 模塊中,以CLKIN 作為接收的主時鐘,該時鐘為主模塊中的115 200×16 bps 的時鐘信號,RXD 為接收數(shù)據(jù)線,串口發(fā)送過來的數(shù)據(jù)通過該輸入口進行接收。在該模塊中定義了5 位狀態(tài)機,首先IDLE 狀態(tài)是空閑狀態(tài),等待數(shù)據(jù)的到來,此時數(shù)據(jù)線為高電平,當數(shù)據(jù)線上傳來0 信號后,進入RevStartBit 狀態(tài),在該狀態(tài)中,一直判斷信號線中的數(shù)據(jù),如果在16 個脈沖內(nèi)均為低電平,則認可該信號為數(shù)據(jù)幀起始信號,如果在此段時間中數(shù)據(jù)線出現(xiàn)高電平,則轉(zhuǎn)到IDLE 狀態(tài),視為數(shù)據(jù)線上的毛刺。16個脈沖后,判定為起始信號后,進入RevDataBit 狀態(tài),對數(shù)據(jù)線上的數(shù)據(jù)進行接收。數(shù)據(jù)位定為8 bit 的數(shù)據(jù),每一bit 數(shù)據(jù)用16 個脈沖來接收,在第7 個脈沖讀取數(shù)據(jù)線上的數(shù)值,防止數(shù)據(jù)線上出現(xiàn)毛刺或抖動,接收到的數(shù)據(jù)存在RxDataBuf 寄存器中。接收完8 bit 數(shù)據(jù)后進入RevStopBit狀態(tài),將RxReady 置為1,表示接收完成,傳遞到主程序,進行相應(yīng)動作。16 個脈沖后進入RevDone 狀態(tài),將接收到的數(shù)據(jù)從RxDataBuf 寄存器傳遞給RxData 寄存器,輸出到主模塊中。
圖2 RS-232 數(shù)據(jù)幀結(jié)構(gòu)
HT7017 芯片是經(jīng)典的單相電能計量芯片,該芯片通信接口為UART 即RS-232 接口,可以將電表通過的功率信號等信息存儲在芯片的內(nèi)部寄存器中,用作電表的計量數(shù)據(jù)。該文利用FPGA 模擬該芯片的通信接口,以及芯片內(nèi)部的寄存器。以此可以模擬和監(jiān)控寫入該芯片的數(shù)據(jù),防止出現(xiàn)篡改計量芯片數(shù)據(jù)的行為。
HT7017 芯片UART 通信有一確定的命令幀規(guī)范,首先發(fā)送0x6A 作為字節(jié)幀頭,然后發(fā)送 CMD 字節(jié), CMD 字節(jié)最高位為0 則表示要進行讀操作,如果為1 則表示要進行寫操作,后面7 位數(shù)據(jù)表示要操作的數(shù)的寄存器地址。如果為讀操作,則將指定寄存器中的數(shù)據(jù)讀取出來,發(fā)送到數(shù)據(jù)線上,高位在前。發(fā)送數(shù)據(jù)一般為3 個字節(jié)的寄存器數(shù)據(jù),如果數(shù)據(jù)不足3 字節(jié),則將寄存器數(shù)據(jù)與數(shù)據(jù)幀的低位對齊,并將前面5 個字節(jié)的數(shù)據(jù)相加,拋棄進位,最后再按位取反,得到CHKSUM 字節(jié),發(fā)送出去,用來校驗前面發(fā)送的數(shù)據(jù)的正確性。如果為寫操作,則將接收到的數(shù)據(jù)進行校驗和運算,與接收到的CHKSUM 字節(jié)對比驗證,如果相同則將數(shù)據(jù)存入寄存器中并返回一個ACK,數(shù)據(jù)為0x54,否則將數(shù)據(jù)丟棄,也返回ACK,數(shù)據(jù)為0x63。HT7017 芯片UART 通信的數(shù)據(jù)幀規(guī)范流程圖如圖3 所示。
在uart_r 模塊中,主要實現(xiàn)HT7017 接收數(shù)據(jù)的時序模擬仿真。首先利用FPGA 中配置的PLL 鎖相環(huán)IP 核,將板載主時鐘50M 分頻成1.8432 MHz 的時鐘信號,該頻率為通信波特率115 200 bps 的16 倍,用來接收數(shù)據(jù)線上的信息。之后定義6 位狀態(tài)機,以此來完成數(shù)據(jù)接收的時序設(shè)計。
IDLE 狀態(tài)為空閑狀態(tài),此時數(shù)據(jù)線上一直為高電平,當檢測到數(shù)據(jù)線上有低電平時跳轉(zhuǎn)到start bit 狀態(tài)中,檢測該低電平,如果在16 個脈沖內(nèi)均為低電平,則判定為起始信號,否則認定為數(shù)據(jù)線上的毛刺。之后轉(zhuǎn)入data bit 狀態(tài),在該狀態(tài)接收8 bit 數(shù)據(jù),第一個數(shù)據(jù)如果為0x6A,則繼續(xù)接收,否則放棄本次數(shù)據(jù)通信。接收第2 個字節(jié)后,判斷第一個bit,如果為1,則進行寫操作,如果為0 則進行讀操作。寫操作就繼續(xù)接收2 個字節(jié)的寄存器數(shù)據(jù)和1 個字節(jié)的校驗和數(shù)據(jù),將校驗和數(shù)據(jù)前的數(shù)據(jù)相加,拋棄進位,再按位取反,與接收到的校驗和數(shù)據(jù)對比,如果相同則將數(shù)據(jù)存儲到在SDRAM中開辟的寄存器中,并返回0x54 表示接收完成。如果與校驗和數(shù)據(jù)不同,則放棄存儲數(shù)據(jù),且返回0x63。如果要進行讀操作,則需要調(diào)用uart_x 模塊,且需要先利用gen_divd 模塊,分頻得到115 200 bps 的波特率,根據(jù)CMD 中給出的寄存器地址,取出其中的數(shù)據(jù)信息,如果不足3 個字節(jié),則高位補0,并計算出校驗和字節(jié),發(fā)送出去,作為發(fā)送數(shù)據(jù)的驗證。
圖3 HT7017 數(shù)據(jù)幀流程圖
設(shè)計完串口的時序邏輯后,在QUARTUS中的SignalTab II 邏輯分析軟件中,進行了仿真驗證,結(jié)果如圖4 所示。該圖是通過使用串口調(diào)試助手軟件以115 200 bps 波特率發(fā)送十六進制數(shù)62 到FPGA 中,F(xiàn)PGA 上接收數(shù)據(jù)的波形,可以看出數(shù)據(jù)傳輸穩(wěn)定且準確。
圖4 串口接收時序圖
圖5 HT7017 寫入數(shù)據(jù)時序圖
HT7017 通信接口有其專門的數(shù)據(jù)幀規(guī)范,該文利用FPGA 模擬了其通信接口的設(shè)計,實現(xiàn)了數(shù)據(jù)的存取,滿足了項目的需要。圖5 為HT7017 芯片寫入數(shù)據(jù)的時序圖,首先接收到頭字節(jié)為0x6A,之后接收到CWD 字節(jié)為0x82,首位為1,表示有數(shù)據(jù)需要寫入,寫入的寄存器地址為0x02,之后接收到的數(shù)據(jù)為0x33 和0x56,計算其校驗和為0x8A,與接收的CHKSUM 一致,表明數(shù)據(jù)接收正確,可以存入相應(yīng)寄存器中。數(shù)據(jù)接收過程明確,滿足要求。
圖6 為模擬讀取HT7017 芯片中寄存器數(shù)據(jù)的時序圖,圖7 為串口調(diào)試助手中接收的數(shù)據(jù)截圖。首先利用串口調(diào)試助手發(fā)送頭字節(jié)0x6A,然后發(fā)送CWD 字節(jié)0x32,首位為0,表明要讀取數(shù)據(jù),要讀取的寄存器地址為0x02,讀出的數(shù)據(jù)為0xE1,0xD5,0x62,仿真表明數(shù)據(jù)讀取準確。
圖6 讀取HT7017 數(shù)據(jù)時序圖
圖7 串口調(diào)試助手讀取數(shù)據(jù)圖
該文提出的利用FPGA模擬RS-232串口通信的設(shè)計,運行穩(wěn)定且配置簡單,可以廣泛應(yīng)用于支持RS-232 接口的各類芯片的通信仿真,也可以解決某些開發(fā)板串口數(shù)量不足的問題。該文基于智能電表測試系統(tǒng)進行設(shè)計,利用FPGA 模擬支持RS-232 串口通信協(xié)議的存儲芯片,例如Flash 芯片、EEPROM 芯片等,可以用來監(jiān)督通過該芯片收發(fā)的數(shù)據(jù),并可以通過板載的ARM9 處理器將所得數(shù)據(jù)以Modbus 協(xié)議傳遞到上位機,進行顯示。也可以通過上位機直接修改該芯片內(nèi)的數(shù)據(jù),實現(xiàn)對智能電表的測試,防止出現(xiàn)篡改數(shù)據(jù)或偽造數(shù)據(jù)等行為,有較高的應(yīng)用價值。