19.?數碼管的靜態顯示
在許多項目設計中,我們通常需要一些顯示設備來顯示我們需要的信息,可以選擇的顯示設備有很多,而數碼管是使用最多,最簡單的顯示設備之一。數碼管是一種半導體發光器件,具有響應時間短、體積小、重量輕、壽命長等優點。本章節將為大家介紹數碼管的顯示原理和驅動方式。
19.1.?理論學習
19.1.1.?數碼管簡介
數碼管是一種半導體發光器件,其基本單元是發光二極管。數碼管按段數一般分為七段數碼管和八段數碼管,八段數碼管比七段數碼管多一個發光二極管(多一個小數點顯示)。當然也還有一些其他類型的數碼管如“N”形管、“米”字管以及工業科研領域用的16段管、24段管等,在此就不詳細介紹。下面將為大家詳細介紹本次實驗使 用的八段數碼管。
圖 25?1 常見數碼管
19.1.2.?八段數碼管
八段數碼管的結構圖如圖 25?2所示。
圖 25?2 八段數碼管結構圖
由圖 25?2可以看出,八段數碼管是一個八字型數碼管,分為八段:a、b、c、d、e、f、g、dp,其中dp為小數點,每一段即為一個發光二極管,這樣的八段我們稱之為段選信號。數碼管常用的有10根管腳,每一段有一根管腳,另外兩根管腳為一個數碼管的公共端,兩根互相連接。
數碼管分為共陽極數碼管和共陰極數碼管。共陽極數碼管就是把發光二極管的正極連接在一起作為一個引腳,負極分開。相反的,共陰極數碼管就是把發光二極管的陰極連接在一起作為一個引腳,正極分開。這兩者的區別在于,公共端是連接到地還是高電平,對于共陽極數碼管需要給對應段低電平才會使其點亮,而對于共陰極數碼管則需要 給其高電平才會點亮。本次實驗使用的是共陽極數碼管,也就是說給對應段低電平才會被點亮。給不同的段點亮可顯示0~f的值,如表格 25?1所示。
表格 25?1 數碼管編碼譯碼表
二進制段碼右邊為高位左邊為低位。我們只要點亮相應的段碼,就能顯示我們需要顯示的內容。
段式數碼管工作方式有兩種:靜態顯示和動態顯示。靜態顯示的特點是每個數碼管的段選必須接一個8位數據線來顯示字形,顯示字形可一直保持,直到送入新字形碼為止。那么如果點亮6個碼管是不是需要48位數據線去分別控制每一個碼管的段選?當然這種方法也可以,但是其占用的I/O口較多,因此硬件電路比較復雜,成本較高, 很少使用。
那么如何節約資源呢?以我們本實驗使用的數碼管為例,如圖 25?3所示:
圖 25?3 六位數碼管等效電路圖
由上圖可以看到,我們將六個數碼管的段選信號連接在一起,而位選(sel)獨立控制,這樣六個數碼管接在一起就少了8×5個I/O口。這里對位選信號特別說明一下:由上圖可以看到每一個數碼管都有一個位選信號,而這個位選信號就控制著數碼管的亮滅。這樣我們就可以通過位選信號去控制 數碼管亮,而在同一時刻,位選選通的數碼管上顯示的字形是一樣的,因為我們將6個數碼管相對應的段選連在了一起,數碼管的顯示自然就相同了,數碼管的這種顯示方式即為靜態顯示。而如果要讓每個數碼管顯示的值不同,我們要用到另外一種顯示方式,即動態顯示,將在下一章節給大家介紹。本章節先講述6位共陽極數碼管的靜態顯 示,為下個章節的動態顯示做準備。
由圖 25?3可以看到,即使這樣我們控制數碼管仍然需要占用14個I/O口資源(8個段選,6個位選)。如果我想節約FPGA芯片的更多I/O口去做其它設計,那能不能使用更少的I/O口去驅動數碼管顯示呢?這當然是可以的,我們可通過74HC595芯片(位移緩存器)進行實現。
19.1.3.?74HC595簡介
74HC595是一個8位串行輸入、并行輸出的位移緩存器。其內部具有8位移位寄存器和一個存儲器,具有三態輸出功能。我們先跟據該芯片的引腳圖來為大家講解其功能,如圖 25?4所示。
圖 25?4 74HC595芯片引腳圖
其各引腳功能簡介如表格 25?2所示。
表格 25?2 74HC595引腳功能簡介
引腳名 | 引腳編號 | 引腳功能 |
---|---|---|
Q0—Q7 | 15,1—7 | 并行數據輸出 |
GND | 8 | 電源地 |
Q7S | 9 | 串行數據輸出 |
10 | 主復位(低電平有效) | |
SHCP | 11 | 移位寄存器時鐘輸入 |
STCP | 12 | 存儲寄存器時鐘輸入 |
13 | 輸出使能輸入(低電平有效) | |
DS | 14 | 串行數據輸入 |
VCC | 16 | 電源電壓 |
如表格 25?2所示,該芯片有個并行的數據輸出,同時芯片的輸入是串行數據,也就是說我們使用一個串行輸入口就可以并行輸出八個輸入的串行數據。從上一小節數碼管的講解我們知道六位八端數碼管需要14個I/O(也就是14bit)去驅動數碼管,而使用該芯片后,我們就可以將輸出的數碼管信號以串行(1bit)的方式 輸入該芯片,然后該芯片會將我們輸入的數碼管信號以并行的方式輸出。但是可以看到一片芯片只能并行輸出8位數據,而我們的六位八段數碼管是需要14位數據驅動的,這該怎么辦呢?這里我們可以使用兩片74HC595芯片進行輸出,事實上這正是74HC595的一大特點,可以進行級聯。74HC595芯片有個Q7S引腳, 該引腳的功能為串行數據輸出,我們將這個輸出接入下一片74HC595芯片的串行數據輸入端,這樣后面的數據就會在下一片74HC595芯片輸出了。應用好這個聯級功能,我們最少只需占用三個I/O口就可以控制很多片74HC595。
我們知道了數據的輸入輸出,那我們該如何控制這些數據輸入和輸出呢?我們通過74HC595芯片內部結構圖來為大家講解其控制過程,如圖 25?5所示。
圖 25?5 74HC595內部結構圖
如圖 25?5所示,是主復位,低電平時將移位寄存器的數據清零,通常接到VCC防止數據清零。SHCP為移位寄存器時鐘輸入,上升沿時將輸入的串行數據(DS端輸入)移入移位寄存器中。需要注要的是它是一個移位寄存器,也就是說當下一個脈沖(時鐘上升沿)到來時,上一個脈沖移入的數據就會往下移動一位。如果我們串行 輸入8bit數據,8bit數據輸入完之后,那么第一位輸入的數據將會移動到最后面。若我們一次輸入的數據超過8bit,那么后面的數據就會通過Q7S端口輸出,此時我們可以將該接口接到另一片74HC595芯片的串行輸入端(級聯),這樣數據就會隨著脈沖依次移位到另一片74HC595芯片上。
當串行數據移入到74HC595芯片的移位寄存器之后,我們如何控制其輸出呢?74HC595內部有一個8位存儲寄存器,該寄存器由STCP(存儲寄存器時鐘)控制,STCP上升沿時移位寄存器的數據會進入數據存儲寄存器中,通過讓(輸出使能輸入)為低即可讓存儲寄存器中的數據進行輸出。
最后我們總結一下74HC595的使用步驟:
-
首先把要傳輸的數據通過引腳DS輸入到74HC595中。
-
產生SHCP時鐘,將DS上的數據串行移入移位寄存器。
-
產生STCP時鐘,將移位寄存器里的數據送入存儲寄存器。
-
將引腳置為低電平,存儲寄存器的數據會在Q0—Q7并行輸出,同時并行輸出的數據會被鎖存起來。
輸入與輸出的關系如圖 25?6所示:
圖 25?6 串并輸出關系
如上圖所示最先輸入的數據會被移位到最后位進行輸出。通過以上理論知識的講解相信大家對數碼管以及74HC595的使用都有了大致的了解,下面我們通過實戰演練去看看具體該如何操作。
19.2.?實戰演練
19.2.1.?實驗目標
根據上一小節的理論學習,我們可以設計一個這樣的6位數碼管靜態顯示:控制六位數碼管讓其以000000、111111、222222一直到FFFFFF循環顯示。每個字符顯示0.5s后變化。
19.2.2.?硬件資源
本章節我們要使用開發板上的六位八段數碼管進行實驗,如圖 25?7所示。
圖 25?7 硬件資源
征途Pro開發板上使用的數碼管型號為FJ3661BH,以及使用了兩片74HC595芯片。原理圖如圖 25?8、圖 25?9所示。
圖 25?8 數碼管原理圖
圖 25?9 74HC595原理圖
圖 25?8的數碼管為共陽極數碼管,即段選為低電平點亮。對應的數碼管點亮原理圖為圖 25?3所示。從圖中可以看到,其位選為高電平時才能點亮對應數碼管,DIG1(sel[5])對應的是開發板上最左側數碼管,依次類推,DIG6(sel[0])對應的就是開發板上最右側數碼管。
如圖 25?9所示開發板上搭載了兩片74HC595芯片用于輸出數碼管驅動信號,其中我們接到了VCC防止數據清零,所以這兩片74HC595芯片我們只用四個IO口控制即可。我們將兩片74HC595進行級聯,一片的Q7S輸出端接到另一片的數據輸入端DS,這樣我們輸入的14位串行輸入數碼管信號的前六位就會在 第二片就行輸出。(注意:因為是移位寄存器,如果一次共輸入14位數據,那么第一位輸入的串行數據會在第二片74HC595芯片的Q5輸出)。
19.2.3.?程序設計
硬件資源介紹完畢,我們開始實驗工程的程序設計。
19.2.3.1.?整體說明
我們根據實驗任務可以先畫出我們的系統框圖,根據框圖我們可以更加明確的看到我們該如何完成這個實驗。
圖 25?10 數碼管靜態顯示系統框圖
根據框圖可以看到實驗一共分為3個模塊,下面分模塊為大家介紹。
表格 25?3 數碼管靜態顯示工程模塊簡介
模塊名稱 | 功能描述 |
---|---|
seg_static | 靜態數碼管驅動模塊 |
hc595_ctrl | 74HC595控制模塊 |
seg_595_static | 數碼管靜態顯示頂層模塊 |
19.2.3.2.?靜態數碼管驅動模塊
模塊框圖
圖 25?11 靜態數碼管驅動模塊框圖
表格 25?4 靜態數碼管驅動模塊輸入輸出信號描述
信號 | 位寬 | 類型 | 功能描述 |
---|---|---|---|
sys_clk | 1bit | Input | 50MHz晶振時鐘輸入 |
sys_rst_n | 1bit | Input | 復位信號,低電平有效 |
sel | 6bit | Output | 數碼管位選信號 |
seg | 8bit | Output | 數碼管段選信號 |
數碼管的靜態顯示驅動模塊我們只需要給其輸入時鐘、復位信號即可,此模塊是產生驅動數碼管的段選信號和位選信號。下面根據波形圖去了解位選信號和段選信號該如何輸出才能使數碼管達到我們的顯示要求。
波形圖繪制
六位數碼管靜態顯示參考波形圖,具體見圖 25?12。
圖 25?12 數碼管靜態顯示波形圖
如圖 25?12所示:
cnt_wait:根據實驗要求需要等待0.5s后顯示的字符才發生變化。所以我們需要一個0.5s的循環計數器。我們輸入的時鐘頻率是50MHz,一個時鐘周期的時間就是(1/50MHz)s,也就是20ns。所以我們計數器從0計到24_999_999即為0.5s(25000000*20ns)的時間。計到0. 5s后讓其歸0開始下一個0.5s的計數。
add_flag:當計數器計到0.5s時,我們拉高一個標志信號,讓這個標志信號去控制數碼管字符的跳轉。
num:每個數碼管顯示的字符,初始顯示為0,六個就是000000。當檢測到跳轉的標志信號為高時,讓各個數碼管顯示的字符加1。當加到4’hF時讓其歸0重新相加以此循環。
sel:數碼管的位選信號。我們是顯示六個數碼管,直接給其全點亮即可。根據原理圖可知我們需要給其位選信號高電平數碼管才會被點亮,所以給對應的位數高電平對應的數碼管就會點亮,一位表示一個數碼管。這里我們全部點亮即可。
seg:數碼管的段選信號,給其相應段碼點亮顯示num里的值即可。
本設計思路只做參考,并非唯一方法,讀者也可利用所學知識,按照自己思路進行設計。
代碼編寫
根據波形圖以及波形的的講解,詳細大家已經對模塊所有信號的邏輯關系都已經基本了解,那么代碼編寫起來就比較簡單了。模塊參考代碼,具體見代碼清單 25?1。
代碼清單 25?1 數碼管靜態顯示參考代碼(seg_static.v)
module seg_static ( input wire sys_clk , //系統時鐘,頻率50MHz input wire sys_rst_n , //復位信號,低電平有效output reg [5:0] sel , //數碼管位選信號 output reg [7:0] seg //數碼管段選信號);//////\* Parameter and Internal Signal \////////parameter defineparameter CNT_WAIT_MAX = 25'd24_999_999; //計數器最大值(0.5s)//十六進制數顯示編碼parameter SEG_0 = 8'b1100_0000, SEG_1 = 8'b1111_1001,SEG_2 = 8'b1010_0100, SEG_3 = 8'b1011_0000,SEG_4 = 8'b1001_1001, SEG_5 = 8'b1001_0010,SEG_6 = 8'b1000_0010, SEG_7 = 8'b1111_1000,SEG_8 = 8'b1000_0000, SEG_9 = 8'b1001_0000,SEG_A = 8'b1000_1000, SEG_B = 8'b1000_0011,SEG_C = 8'b1100_0110, SEG_D = 8'b1010_0001,SEG_E = 8'b1000_0110, SEG_F = 8'b1000_1110;parameter IDLE = 8'b1111_1111; //不顯示狀態//reg definereg add_flag ; //數碼管數值+1標志信號reg [24:0] cnt_wait ; //時鐘分頻計數器reg [3:0] num ; //數碼管顯示的十六進制數//////\* Main Code \////////cnt_wait:0.5秒計數always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_wait <= 25'd0;else if(cnt_wait == CNT_WAIT_MAX)cnt_wait <= 25'd0;elsecnt_wait <= cnt_wait + 1'b1;//add_flag:0.5s拉高一個標志信號always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)add_flag <= 1'b0;else if(cnt_wait == CNT_WAIT_MAX - 1)add_flag <= 1'b1;elseadd_flag <= 1'b0;//num:從 4'h0 加到 4'hf 循環always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)num <= 4'd0;else if(add_flag == 1'b1)num <= num + 1'b1;elsenum <= num;//sel:選中六個數碼管always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)sel <= 6'b000000;elsesel <= 6'b111111;//給要顯示的值編碼always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)seg <= IDLE;else case(num)4'd0: seg <= SEG_0;4'd1: seg <= SEG_1;4'd2: seg <= SEG_2;4'd3: seg <= SEG_3;4'd4: seg <= SEG_4;4'd5: seg <= SEG_5;4'd6: seg <= SEG_6;4'd7: seg <= SEG_7;4'd8: seg <= SEG_8;4'd9: seg <= SEG_9;4'd10: seg <= SEG_A;4'd11: seg <= SEG_B;4'd12: seg <= SEG_C;4'd13: seg <= SEG_D;4'd14: seg <= SEG_E;4'd15: seg <= SEG_F;default:seg <= IDLE ; //閑置狀態,不顯示endcaseendmodule |
以上代碼都是根據波形圖進行編寫的,這里就不再過多講解了。
19.2.3.3.?74HC595控制模塊
模塊框圖
圖 25?13 74HC595控制模塊框圖
表格 25?5 74HC595控制模塊框圖
信號 | 位寬 | 類型 | 功能簡介 |
---|---|---|---|
sys_clk | 1bit | Input | 系統時鐘,頻率50MHz |
sys_rst_n | 1bit | Input | 復位信號,低有效 |
sel | 6bit | Input | 數碼管位選信號 |
seg | 8bit | Input | 數碼管段選信號 |
stcp | 1bit | Output | 存儲寄存器時鐘 |
shcp | 1bit | Output | 移位寄存器時鐘 |
ds | 1bit | Output | 串行數據 |
oe | 1bit | Output | 輸出使能,低有效 |
由圖 25?13、表格 25?5所示,該模塊我們需要產生stcp、shcp、ds、oe四個信號對74HC595進行控制。其中ds(串行數據)就是輸入的數碼管位選信號和段選信號;shcp(移位寄存器時鐘),這個是ds數據進入移位寄存器的時鐘,它的頻率是有限制的,我們可以從數據手冊中看到,如圖 25?14所示:
圖 25?14 shcp、stcp時鐘頻率
由上圖可以看到shcp和stcp的最大頻率是有限制的,由原理圖可以看到我們使用的電壓是3.3v,同時溫度不同其支持的最大頻率也不同,大家可根據自己的實驗環境進行頻率的選取,本實驗我們使用系統時鐘(50MHz)四分頻得到的shcp時鐘(12.5MHz)去進行驅動,而stcp時鐘是在我們串行輸入14位數 碼管之后拉高的,其頻率遠遠小于shcp,所以這里我們只要確定shcp的頻率即可,至于oe信號我們一直讓其拉低即可。下面根據波形圖圖為大家進一步講解。
波形圖繪制
圖 25?15 74HC595控制模塊波形圖
如圖 25?15所示時鐘和復位由頂層傳來,seg(數碼管段選)和sel(數碼管位選)由數碼管驅動模塊傳來。seg數據和sel數據就是我們需要串并轉換的數據,這兩個信號的位寬加起來為14位,即我們每傳輸14位數據后需并行輸出。
cnt:分頻計數器。這里我們讓計數器在0和3之間循環計數,這樣一個循環生成一個時鐘即為四分頻時鐘。
cnt_bit:傳輸位數計數器。我們知道我們需要傳輸14bit的數據,故我們需要一個數據器對傳輸的位數進行計數,這樣我們對傳輸完成14位數據就可以用這個計數器進行判別了。如圖所示,當cnt等于3時讓cnt_bit計數器加1,讓其從0到13循環計數,每個數值代表傳輸一位數據。
data:我們將需要傳輸的數碼管信號寄存在data中,方便賦值。存儲順序是根據我們傳輸的位數順序由低到高位進行存儲的,至于數碼管各信號的傳輸順序我們在硬件部分已有所講解。
ds:串行數據輸出(對我們FPGA芯片來說其是輸出,對74HC595來說其是輸入,stcp和shcp信號也是如此)。這里我們回到原理圖 25?9,可以看到第二片的Q5引腳連到了數碼管的DIG6,也就是最右側的數碼管,而我們最右側數碼管對應的是我們位選信號的最低位,即sel[0]。所以我們第一位應傳輸 的數據為sel[0],依次類推根據原理圖傳輸相應的數據,具體的傳輸數據如波形圖所示。當一次數據傳完之后再次回到狀態0開始新一輪的數碼管信號傳輸。
shcp:移位寄存器時鐘,上升沿時將數據寫入移位寄存器中。我們在ds數據的中間狀態拉高產生上升沿,這樣可以使shcp采得的ds數據更加穩定。如波形圖所示我們在cnt=2時拉高,cnt=0時拉低,即可產生該時鐘,其頻率即為系統時鐘四分頻(12.5MHz)。
stcp:存儲寄存器時鐘。當我們14位數碼管控制信號傳輸完之后我們需要拉高一個stcp時鐘來將信號存入存儲寄存器之中。最后一個數據是在cnt_bit=13且cnt=2時傳輸的,所以我們就在下一個時鐘(cnt_bit=13且cnt=3時)將stcp拉高一個時鐘產生上升沿即可。
oe:存儲寄存器數據輸出使能信號,低電平有效,這里我們將復位信號取反的值賦給該信號即可。
本設計思路只做參考,并非唯一方法,讀者也可利用所學知識,按照自己思路進行設計。
代碼編寫
根據波形圖以及波形圖的講解,相信大家已經對模塊所有信號的邏輯關系都已經基本了解,那么代碼編寫起來就比較簡單了。模塊參考代碼,具體見代碼清單 25?2。
代碼清單 25?2 74HC595控制模塊參考代碼(hc595.v)
module hc595_ctrl ( input wire sys_clk , //系統時鐘,頻率50MHz input wire sys_rst_n , //復位信號,低有效 input wire [5:0] sel , //數碼管位選信號 input wire [7:0] seg , //數碼管段選信號output reg stcp , //數據存儲器時鐘 output reg shcp , //移位寄存器時鐘output reg ds , //串行數據輸入output wire oe //使能信號,低有效);//////\* Parameter and Internal Signal \////////reg definereg [1:0] cnt_4 ; //分頻計數器reg [3:0] cnt_bit ; //傳輸位數計數器//wire definewire [13:0] data ; //數碼管信號寄存//////\* Main Code \////////將數碼管信號寄存assign data={seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel};//將復位取反后賦值給其即可assign oe = ~sys_rst_n;//分頻計數器:0~3循環計數always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_4 <= 2'd0;else if(cnt_4 == 2'd3)cnt_4 <= 2'd0;elsecnt_4 <= cnt_4 + 1'b1;//cnt_bit:每輸入一位數據加一always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_bit <= 4'd0;else if(cnt_4 == 2'd3 && cnt_bit == 4'd13)cnt_bit <= 4'd0;else if(cnt_4 == 2'd3)cnt_bit <= cnt_bit + 1'b1;elsecnt_bit <= cnt_bit;//stcp:14個信號傳輸完成之后產生一個上升沿always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)stcp <= 1'b0;else if(cnt_bit == 4'd13 && cnt_4 == 2'd3)stcp <= 1'b1;elsestcp <= 1'b0;//shcp:產生四分頻移位時鐘always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)shcp <= 1'b0;else if(cnt_4 >= 4'd2)shcp <= 1'b1;elseshcp <= 1'b0;//ds:將寄存器里存儲的數碼管信號輸入即always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)ds <= 1'b0;else if(cnt_4 == 2'd0)ds <= data[cnt_bit];elseds <= ds;endmodule |
代碼是根據所繪制的波形圖進行講解的,前面已經波形圖有了詳細的講解,再次就不再過多的敘述了。
19.2.3.4.?頂層模塊
模塊框圖
圖 25?16 頂層模塊
頂層模塊主要是對各個子功能模塊的實例化,以及對應信號的連接,各輸入輸出如表格 25?6所示。
表格 25?6 頂層模塊輸入輸出信號描述
信號 | 位寬 | 類型 | 功能描述 |
---|---|---|---|
sys_clk | 1bit | Input | 系統時鐘,50MHz |
sys_rst_n | 1bit | Input | 復位信號,低有效 |
stcp | 1bit | Output | 存儲寄存器時鐘 |
shcp | 1bit | Output | 移位寄存器時鐘 |
ds | 1bit | Output | 串行數據 |
oe | 1bit | Output | 輸出使能,低有效 |
代碼編寫
頂層模塊代碼編寫較為容易,無需波形圖的繪制。頂層參考代碼,具體見代碼清單 25?3。
代碼清單 25?3 數碼管動態顯示頂層模塊參考代碼(seg_595_static.v)
module seg_595_static ( input wire sys_clk , //系統時鐘,頻率50MHz input wire sys_rst_n , //復位信號,低有效output wire stcp , //輸出數據存儲寄時鐘 output wire shcp , //移位寄存器的時鐘輸入 output wire ds , //串行數據輸入 output wire oe //輸出使能信號);//////\* Parameter And Internal Signal \////////wire definewire [5:0] sel;wire [7:0] seg;//////\* Instantiation \////////---------- seg_static_inst ----------seg_static seg_static_inst(.sys_clk (sys_clk ), //系統時鐘,頻率50MHz.sys_rst_n (sys_rst_n ), //復位信號,低電平有效.sel (sel ), //數碼管位選信號.seg (seg ) //數碼管段選信號);//---------- hc595_ctrl_inst ----------hc595_ctrl hc595_ctrl_inst(.sys_clk (sys_clk ), //系統時鐘,頻率50MHz.sys_rst_n (sys_rst_n), //復位信號,低有效.sel (sel ), //數碼管位選信號.seg (seg ), //數碼管段選信號.stcp (stcp ), //輸出數據存儲寄時鐘.shcp (shcp ), //移位寄存器的時鐘輸入.ds (ds ), //串行數據輸入.oe (oe ) //輸出使能信號);endmodule |
19.2.3.5.?RTL視圖
頂層模塊介紹完畢,使用Quartus II軟件對實驗工程進行編譯,工程通過編譯后查看實驗工程RTL視圖。工程RTL視圖,具體見由圖 25?17可知,實驗工程的RTL視圖與實驗整體框圖相同,各信號線均已正確連接。
圖 25?17 RTL視圖
19.2.3.6.?仿真驗證
仿真代碼編寫
編寫仿真代碼,對參考代碼進行仿真驗證。仿真參考代碼,具體見代碼清單 25?4。
代碼清單 25?4 數碼管靜態顯示仿真參考代碼(tb_seg7_static.v)
\`timescale 1ns/1ns module tb_seg_595_static();//// //\* Parameter and Internal Signal \// //////wire define wire stcp ; //輸出數據存儲寄時鐘wire shcp ; //移位寄存器的時鐘輸入wire ds ; //串行數據輸入wire oe ; //輸出使能信號//reg definereg sys_clk ;reg sys_rst_n ;//////\* Main Code \////////對sys_clk,sys_rst_n賦初始值initialbeginsys_clk = 1'b1;sys_rst_n <= 1'b0;#100sys_rst_n <= 1'b1;end//clk:產生時鐘always #10 sys_clk <= ~sys_clk;//重新定義參數值,縮短仿真時間defparam seg_595_static_inst.seg_static_inst.CNT_WAIT_MAX = 100;//////\* Instantiation \////////-------------seg_595_static_inst-------------seg_595_static seg_595_static_inst(.sys_clk (sys_clk ), //系統時鐘,頻率50MHz.sys_rst_n (sys_rst_n ), //復位信號,低電平有效.stcp (stcp ), //輸出數據存儲寄時鐘.shcp (shcp ), //移位寄存器的時鐘輸入.ds (ds ), //串行數據輸入.oe (oe ) //輸出使能信號);endmodule |
仿真波形分析
配置好仿真文件,使用ModelSim對參考代碼進行仿真。
圖 25?18 數碼管靜態驅動模塊仿真波形圖(一)
由圖 25?18可以看到數碼顯示的值(num)從0開始跳轉到了1,再跳轉到了2;同時段選信號(seg)的編碼與顯示的字符也相吻合,仿真圖與我們所畫波形圖的開頭是一致的。
圖 25?19 數碼管靜態驅動模塊仿真波形圖(二)
由圖 25?19可以看到數碼管顯示的數值從4’hf跳轉回0從頭開始顯示了,這與我們的設計和繪制的波形圖是一致的。可以滿足我們的實驗要求。
圖 25?20 74HC595控制模塊仿真波形圖
如圖 25?20所示,抓取的74HC595控制模塊的各信號時序與我們繪制的波形圖時序是一致的。
19.3.?上板調試
19.3.1.?引腳約束
仿真驗證通過后,準備上板驗證,上板驗證之前先要進行引腳約束。工程中各輸入輸出信號與開發板引腳對應關系如表格 25?7所示。
表格 25?7 引腳分配表
信號名 | 信號類型 | 對應引腳 | 備注 |
---|---|---|---|
sys_clk | input | E1 | 時鐘 |
sys_rst_n | input | M15 | 復位 |
stcp | output | K9 | 存儲寄存器時鐘 |
shcp | output | B1 | 移位寄存器時鐘 |
ds | output | R1 | 串行數據 |
oe | output | L11 | 輸出使能 |
下面進行管腳分配,管腳的分配方法在前面章節已有所講解,在此就不再過多敘述,管腳的分配如下圖 25?21所示。
圖 25?21 管腳分配
19.3.1.1.?結果驗證
管腳配置完成之后重新進行編譯,編譯完之后就可以進行下載驗證了,在下載之前首先將電源與下載線與開發板連接好,連接好之后上電,如圖 25?22所示。
圖 25?22 下載連線圖
打開下載界面后,當檢測到下載器(USB-Blaster)已連接之后,即可點擊“Add File…”添加sof文件,添加好后點擊“start”開始下載,隨后界面會顯示下載成功,如圖 25?23所示。
圖 25?23 下載成功界面
下載成功后可以看到數碼管上的數據從000000~FFFFFF之間循環顯示,說明驗證成功。
19.4.?章末總結
到這里,本章節講解完畢,通過本章節相信大家對數碼管有了初步的了解,那么對下一章節的數碼管的動態顯示將會有所幫助。