1 項(xiàng)目背景 技術(shù)交流群 :544453837 在使用教學(xué)板的串口前,需要安裝CH340的驅(qū)動(dòng)程序。下載后直接解壓安裝就可以了。 當(dāng)用USB線接上電腦和教學(xué)板,并且教學(xué)板上電后,打開電腦的“設(shè)備管理器”,將會(huì)看到如下顯示。當(dāng)出現(xiàn)該顯示時(shí),表示驅(qū)程安裝成功并且已經(jīng)被電腦正確地識(shí)別。 我們可以從“設(shè)備管理器”中查看串口號(hào),如下圖所示。圖中表示該串口號(hào)為XX。我們可以修改串口號(hào),方法是:XXXXXX。 串口:可以選擇串口號(hào),支持串口號(hào)1~4。如果連接的串口號(hào)不在此范圍,則需要從設(shè)備管理器中修改串口號(hào),詳細(xì)見本章前面的描述。 波特率:選擇串口的波特率,支持9600、19200、38400、57600、115200。該選項(xiàng)影響了每一位碼元占用的時(shí)間。 校驗(yàn)位:可選擇沒有檢驗(yàn)位、奇校驗(yàn)和偶校驗(yàn)。 數(shù)據(jù)位:可以設(shè)置數(shù)據(jù)位的位數(shù),可選擇4~8位的數(shù)據(jù)拉。 停止位:可以設(shè)置停止位的時(shí)間長度。有1位、1.5位和2位可供選擇。 打開/關(guān)閉串口:用來打開和關(guān)閉串口。打開軟件時(shí),串口默認(rèn)是關(guān)閉狀態(tài)。注意,一定要設(shè)置好參數(shù)后,才能打開串口;一定要關(guān)閉串口后,才能關(guān)掉教學(xué)板電源和撥掉USB線。 十六進(jìn)制顯示:本軟件支持ASCII顯示和十六進(jìn)制顯示。勾選后,用十六進(jìn)制顯示。例如FPGA發(fā)送8’b00110001,本軟件收到后會(huì)顯示31。如果不勾選,則是用ASCII碼顯示。下圖就是ASCII表。FPGA發(fā)送8’b00110001,即下表中十六進(jìn)制的31,它所對(duì)應(yīng)的圖形為1,所以軟件只會(huì)顯示1。假設(shè)FPGA發(fā)送的是8’h00100011,即下表中十六進(jìn)制的23,它所對(duì)應(yīng)的是圖形是#,所示軟件會(huì)顯示#。 十六進(jìn)制發(fā)送:本軟件支持ASCII發(fā)送和十六進(jìn)制發(fā)送。勾選后,用十六進(jìn)制發(fā)送。例如填寫“31”,按手動(dòng)發(fā)送,那么FPGA收到的值是8’b00110001。如果不勾選,則是用ASCII碼發(fā)送。例如填寫“31”,按下手動(dòng)發(fā)送,軟件將首先發(fā)送ASCII碼“3”所對(duì)應(yīng)的十六進(jìn)制值8’h33,再發(fā)送ASCII碼“1”所對(duì)應(yīng)的十六進(jìn)制值8’h31。也就是FPGA將收到兩個(gè)字節(jié)數(shù)據(jù):8’h33和8’h31。 2 設(shè)計(jì)目標(biāo) 上板效果圖如下圖所示 3 設(shè)計(jì)實(shí)現(xiàn)3.1 頂層信號(hào) 綜上所述,我們這個(gè)工程需要4個(gè)信號(hào),時(shí)鐘clk,復(fù)位rst_n,串口輸入信號(hào)rx_uart和輸出控制LED燈的8位信號(hào)led。 將module的名稱定義為uart。并且我們已經(jīng)知道該模塊有四個(gè)信號(hào):clk、rst_n、rx_uart和dout。為此,代碼如下: 其中clk、rst_n和rx_uart是輸入信號(hào),dout是輸出信號(hào),其中clk、rst_n、rx_uart的值是0或者1,一根線即可,dout為8位位寬的,根據(jù)這些信息,我們補(bǔ)充輸入輸出端口定義。代碼如下: 3.2 信號(hào)設(shè)計(jì) 我們先分析要實(shí)現(xiàn)的功能,led信號(hào)控制了8個(gè)LED燈的亮滅,而具體哪些燈亮哪些燈滅,是取決于串口過來的數(shù)據(jù)。那串口過來的數(shù)據(jù),是如何告知FPGA,并與led對(duì)應(yīng)起來呢?我們可以看一下串口過來的時(shí)序。 上面波形是CH340控制的信號(hào)rx_uart。如果CH340要發(fā)送一個(gè)8位數(shù)據(jù)data,它首先會(huì)將信號(hào)rx_uart變0并持續(xù)一段時(shí)間(起啟位),然后發(fā)送data[0]并持續(xù)一段時(shí)間,然后發(fā)送data[1]并持續(xù)一段時(shí)間,以此類推,發(fā)送data[7]并持續(xù)一段時(shí)間,最后CH340將rx_uart為1并持續(xù)一段時(shí)間(結(jié)束位)。這樣CH340就完成了數(shù)據(jù)的發(fā)送。 例如,CH340要發(fā)送的數(shù)據(jù)data=8’h00110001,則rx_uart的波形如下。 再考慮一下時(shí)間信息。由于波特率是9600,那么每位持續(xù)的時(shí)間是1s/9600=104166ns。將時(shí)間信息補(bǔ)上波形。 本開發(fā)板的晶振時(shí)鐘是50Mz,104166ns/20ns 約等于5208個(gè)時(shí)鐘周期。也就是說上面波形中,每個(gè)比特的持續(xù)時(shí)間約等于5208個(gè)時(shí)鐘周期。需要注意的是,5208只是一個(gè)估計(jì)的大概數(shù)字,實(shí)際情況會(huì)有偏差。同時(shí),我們還有計(jì)數(shù)這是第幾個(gè)比特,用于讓我們判斷是開始位、數(shù)據(jù)位和停止位等。 可以看出,我們需要2個(gè)計(jì)數(shù)器,1個(gè)計(jì)數(shù)器用于計(jì)算1比特的位寬長度:5208個(gè)時(shí)鐘周期,命名為cnt0;另一個(gè)用于計(jì)算有多少個(gè)比特,命名為cnt1。 很明顯cnt0每次都是數(shù)5208個(gè),但cnt0的加1條件需要仔細(xì)分析。我們很清楚cnt0的加1區(qū)域是下面的灰度地方。 目前沒有任何信號(hào)可以區(qū)分出此區(qū)域。參考至簡(jiǎn)設(shè)計(jì)法案例2的方法,設(shè)計(jì)一個(gè)信號(hào)flag_add,當(dāng)其為1表示上述灰度區(qū)域,即cnt0的加1區(qū)域。 有了flag_add,我們就很明確,cnt0的加1條件是flag_add==1,數(shù)到5208下就結(jié)束。為此,可以寫出cnt0的代碼。 中間信號(hào),trigger連到觸發(fā)器的信號(hào)輸入端D,觸發(fā)器的輸出器連的是tri_ff0。將trigger取反,與tri_ff0相與,就得到信號(hào)neg_edge,如果neg_edge=1就表示檢測(cè)到trigger的下降沿。將tri_ff0取反,與trigger相與,就得到信號(hào)pos_edge,如果pos_edge=1,就表示檢測(cè)到trigger的上升沿。 我們來講解這個(gè)原理,畫出信號(hào)的波形圖。 Tri_ff0是觸發(fā)器的輸出,因此tri_ff0的信號(hào)與trigger信號(hào)相似,只是相差一個(gè)時(shí)鐘周期。我們也可以這樣理解:每個(gè)時(shí)鐘上升沿看到的tri_ff0的值,其實(shí)就是triffer信號(hào)上一個(gè)時(shí)鐘看到的值,也就是tri_ff0是trigg 3.2.2 異步信號(hào)同步化 。 這樣,flag_add變1的條件就變成:rx_uart_ff1==0&& rx_uart_ff2==1。 Flag_add變0的條件,可以完成收完9比特?cái)?shù)據(jù)就變0,不用再計(jì)數(shù)了。所以變0條件:end_cnt1。 綜上所述,可以寫出flag_add的代碼。 設(shè)計(jì)下data信號(hào),該信號(hào)的值來自于圖中第2~第9比特的值。第2比特的值賦給data[0],第3比特的值賦給data[1],以此類推,第9比特的值賦給data[7]。 由于每一個(gè)比特都持續(xù)5208個(gè)時(shí)鐘周期,我們必須選定一個(gè)時(shí)刻,將值賦給data。 首先,不能在end_cnt0的時(shí)候賦值,如上圖的點(diǎn)。因?yàn)槲覀冞@里的5208個(gè)時(shí)鐘周期是理想、估算的數(shù)值,實(shí)際上是非常有可能有偏差的。如果我們?cè)趀nd_cnt0的時(shí)候取值,就有可能采錯(cuò)。 最保險(xiǎn)的做法是在中間點(diǎn)取值。這樣,即使有比較多的偏差,都不會(huì)影響到采樣的正確性。 綜上所述,我們?cè)赾nt0數(shù)到一半時(shí)采到當(dāng)前rx_uart的值賦給dout,其中第2比特賦給led[0],第3比特賦給led[1],以此類推,第9比特賦給led[7]。 進(jìn)一步用信號(hào)表示,可翻譯成:數(shù)到add_cnt0 && cnt0==5208/2 -1時(shí),如果cnt1==1,則將rx_uart_ff1賦給led[0]。如果cnt1==2,則將rx_uart_ff1賦給led[1],以此類推,如果cnt1==8,將rx_uart_ff1賦給led[7]。 那么直接翻譯成代碼。 上面代碼可優(yōu)化,簡(jiǎn)寫成如下: 通常我們?cè)O(shè)計(jì)時(shí),首先是想到實(shí)現(xiàn)功能,所以會(huì)先寫出前面代碼。在功能實(shí)現(xiàn)的前提下,再考慮有沒有優(yōu)化空間,從而寫出后面代碼。好代碼都是一步步優(yōu)化出來的。 注意,上面代碼,我們采集的是rx_uart_ff1而不是rx_uart信號(hào)。這是因?yàn)閞x_uart是異步信號(hào),我們只能用同步化后的信號(hào),否則會(huì)引起亞穩(wěn)態(tài)。所以只能是rx_uart_ff1。 至此,主體程序已經(jīng)完成。接下來是將module補(bǔ)充完整。 3.3 信號(hào)定義 cnt0是用always產(chǎn)生的信號(hào),因此類型為reg。cnt0計(jì)數(shù)的最大值為5208,需要用13根線表示,即位寬是13位。因此代碼如下: add_cnt0和end_cnt0都是用assign方式設(shè)計(jì)的,因此類型為wire。并且其值是0或者1,1個(gè)線表示即可。因此代碼如下: cnt1是用always產(chǎn)生的信號(hào),因此類型為reg。cnt1計(jì)數(shù)的最大值為9,需要用4根線表示,即位寬是4位。因此代碼如下: add_cnt1和end_cnt1都是用assign方式設(shè)計(jì)的,因此類型為wire。并且其值是0或者1,1根線表示即可。因此代碼如下: flag_add是用always方式設(shè)計(jì)的,因此類型為reg。并且其值是0或者1,1根線表示即可。因此代碼如下: rx_uart_ff0、rx_uart_ff1和rx_uart_ff2是用always方式設(shè)計(jì)的,因此類型為reg。并且其值是0或1,需要1根線表示即可。因此代碼如下: 4 綜合工程和上板4.1 新建工程 1.首先在d盤中創(chuàng)建名為“uart”的工程文件夾,將寫的代碼命名為“uart.v”,頂層模塊名為“uart”。 2. 然后打開Quartus ,點(diǎn)擊File下拉列表中的New Project Wzard...新建工程選項(xiàng)。 3.在出現(xiàn)的界面中直接點(diǎn)擊最下方的“Next”。 4.之后出現(xiàn)的是工程文件夾、工程名、頂層模塊名設(shè)置界面。按照之前的命名進(jìn)行填寫,第一欄選擇工程文件夾“uart”,第二欄選擇工程文件“uart.v”,最后一欄選擇頂層模塊名“uart”,然后點(diǎn)擊”Next”,再出現(xiàn)的界面選擇empty project。 6. 器件型號(hào)選擇界面。在“Device family”處選擇Cyclone E,在“Available devices”處選擇EP4CE15F23C8,然后點(diǎn)擊“Next”。 7. EDA工具界面。該頁面用默認(rèn)的就行,直接點(diǎn)擊最下方“Next”。 8.之后出現(xiàn)的界面是我們前面的設(shè)置的總結(jié),確認(rèn)沒有錯(cuò)誤后點(diǎn)擊“Finish” 4.2 綜合 1.新建工程步驟完成后,就會(huì)出現(xiàn)以下界面。在“Project Navigator”下選中要編譯的文件,點(diǎn)擊上方工具欄中“Start Compilation”編譯按鈕(藍(lán)色三角形) 2.編譯成功后會(huì)出現(xiàn)以下界面,點(diǎn)擊“OK”。 4.3 配置管腳 在菜單欄中,選中Assignments,然后選擇Pin Planner,就會(huì)彈出配置管腳的窗口。 在配置窗口最下方中的location一列,參考下表中最右兩列配置好FPGA管腳。 配置完成后,關(guān)閉Pin Planner,軟件自動(dòng)會(huì)保存管腳配置信息。 4.4 再次綜合 在菜單欄中,選中Processing,然后選擇Start Compilation,再次對(duì)整個(gè)工程進(jìn)行編譯和綜合。 出現(xiàn)上面的界面,就說明編譯綜合成功。 4.5 連接開發(fā)板 圖中,下載器接入電腦USB接口,電源接入電源,uart線連接電腦USB,然后摁下電源開關(guān),看到開發(fā)板燈亮。 4.6 上板 1.雙擊Tasks一欄中”Program Device” 2.會(huì)出現(xiàn)如下界面,點(diǎn)擊add file添加.sof文件,在右側(cè)點(diǎn)擊“Start”,會(huì)在上方的“Progress”處顯示進(jìn)度。 3.進(jìn)度條中提示成功后,即可在顯示器上觀察到相應(yīng)的現(xiàn)象。 4.7 串口調(diào)試 1,安裝串口調(diào)試工具。 2. 開發(fā)板連接完成,打開電源后,在設(shè)備管理器中查看串口名。填寫圖片摘要(選填) 3,打開串口調(diào)試助手,在串口處選擇之前查看的串口名,波特率、校驗(yàn)位、數(shù)據(jù)位、停止位根據(jù)之前給出的數(shù)據(jù)進(jìn)行填寫,發(fā)送和接收都選擇十六進(jìn)制。 4,上板成功之后,在發(fā)送數(shù)據(jù)欄輸入相應(yīng)的數(shù)據(jù)(將8個(gè)LED燈對(duì)應(yīng)的8位二進(jìn)制數(shù)轉(zhuǎn)化為十六進(jìn)制),然后發(fā)送,即可在開發(fā)板上看到相應(yīng)的現(xiàn)象。 |