本系列將帶來FPGA的系統性學習,從最基本的數字電路基礎開始,最詳細操作步驟,最直白的言語描述,手把手的“傻瓜式”講解,讓電子、信息、通信類專業學生、初入職場小白及打算進階提升的職業開發者都可以有系統性學習的機會。
系統性的掌握技術開發以及相關要求,對個人就業以及職業發展都有著潛在的幫助,希望對大家有所幫助。后續會陸續更新 Xilinx 的 Vivado、ISE 及相關操作軟件的開發的相關內容,學習FPGA設計方法及設計思想的同時,實操結合各類操作軟件,會讓你在技術學習道路上無比的順暢,告別技術學習小BUG卡破腦殼,告別目前忽悠性的培訓誘導,真正的去學習去實戰應用。話不多說,上貨。
UART協議驅動設計
本篇實現基于叁芯智能科技的SANXIN -B01 FPGA開發板,以下為配套的教程,如有入手開發板,可以登錄官方淘寶店購買,還有配套的學習視頻。SANXIN-B01 Verilog教程-郝旭帥團隊
通用異步收發傳輸器(Universal Asynchronous Receiver / Transmitter),通常稱作UART,是一種異步收發傳輸器。它將要傳輸的資料在串行通信與并行通信之間加以轉換。作為把并行輸入信號轉成串行輸出信號的芯片,UART通常被集成于其他通訊接口的連接上。
UART是一種通用串行數據總線,用于異步通信。該總線雙向通信,可以實現全雙工傳輸和接收。在嵌入式設計中,UART用于主機與輔助設備通信,如汽車音響與外接AP之間的通信,與PC機通信包括與監控調試器和其它器件。
并行通信與串行通信
兩個芯片或者設備之間傳遞信息稱為通信。對于信息來說可能會有很多位,例如:傳輸ASCII碼(8bit)。在設計時,我們可以采取在兩個通信設備之間設計8根數據線,將8bit數據同時發送過去,對方同時接收8位數據。這種同時發送多位數據的傳輸方式,稱為并行通信。
由于某些原因,設備A和設備B之間不能設計多根數據線,只能設計一根數據線。如果此時還是需要傳輸ASCII碼,那么應該怎么辦呢?
設備A可以將ASCII碼的8位,按照一定的順序一位一位的發送到數據線上。設備B按照設備A發送的順序進行一位一位的接收,然后拼接為一個8位。這種通信方式成為串行通信。
將8位或者多位數據拆分為一位一位的發送出去的過程稱為并轉串。將一位一位接收的數據合并為8位或者多位數據的過程稱為串轉并。
對于串行通信設備來說,發送方都是在執行并轉串,接收方都是在執行串轉并。
UART設備為串行通信設備。
全雙工通信、半雙工通信和單工通信
全雙工通信是指在同一時刻信息可以進行雙向傳輸。例如:打電話,說的同時也能聽。
半雙工通信是指在同一時刻信息只能單向傳輸,雙方都可以進行發送和接收,但是不能夠同時發送和接收。例如:對講機通信。
單工通信是指在通信過程中,只能夠設備A發送,設備B接收。例如:聽收音機。
SANXIN – B01的開發板上的UART接口設備可以做到半雙工通信。
UART的通信電平標準
兩個設備之間能夠互相通信的基礎條件為電平標準相同。UART的接口標準有很多,有RS232、RS485等等。
臺式PC上一般會有一個DB9,接口標準為RS232。
此接口在各個工業板上也有很多。隨著技術的發展,PC上的DB9的接口逐漸被淘汰,換成了USB接口。
我們的開發板上選擇使用USB接口,方便大家學習,便于和PC進行通信。
FPGA芯片是無法(較為復雜)發出對應的電平標準,如:RS485、RS232、USB接口電平等。在大多數板卡設計時,都會在FPGA外圍添加電平轉換器,將FPGA的電平標準轉換為通信的電平標準。
我們的開發板上采用USB <->UART(LVCOMS/LVTTL)的電平轉換芯片CP2102。所以開發板上的供電端口不僅僅可以供電,還可以進行通信。
對于開發者來說,不用考慮線路的電平標準,只需要考慮如何發送和接收邏輯即可。
UART通信協議
雙方進行通信時,并不是每時每刻都在進行通信,大多數的通信都是突發性的。此時發送設備需要在發送有效之前需要提前通知接收設備應該要進行接收信息。有的人就會有疑問,發送方有信息就發送,沒有信息就停止;接收設備檢測有信息發送過來就接收,沒有信息就不接收;這樣的話不就可以了嗎?為什么需要提前通知有信息過來?
雙方既然能夠進行通信,中間勢必建立了通信線路。發送方有信息時,發送信息;沒有信息就停止發送。對于發送方來說,沒有任何問題。接收方的難度就比較大,在通信線路中,發送方不發送信息時,接收方也會在線路上接收到信息,由于接收方也不知道是不是發送方發送的信息,此時就會造成接收方無法判斷是信息還是噪聲。
為了解決上述的問題,我們規定了通信協議。
在UART通信協議中,我們規定:
在不通信時,發送高電平。
發送信息時,應該首先發送起始位(1bit、低電平)。可以理解為告訴接收方,應該接收信息了。
發送數據位,由于是串行通信,規定從低位開始發,最后到高位(協議規定信息位可以為4、5、6、7、8)。
校驗位(1bit)。可以采用奇校驗、偶校驗、直接發1、直接發0、不發等5種情況。
停止位(1bit、1.5bit、2bit。高電平)。
空閑位(1bit,高電平)
1bit的時間寬度為多少呢?
在UART協議中,一般常用的波特率(BAUD)為300、600、1200、2400、4800、9600、19200、38400、43000、56000、57600、115200。1秒鐘除以波特率就是1bit的時間寬度。
校驗位有什么作用?如何進行校驗?
在發送信息時,由于要經過很長的線路,中間極有可能受到干擾,導致某些信息位發生反轉,最終導致通信失敗。校驗位的作用為當接收到數據后,進行檢驗,如果檢驗不通過,視為接收數據有誤,直接丟棄即可。
在校驗時,可以選擇奇校驗和偶校驗。奇校驗是要求發送的數據位和校驗位中1的個數為奇數個;偶校驗是要求發送的數據位和校驗位中1的個數為偶數個。
發送器設計原理
發送器中加入緩沖器。即上游模塊把想要發送的數據寫入到發送器中的FIFO里,發送器的控制邏輯檢測到FIFO中有數據時,就讀出來進行發送。因為發送器發送的速率比較慢,加入FIFO后,上游模塊不用等待上一個數據發送完成就可以直接寫入后續的數據。
根據提前約定好的波特率和校驗方式,發送器的控制邏輯讀出FIFO的數據后,按照UART的協議向外發送即可。
接收器設計原理
接收器中加入緩沖器。即接收器的控制邏輯接收到信息后,發送到緩沖器中。由于有緩沖器的存在,主控制器可以不必時時刻刻檢查接收狀態,只需要一定的時間檢測緩沖器中是否有數據即可。
在接收時,起始位的低電平持續時間要超過半個周期才可以認為是開始,避免線路上干擾,引起錯誤接收。
在接收數據位、校驗位、停止位時,采用倍頻(16倍頻)采樣,使用中間的6、7、8、9、10這五次采樣值作為采樣依據,當五次全部為同一個電平時,即認為本位為此電平值;當四次相同,一次不同時,即認為本位與四次相同的電平值相同;當出現其他情況時,認為線路干擾太大,不做任何接收。
接收完成后,進行幀檢測和校驗,滿足設計要求時,將其中的數據寫入到FIFO中。
架構設計和信號說明
此模塊命名為uart_drive,共有四個模塊構成。
tx_fifo模塊:發送緩沖區256深度、寬度為8,該緩沖區設計一個高電平有效的復位。負責將上游想要發送的數據緩存起來。
tx_ctrl模塊:發送邏輯控制部分。負責將tx_fifo中的數據按照UART的協議規定發送出去。
rx_ctrl模塊:接收邏輯控制部分。負責將外部數據線上的數據按照UART協議規定解析出來,存儲到tx_fifo中。
rx_fifo模塊:接收緩沖區256深度、寬度為8,該緩沖區設計一個高電平有效的復位。負責將接收邏輯控制部分解析的數據緩存起來,等待著控制器件的讀取。
在上述表格中,所有的為端口但是不分配管腳的信號都是由上游邏輯控制給出。本次下板實驗時,也會給出上游控制模塊。
調用tx_fifo
調用tx_fifo和7.4節中方法類似,其他有幾個步驟不太一樣,下面給出具體說明。
對于很多的標志信號在設計中用不到,就不再引出。
引出清除信號(高電平有效),并使清除信號同步于讀時鐘。
調用rx_fifo
調用rx_fifo和7.4節中方法類似,其他有幾個步驟不太一樣,下面給出具體說明。
對于很多的標志信號在設計中用不到,就不再引出。
引出清除信號(高電平有效),并使清除信號同步于寫時鐘。
tx_ctrl設計實現
參數PARITY為選擇的校驗方式,1表示為奇校驗,0表示為偶校驗。
參數BAUD為選擇的波特率。
參數F_clk為參考的時鐘頻率。
參數T為需要計數多個參考時鐘周期才可以到波特率規定的時間。
設計代碼為:
tx_en為發送標志信號,當發送邏輯處于不發送狀態時,并且tx_fifo中不空,就將tx_en拉高,啟動發送邏輯。當發送完成后,拉高tx_done,將tx_en拉低。其他時間tx_en保持不變。
tx_fifo_rden為tx_fifo的讀使能信號,拉高一拍,讀出一個數據,所以每次只能拉高一拍。在tx_en為低器件,且外部tx_fifo中有數據時,拉高tx_fifo_rden。tx_fifo_rden和tx_en拉高的條件相同,故而會同步拉高,下一拍時,tx_en會變為高電平,所以此時tx_fifo_rden只會拉高一拍。
baud_cnt是為了記錄每發送1bit時間寬度的計數器。在發送使能tx_en拉高后,baud_cnt就開始不斷的計數即可。
bit_cnt為此時應該發送UART協議中哪一位的計數器,此計數器在發送使能拉高后,baud_cnt每次計數到1時,bit_cnt進行加1。由于baud_cnt為循環計數,無論在什么時刻bit_cnt加1,后續加1的時間間隔都是一個bit時間寬度。為了能夠使tx_en一旦拉高,發送邏輯能夠快速發送起始位,所以本設計中選擇1。
tx_done信號為發送完成信號,當bit_cnt等于13(起始位1bit、數據位8bit、校驗位1bit,停止位1bit和空閑位1bit,共計12bit。本設計中bit_cnt為1時,發送起始位;bit_cnt為12時,發送空閑位)時,證明所有的bit位都已經發送完成,將tx_done拉高。
在算術運算中,假設data的位寬為3,^data=data[1] ^ data[1] ^ data[0],這種運算規則稱為縮減運算符。縮減運算符還有“&”和“|”。如果data中1的個數為奇數個,那么縮減異或之后的記過為1,否則為0。當采用奇校驗時,數據位和校驗位的1個數為奇數,所以校驗位應該是~(^tx_fifo_rdata)。當采用偶校驗時,數據位和校驗位的1個數為偶數,所以校驗位應該是^tx_fifo_rdata。
rx_ctrl設計實現
參數PARITY為選擇的校驗方式,1表示為奇校驗,0表示為偶校驗。
參數BAUD為選擇的波特率。
參數F_clk為參考的時鐘頻率。
參數T為需要計數多個參考時鐘周期才可以到16倍波特率規定的時間。
由于外部uart_rxd的信號為異步信號,首先需要打兩拍。
設計代碼為:
start_cnt為記錄在沒有啟動接收時,低電平的持續時間。
當start_cnt的低電平持續時間等于8個T時(16個T為一個bit的時間寬度),認為此起始位有效,拉高rx_en。當接收完成后,rx_en拉低,其他時間,rx_en保持不變。
當rx_en拉高后,baudx16_cnt不斷開始計數,最大值為16倍頻的寬度值。
當rx_en拉高后,且baudx16_cnt為最大值時,就開始進行移位采樣。由于起始位只判斷一半,所以半個起始位、8個數據位、1個奇偶校驗位,在16倍頻采樣的情況下,一共會采樣152次。
cap_cnt為采樣的計數,當采樣到152時,且baudx16_cnt等于2時,認為采樣結束。利用baudx16_cnt等于2只是為了產生的tx_done為一個脈沖。
采樣結束后,利用函數的特性,得出8個數據位、1個校驗位,并且得出9個線路是不是出現干擾的標志rx_error。
得到最終結果后,將數據進行輸出。
產生rx_fifo_wren時,進行了線路干擾檢測判斷,停止位判斷,以及奇偶校驗判斷,當都符合預期后,輸出為1。其他情況輸出為0。
頂層設計
頂層設計只負責將上述四個模塊按照架構圖的方式進行連接。
設計代碼為:
parameter所定義的參數,在例化時,可以對它進行重新賦值,方便我們參數化設計。
綜合出來的RTL視圖如下:
RTL仿真
在仿真中,將uart_rxd和uart_txd相連接,實現自發自收。
對于tx_clk和rx_clk都采用clk連接。
仿真代碼如下:
復位結束后,采用寫入隨機數的方式,寫入了五個數據。從RTL仿真圖中可以看到這個五個數據為24、81、09、63、0d。
接收端口時刻監測rx_empty是不是為假值,一旦為假值,就證明有接收到數據,立刻拉高一拍rx_en,進行讀出。大概經過十幾毫秒后,仿真會自動停止。
從RTL仿真圖中可以看到,讀出的數據為24、81、09、63、0d這五個數據,和我們寫入的相同。
下板驗證
由于此設計外設接口眾多,并且在使用時,都是由上游控制器進行控制。本小節編寫上游控制器,實現回環測試(將接收到的數據,全部在發送出去)。
在測試時,rx_clk和tx_clk都采用系統時鐘。
本模塊命名為uart_drive_example。
test_ctrl模塊負責監控rx_empty是否為假值,一旦有數據接收到就可以讀出,發送到發送緩沖區中。
此模塊采用狀態實現。共分為WAIT_RX(等待UART接收數據),WAIT_RD(等待讀數據),SEND(發送數據)。
將rx_en置高后,rx_data需要等待一拍才會有效。
狀態轉移圖如下:
設計代碼如下:
uart_drive_example負責將test_ctrl和uart_drive聯系起來。
設計代碼如下:
將uart_drive_example設置為頂層。
在file界面,右擊uart_drive_example文件,選擇set as top level……。
進行綜合分析后,分配管腳,形成配置文件。
安裝驅動
將開發板與電腦相連接,打開設備管理器。可以看到在其他設備中出現了CP2102 USB to UART Bridge Controller,并且前面有一個黃色的感嘆號,標志著此端口還不能使用。
在我們的開發板上,使用的USB <->UART的芯片就是CP2102,所以在此需要安裝驅動。
打開04_串口驅動,安裝CP210x_windows_drivers。
文件中有兩個安裝程序。一個是CP210xVCPInstaller_x64,另外一個是CP210xVCPInstaller_x86。此時我們需要查看自己電腦的系統是多少位的,打開控制面板中的系統就可以看自己的電腦是多少位的操作系統。
64位的操作系統,安裝CP210xVCPInstaller_x64,32位的操作系統安裝CP210xVCPInstaller_x86。
雙擊對應的安裝程序后,點擊下一步。
點擊“我接受”,點擊下一步。
等待一段時間后,選擇完成即可。
此時對開發板進行斷電再上電的處理,就可以在設備管理的端口(COM和LPT)中看到安裝好的程序,并且記住后面的COM口的編號,一會兒需要使用。在此,筆者的PC上的COM口為COM3。
安裝串口助手軟件
如果電腦上有其他串口助手軟件的,也可以使用。
電腦上沒有串口助手的軟件的,可以安裝我們提供的軟件。
打開09_工具,安裝串口獵人。
雙擊串口獵人安裝程序,點擊下一步。
選擇安裝位置。點擊下一步。
點擊下一步,開始安裝。
等待一段時間后,安裝成功。點擊完成。
此軟件安裝好,并不會在桌面上形成快捷方式。可以在程序列表中找到這個軟件。
打開后,可以看到串口獵人的界面。
串口助手調試
將串口助手配置為,端口號:com3(每個人會有不同,請去設備管理器中查找),波特率:9600,校驗位:Odd(奇校驗)。
點擊啟動串行端口。
把所有的信息全部清除一下。
清除后,再發碼區,隨便兩個十六進制的數,點擊發送。
開發板中配置的是回環測試的代碼,所以發送的數據會在收嗎區顯示出來。
開發板上還有兩個LED用來指示發送接收數據。當發送或者接收數據時,對應的LED會點亮。
將發碼區和收碼區清除一下,然后都改為字符串。然后發送任意一串字符,進行測試。
我們可以設置其他的波特率或者校驗方式,進行其他測試。在此就不再敘述。
在應用時,只需要將uart_drive例化使用即可。
更多熱點文章閱讀
-
電子技術
+關注
關注
18文章
901瀏覽量
56127 -
電子發燒友論壇
+關注
關注
4文章
197瀏覽量
1113
原文標題:【教程分享】FPGA零基礎學習:UART協議驅動設計
文章出處:【微信號:gh_9b9470648b3c,微信公眾號:電子發燒友論壇】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論