天天看點

FPGA期末項目 | 數字時鐘

戳這裡下載下傳整個項目包(已上傳到CSDN資源庫)

一、實驗裝置

FPGA開發平台、計算機、其它外接器件

二、需求分析(選題的意義、功能要求等。。。這裡有點水,小夥伴們可以選擇性跳過)

選題的意義:個人認為本項目(《數字時鐘》)的選題意義有二,其一,時鐘和鬧鐘早已是老生常談的日常工具,利用課堂上所學習的知識貫通運用到現實生活中,作為操作實踐,具有一定的現實意義;其二,數字時鐘的功能設計囊括了數位管、LCD屏、開關運用、管教配置設定等知識,能夠對本學期所學的實驗知識做一個挽接,在知識的總結上也具備一定意義;

功能要求:

1.用數位管顯示時、分、秒:分為兩個界面,即時鐘界面以及鬧鐘設定界面,顯示時鐘的時分秒以及鬧鐘的時分秒,可以通過開關切換顯示,是項目的基本功能;

2.能按比例縮短時間調試:調控時鐘或鬧鐘的頻跳速度,友善示範和調試;

3.鬧鐘功能:使用者可以通過sw8切換進入鬧鐘界面,再利用sw1-3設定具體的鬧鐘時間,到點即響,同樣是項目的基本功能;

4.用LCD屏顯示日期(年月日)以及祝福語:作為時鐘,顯示年月日的功能個人覺得也是有必要的,另外關于祝福語,我們對實驗和知識的學習其實本身就是快樂的過程,生活也沒有必要每天都過得毫無色彩、千篇一律,是以懷揣着這份情懷呢,我在本項目中加了一個顯示祝福語的功能,意在表達自己的這份對科學和生活的熱愛以及學習的熱情。

三、系統架構介紹(系統結構圖,各子產品的功能及端口介紹,等)

系統結構圖如下所示:

FPGA期末項目 | 數字時鐘

系統結構圖

各子產品的功能及端口介紹:

(這裡的子產品功能和端口做簡要的介紹,詳細的用法請移步至《設計思路》部分)

1.Digital_CLK_Top(clk_50M, Reset_n, seg7,ledcom,key,beep,

LCD_ON1,LCD_BLON1,LCD_RS1,LCD_RW1,LCD_EN1,LCD_DATA1);
           

功能:頂層子產品,調用其他子子產品,統籌整個系統的功能;

端口:

clk_50M, //系統時鐘輸入

Reset_n, //系統複位輸入

seg7, //數位管顯示輸出位

ledcom, //數位管位置調控輸出位

key, //開關輸入号位,主要使用于CLKcounter_60BCD

beep, //蜂鳴器輸出信号

LCD_ON1, //LCD供電電源開關

LCD_BLON1, //LCD背景電源開關

LCD_RS1, //寄存器選擇信号

LCD_RW1, //液晶讀寫信号

LCD_EN1, //液晶時鐘信号

LCD_DATA1, //LCD的資料端口

2.lcd_ori(LCD_ON,LCD_BLON,LCD_RS,LCD_RW,LCD_EN,LCD_DATA,CLK);

功能:LCD屏顯示控制子產品,用于控制LCD屏顯示年月日以及祝福語;

LCD_ON, //LCD供電電源開關

LCD_BLON, //LCD背景電源開關

LCD_RS, //寄存器選擇信号

LCD_RW, //液晶讀寫信号

LCD_EN, //液晶時鐘信号

LCD_DATA, //LCD的資料端口

CLK, //子產品時鐘輸入(項目中輸入的是clk_50M)

3.seg_display(clk,rst_n,mimute_cnt,second_cnt,hour_cnt,ledcom,seg7);

功能:基于視覺暫留知識,控制時鐘界面數位管的顯示;

clk, //子產品時鐘輸入

rst_n, //複位信号輸入

mimute_cnt, //分鐘位資料輸入

second_cnt, //秒位資料輸入

hour_cnt, //時位資料輸入

4.counter_60BCD(clk, rst, couter_o,flag);

功能:在頂層子產品調用,根據輸入的時鐘和時|分|秒位資料進行對應的加一計算和進位計算,并在溢出(分秒59加一溢出,時23加一溢出)時傳回一個flag供頂層子產品使用;

rst, //複位信号輸入

couter_o, //數字時鐘部分的時|分|秒位資料輸出

flag, //輸出一個溢出進位标志

5.clk_gen(clk_in,rst,clk_out); //clk_in=50MHz

功能:對輸入的50MHz的系統時鐘分頻,調用時根據CLK_DIV變量的複用情況進行運算并傳回對應的時鐘分頻結果;

clk_in, //子產品時鐘輸入,在頂層子產品

clk_out, //時鐘分頻結果輸出

6.CLKseg_display(clk,rst_n,mimute_cnt,second_cnt,

hour_cnt,CLKmimute_cnt,CLKsecond_cnt,CLKhour_cnt,ledcom,seg7,sw8);

功能:基于視覺暫留知識,控制鬧鐘設定界面數位管的顯示,并基于sw8的狀态控制切換數位管屏顯示;

mimute_cnt, //分鐘位資料輸入(時鐘)

second_cnt, //秒位資料輸入(時鐘)

hour_cnt, //時位資料輸入(時鐘)

CLKmimute_cnt,//分鐘位資料輸入(鬧鐘設定)

CLKsecond_cnt,//秒位資料輸入(鬧鐘設定)

CLKhour_cnt, //時位資料輸入(鬧鐘設定)

sw8 //開關8的輸入信号

7.CLKcounter_60BCD(clk, rst, couter_o,flag,sw);

功能:在頂層子產品調用,根據輸入的時鐘頻率clk和時|分|秒位資料進行對應的加一計算和進位計算,并在溢出(分秒59加一溢出,時23加一溢出)時傳回一個flag供頂層子產品使用;

couter_o, //數字鬧鐘設定部分的時|分|秒位資料輸出

sw //開關輸入位,作為key的接收變量

四、設計思路(每個子產品的設計思路,文字結合示意圖等進行介紹)

LCD_ON1,LCD_BLON1,LCD_RS1,LCD_RW1,LCD_EN1,LCD_DATA1);
           

思路:

A.複用兩次分頻子產品clk_gen,産生兩個速度不一樣的時鐘頻——clk_second和clk_second2,分别用來驅動數字時鐘和數字鬧鐘設定;

B.複用三次時鐘控制子產品counter_60BCD:

第一次,用clk_second作為時鐘頻輸入,傳入second_cnt給couter_o作為秒位資料承載,MODULEofCNT設定為60,子產品每溢出一次(即每計數到60個秒),産生一個flag,即flag_min;

第二次,用flag_min作為時鐘頻輸入,傳入minute_cnt給couter_o作為秒位資料承載,MODULEofCNT設定為60,子產品每溢出一次(即每計數到60個分),産生一個flag,即flag_hour;

第三次,用flag_hour作為時鐘頻輸入,傳入hour_cnt給couter_o作為秒位資料承載,MODULEofCNT設定為24,子產品每計數到24個時溢出一次;

C.複用三次鬧鐘控制子產品CLKcounter_60BCD:

第一次,用clk_second2作為時鐘頻輸入,傳入CLKsecond_cnt給couter_o作為秒位資料承載,MODULEofCNT設定為60,sw位傳入key[2]信号,即sw3的狀态信号;

第二次,用clk_second2作為時鐘頻輸入,傳入CLKminute_cnt給couter_o作為秒位資料承載,MODULEofCNT設定為60,sw位傳入key[1]信号,即sw2的狀态信号;

第三次, 用clk_second2作為時鐘頻輸入,傳入CLKhour_cnt給couter_o作為秒位資料承載,MODULEofCNT設定為24,sw位傳入key[0]信号,即sw1的狀态信号;

D.複用LCD屏控制顯示子產品lcd_ori,根據本函數定義的變量複用對應的參數;

E.複用鬧鐘數位管控制顯示子產品CLKseg_display,根據本函數定義的變量複用對應的參數;

F.接下來,編寫了一個狀态機,主要設定并使用了state0、state1、state2等三個狀态;

state0狀态:使用if判斷語句

if(second_cnt==CLKsecond_cnt&&minute_cnt==CLKminute_cnt&&hour_cnt==CLKhour_cnt)

等一個在鬧鐘界面子產品設定的時分秒數列,等到這個數列的時候轉跳到state1或state2,并設定好蜂鳴器鳴響的延時時間到變量cnt_2;

state1、state2:在計數變量cnt_2歸零之前,一直給蜂鳴器管腳輸出高電平,直到計數變量cnt_2歸零,輸出為低電平,停止蜂鳴器鳴響;

A.将年月日以及祝福語分别編寫成字元串,再分别付給變量lcd_buf_first、data_first和lcd_buf_second、data_second;

B.準備好狀态參數常量——

clear_lcd、

set_disp_mode、

disp_on、

shift_down、

write_data_first、

write_data_second;

基于狀态機思想,并用current_state變量承載狀态常量;

C.初始化LCD子產品;

D.clear_lcd狀态, 清屏并光标複位 ;

set_disp_mode: 設定顯示模式:8位2行5x8點陣;

disp_on: 顯示器開、光标不顯示、光标不允許閃爍 ;

shift_down: 文字不動,光标自動右移;data_first指派給lcd_buf_first;

write_data_first、write_data_second: 用于寫入資料

default: 若current_state為其他值,則将current_state置為clear_lcd;

A.複用分頻子產品clk_gen分頻出一個時鐘clk_div,周期約為0.1s;

B.設定一個8位的變量cnt,基于clk_div進行遞加一,并在0到滿位溢出之間循環(滿位溢出時将之歸零,再繼續加一處理);

C.基于快速遞加一的變量cnt,在每個clk時鐘上升沿來的是時候,取其低三位(八個數位管格位,剛好三位二進制數可以完整表示)進行case處理,

每個case的子狀态中,根據cnt低三位的值,把對應的表示數位管位置的二進制數指派給ledcom,用于選擇數位管格位;再把對應的資料(如秒位資料的低四位second_cnt[3:0],高四位second_cnt[7:4]等)傳給dis變量; dis的用法是在下一個always子產品裡面,case判斷dis的值,根據dis的值把對應的二進制數傳給seg7變量,用于基于ledcom選擇數位管格位之後,顯示格位裡面的内容;

由此,基于快速跳變的clk時鐘和clk_div時鐘,ledcom的值也不斷地快速變換,由此數位管的每個格位都在被快速地選擇和顯示,于是這樣便是通過了視覺暫留效應,實作了數位管時鐘的顯示;

A.将MODULEofCNT(分别通過/10和%10運算)切成5/2和9/3兩個數,并分别付給變量a和b;

B.通過a和b判斷是對分秒位資料(MODULEofCNT為60)還是對時位資料(MODULEofCNT為24)進行計算;

若是分秒位資料:先對couter_o[7:4]進行判斷,若小于5,則對couter_o[3:0]判斷,若couter_o[3:0]小于9,則couter_o[3:0]資料加一,若couter_o[3:0]不小于于9,則couter_o[3:0]歸零處理,couter_o[7:4]加一;若couter_o[7:4]不小于5,則對couter_o[3:0]判斷,若couter_o[3:0]小于a(9),則couter_o[3:0]資料加一,若couter_o[3:0]不小于于a(9),則couter_o八個位都歸零,并傳回一個溢出進位flag(flag<=1);

若是時位資料:邏輯同上,隻将b替換為2,将a替換為3進行處理即可;

思路:簡單地基于系統時鐘clk_in以及可複用的參數CLK_DIV實作分頻的功能;

B.(基于sw8的狀态控制切換數位管屏顯示)If語句判斷sw8時候為高電平,如果是,則将CLKsecond_cnt、CLKmimute_cnt、CLKhour_cnt系列資料付給dis變量,如果不是則将second_cnt系統資料付給dis變量;細節處如cnt、ledcom、dis、case(cnt[2:0])等用法則跟seg_display子產品的設計思路相同;

思路:同counter_60BCD子產品的設計思路;

五、實驗結果

1.開機狀态,初始為數字時鐘界面,下圖為數位管上規則地顯示閃動的時鐘,通過分頻子產品的參數調改可以改變其速度;

LCD屏上顯示具體的日期(年月日)以及祝福語(Wish you happy/happiness——祝你幸福),開關狀态為全數低電平:

FPGA期末項目 | 數字時鐘

2.上推sw8,令之輸出為高電平,數位管即切換到鬧鐘設定界面:

FPGA期末項目 | 數字時鐘

3.上推sw1,令之輸出為高電平,數位管鬧鐘界面上“時”數位持續加一(圖中已加到06):

FPGA期末項目 | 數字時鐘

4.上推sw2,令之輸出為高電平,數位管鬧鐘界面上“分”數位持續加一(圖中已加到04):

FPGA期末項目 | 數字時鐘

5.上推sw3,令之輸出為高電平,數位管鬧鐘界面上“秒”數位持續加一(圖中已加到05):

FPGA期末項目 | 數字時鐘

6.數位管停留在設定鬧鐘界面的時候,數字時鐘一直也在背景跑動,當我們設定完鬧鐘,将開關全數歸為低電平時,數位管界面回切到數字時鐘界面,數字時鐘上的時間到達鬧鐘設計的點時,會啟動蜂鳴器,産生一個時長為三秒(可以在程式中設定時長)的鳴響作為鬧鐘。

六、實驗項目代碼清單

1.Digital_CLK_Top.v

頂層檔案,用于調用諸多要使用的子產品;

2.Tcl_2c35_script1.tcl

管教配置設定的腳本檔案,描述管教的配置設定;

3.lcd_ori.v

LCD屏子產品,實作LCD屏顯示年月日以及祝福語的功能;

4.seg_ex.v

5.seg_display.v

時鐘子產品的數位管顯示的相關子產品檔案;

6.counter_60BCD.v

關于實作時鐘界面顯示的背景數字計算(相關變量的加一和進位操作等)的檔案;

7.clk_gen.v

時鐘分頻子產品,用于實作各種參數頻率的分頻;

8.CLKseg_display.v

鬧鐘子產品的數位管管顯示的相關子產品檔案;

9.CLKcounter_60BCD.v

關于實作鬧鐘界面顯示的背景數字計算(相關變量的加一和進位操作等)的檔案。

繼續閱讀