【FPGA】数码管电子时钟(可设置时间和闹钟)
目錄
- 前言
- 一丶需求分析
- 1.設置時間
- 2.設置鬧鐘
- 二丶工程源碼
- 1.counter
- 2.seg_driver
- 3.key_debounce
- 4.beep
- 5.頂層模塊
- 三丶模塊原理圖
- 四丶管腳信息
- 五丶上板驗證
- 六丶源碼
前言
本次實驗內容承接上一篇文章數碼管電子時鐘,在此基礎上新增兩個功能:
1.設置時間
2.設置鬧鐘,到點響鈴
一丶需求分析
模塊:beep counter seg_driver top
其中:
1.設置時間
2.設置鬧鐘,到點響鈴
這兩個功能都整合在counter模塊,里面設置的重要信號如下所示
1.設置時間
我們需要利用開發板上的按鍵來設置時分秒HH:MM:SS
思路:
Counter:
rst_n:復位按鍵 【相當于開發板上的key1】
Key[0]:空閑狀態—電子時鐘 【相當于開發板上的key1】
Key[1]:設置時間 【相當于開發板上的key2】
Key[2]:設置鬧鐘 【相當于開發板上的key3】
按鍵切換三個狀態:
1.空閑狀態—就是一個時鐘
輸出dout_time給seg_driver模塊顯示時間
2.設置時間—設置當前的時分秒,改一下幾個計時器里面的初值
修改counter里面的6個計時器的值,暫停計時
Key[0]:切換修改的時間位,切換到哪一位,哪一位閃爍 【相當于開發板上的key2】
Key[1]:加1 【相當于開發板上的key3】
Key[2]:確定–退出 【相當于開發板上的key4】
3.設置鬧鐘—設置個條件,到幾時幾分幾秒蜂鳴器響
修改counter里面的6個計時器的值,暫停計時
Key[0]:切換修改的時間位,切換到哪一位,哪一位閃爍 【相當于開發板上的key2】
Key[1]:加1 【相當于開發板上的key3】
Key[2]:確定–退出(確定之后輸出dout_time給beep模塊作為響鈴時間) 【相當于開發板上的key4】
2.設置鬧鐘
方式與設置時間基本完全一樣,區別在設置鬧鐘的時間不給電子時鐘,電子時鐘保持設置的時間計時
二丶工程源碼
1.counter
module counter (input wire clk ,input wire rst_n ,input wire [2:0] key ,output reg [19:0] dout_time , //輸出時間 HH:MM:SSoutput wire beep_r ); //計數器 reg [25:0] cnt ; wire add_cnt; wire end_cnt; //S計時器//個位 (0~9) reg [3:0] cnt_s_bit; wire add_cnt_s_bit; wire end_cnt_s_bit;reg [3:0] set_cnt_s_bit; wire add_set_cnt_s_bit; wire end_set_cnt_s_bit;reg [3:0] clock_cnt_s_bit; wire add_clock_cnt_s_bit; wire end_clock_cnt_s_bit; //十位 (0~5) reg [2:0] cnt_s_ten; wire add_cnt_s_ten; wire end_cnt_s_ten;reg [2:0] set_cnt_s_ten; wire add_set_cnt_s_ten; wire end_set_cnt_s_ten;reg [2:0] clock_cnt_s_ten; wire add_clock_cnt_s_ten; wire end_clock_cnt_s_ten;//M計時器//個位 (0~9) reg [3:0] cnt_m_bit; wire add_cnt_m_bit; wire end_cnt_m_bit;reg [3:0] set_cnt_m_bit; wire add_set_cnt_m_bit; wire end_set_cnt_m_bit;reg [3:0] clock_cnt_m_bit; wire add_clock_cnt_m_bit; wire end_clock_cnt_m_bit; //十位 (0~5) reg [2:0] cnt_m_ten; wire add_cnt_m_ten; wire end_cnt_m_ten;reg [2:0] set_cnt_m_ten; wire add_set_cnt_m_ten; wire end_set_cnt_m_ten;reg [2:0] clock_cnt_m_ten; wire add_clock_cnt_m_ten; wire end_clock_cnt_m_ten;//H計時器//個位 (0~9) reg [3:0] cnt_h_bit; wire add_cnt_h_bit; wire end_cnt_h_bit;reg [3:0] set_cnt_h_bit; wire add_set_cnt_h_bit; wire end_set_cnt_h_bit;reg [3:0] clock_cnt_h_bit; wire add_clock_cnt_h_bit; wire end_clock_cnt_h_bit; //十位 (0~2) reg [1:0] cnt_h_ten; wire add_cnt_h_ten; wire end_cnt_h_ten;reg [1:0] set_cnt_h_ten; wire add_set_cnt_h_ten; wire end_set_cnt_h_ten;reg [1:0] clock_cnt_h_ten; wire add_clock_cnt_h_ten; wire end_clock_cnt_h_ten;reg [3:0] cnt_flag; reg [3:0] set_cnt_flag; reg [3:0] clock_cnt_flag; reg [2:0] state_c; //現態 reg [2:0] state_n; //次態 reg [5:0] select_seg; //在設置時間和設置鬧鐘的時候切換位選 wire [19:0] set_time_dout; wire [19:0] idel_dout; wire [19:0] clock_dout;parameter MAX_CNT=26'd50_000_000; //定義狀態 localparam IDEL =3'b001, //空閑狀態SET_TIME =3'b010, //設置時間SET_CLOCK=3'b100; //設置鬧鐘 //狀態轉移條件 wire idel_TO_set_time; wire idel_TO_set_clock; wire set_time_TO_idel; wire set_clock_TO_idel;//狀態機第一段--狀態轉移 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginstate_c<=IDEL;endelsestate_c<=state_n; end//狀態機第二段--組合邏輯 always @(*) begincase (state_c)IDEL: beginif (idel_TO_set_time) beginstate_n=SET_TIME;endelse if(idel_TO_set_clock) beginstate_n=SET_CLOCK;endelsestate_n=state_c;endSET_TIME: beginif (set_time_TO_idel) beginstate_n=IDEL;endelsestate_n=state_c;endSET_CLOCK: beginif (set_clock_TO_idel) beginstate_n=IDEL;endelsestate_n=state_c;enddefault :state_n=IDEL;endcase end assign idel_TO_set_time=state_c==IDEL&&key[0]; assign idel_TO_set_clock=state_c==IDEL&&key[1]; assign set_time_TO_idel=state_c==SET_TIME&&key[2]; assign set_clock_TO_idel=state_c==SET_CLOCK&&key[2];//select_seg always @(posedge clk or negedge rst_n) beginif(!rst_n) beginselect_seg<=6'b000_000;endelse if(idel_TO_set_time||idel_TO_set_clock) beginselect_seg<=6'b000_001;endelse if((state_c==SET_TIME||state_c==SET_CLOCK)&&(key[0])) beginselect_seg<={select_seg[4:0],select_seg[5]};end end //clock_cnt_s_bit clock_cnt_s_ten clock_cnt_m_bit clock_cnt_m_ten clock_cnt_h_bit clock_cnt_h_ten//秒計數器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginclock_cnt_s_bit<=0;endelse if (add_clock_cnt_s_bit) beginif (end_clock_cnt_s_bit) beginclock_cnt_s_bit<=0;endelseclock_cnt_s_bit<=clock_cnt_s_bit+1;endendassign add_clock_cnt_s_bit=state_c==SET_CLOCK&&select_seg==6'b000_001&&key[1]; assign end_clock_cnt_s_bit=add_clock_cnt_s_bit&&clock_cnt_s_bit==9||idel_TO_set_clock;//秒計數器---十位(0~5) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginclock_cnt_s_ten<=0;endelse if (add_clock_cnt_s_ten) beginif (end_clock_cnt_s_ten) beginclock_cnt_s_ten<=0;endelseclock_cnt_s_ten<=clock_cnt_s_ten+1;endendassign add_clock_cnt_s_ten=state_c==SET_CLOCK&&select_seg==6'b000_010&&key[1]; assign end_clock_cnt_s_ten=add_clock_cnt_s_ten&&clock_cnt_s_ten==5||idel_TO_set_clock;//分計數器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginclock_cnt_m_bit<=0;endelse if (add_clock_cnt_m_bit) beginif (end_clock_cnt_m_bit) beginclock_cnt_m_bit<=0;endelseclock_cnt_m_bit<=clock_cnt_m_bit+1;endendassign add_clock_cnt_m_bit=state_c==SET_CLOCK&&select_seg==6'b000_100&&key[1]; assign end_clock_cnt_m_bit=add_clock_cnt_m_bit&&clock_cnt_m_bit==9||idel_TO_set_clock;//分計數器---十位(0~5) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginclock_cnt_m_ten<=0;endelse if (add_clock_cnt_m_ten) beginif (end_clock_cnt_m_ten) beginclock_cnt_m_ten<=0;endelseclock_cnt_m_ten<=clock_cnt_m_ten+1;endendassign add_clock_cnt_m_ten=state_c==SET_CLOCK&&select_seg==6'b001_000&&key[1]; assign end_clock_cnt_m_ten=add_clock_cnt_m_ten&&clock_cnt_m_ten==5||idel_TO_set_clock;//時計數器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginclock_cnt_h_bit<=0;endelse if (add_clock_cnt_h_bit) beginif (end_clock_cnt_h_bit) beginclock_cnt_h_bit<=0;endelseclock_cnt_h_bit<=clock_cnt_h_bit+1;endendassign add_clock_cnt_h_bit=state_c==SET_CLOCK&&select_seg==6'b010_000&&key[1]; assign end_clock_cnt_h_bit=add_clock_cnt_h_bit&&clock_cnt_h_bit==clock_cnt_flag||idel_TO_set_clock;//時計數器---十位(0~2) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginclock_cnt_h_ten<=0;endelse if (add_clock_cnt_h_ten) beginif (end_clock_cnt_h_ten) beginclock_cnt_h_ten<=0;endelseclock_cnt_h_ten<=clock_cnt_h_ten+1;endendassign add_clock_cnt_h_ten=state_c==SET_CLOCK&&select_seg==6'b100_000&&key[1]; assign end_clock_cnt_h_ten=add_clock_cnt_h_ten&&clock_cnt_h_ten==2||idel_TO_set_clock;//判斷小時計時器十位是否記到 2 always @(*) beginif (clock_cnt_h_ten==2) beginclock_cnt_flag=4'd3;endelseclock_cnt_flag=4'd9; endassign clock_dout={clock_cnt_h_ten,clock_cnt_h_bit,clock_cnt_m_ten,clock_cnt_m_bit,clock_cnt_s_ten,clock_cnt_s_bit};/// /////set_cnt_s_bit set_cnt_s_ten set_cnt_m_bit set_cnt_m_ten set_cnt_h_bit set_cnt_h_ten//秒計數器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginset_cnt_s_bit<=0;endelse if (add_set_cnt_s_bit) beginif (end_set_cnt_s_bit) beginset_cnt_s_bit<=0;endelseset_cnt_s_bit<=set_cnt_s_bit+1;endendassign add_set_cnt_s_bit=state_c==SET_TIME&&select_seg==6'b000_001&&key[1]; assign end_set_cnt_s_bit=add_set_cnt_s_bit&&set_cnt_s_bit==9||idel_TO_set_time;//秒計數器---十位(0~5) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginset_cnt_s_ten<=0;endelse if (add_set_cnt_s_ten) beginif (end_set_cnt_s_ten) beginset_cnt_s_ten<=0;endelseset_cnt_s_ten<=set_cnt_s_ten+1;endendassign add_set_cnt_s_ten=state_c==SET_TIME&&select_seg==6'b000_010&&key[1]; assign end_set_cnt_s_ten=add_set_cnt_s_ten&&set_cnt_s_ten==5||idel_TO_set_time;//分計數器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginset_cnt_m_bit<=0;endelse if (add_set_cnt_m_bit) beginif (end_set_cnt_m_bit) beginset_cnt_m_bit<=0;endelseset_cnt_m_bit<=set_cnt_m_bit+1;endendassign add_set_cnt_m_bit=state_c==SET_TIME&&select_seg==6'b000_100&&key[1]; assign end_set_cnt_m_bit=add_set_cnt_m_bit&&set_cnt_m_bit==9||idel_TO_set_time;//分計數器---十位(0~5) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginset_cnt_m_ten<=0;endelse if (add_set_cnt_m_ten) beginif (end_set_cnt_m_ten) beginset_cnt_m_ten<=0;endelseset_cnt_m_ten<=set_cnt_m_ten+1;endendassign add_set_cnt_m_ten=state_c==SET_TIME&&select_seg==6'b001_000&&key[1]; assign end_set_cnt_m_ten=add_set_cnt_m_ten&&set_cnt_m_ten==5||idel_TO_set_time;//時計數器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginset_cnt_h_bit<=0;endelse if (add_set_cnt_h_bit) beginif (end_set_cnt_h_bit) beginset_cnt_h_bit<=0;endelseset_cnt_h_bit<=set_cnt_h_bit+1;endendassign add_set_cnt_h_bit=state_c==SET_TIME&&select_seg==6'b010_000&&key[1]; assign end_set_cnt_h_bit=add_set_cnt_h_bit&&set_cnt_h_bit==set_cnt_flag||idel_TO_set_time;//時計數器---十位(0~2) always @(posedge clk or negedge rst_n) beginif (!rst_n) beginset_cnt_h_ten<=0;endelse if (add_set_cnt_h_ten) beginif (end_set_cnt_h_ten) beginset_cnt_h_ten<=0;endelseset_cnt_h_ten<=set_cnt_h_ten+1;endendassign add_set_cnt_h_ten=state_c==SET_TIME&&select_seg==6'b100_000&&key[1]; assign end_set_cnt_h_ten=add_set_cnt_h_ten&&set_cnt_h_ten==2||idel_TO_set_time;//判斷小時計時器十位是否記到 2 always @(*) beginif (set_cnt_h_ten==2) beginset_cnt_flag=4'd3;endelseset_cnt_flag=4'd9; endassign set_time_dout={set_cnt_h_ten,set_cnt_h_bit,set_cnt_m_ten,set_cnt_m_bit,set_cnt_s_ten,set_cnt_s_bit}; /// /////計數器 always @(posedge clk or negedge rst_n) beginif(!rst_n) begincnt<=0;endelse if (add_cnt) beginif (end_cnt) begincnt<=0;endelsecnt<=cnt+1;end endassign add_cnt=state_c==IDEL||state_c==SET_CLOCK; assign end_cnt=add_cnt&&(cnt==MAX_CNT-1||set_time_TO_idel);//秒計時器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_s_bit<=1;endelse if(set_time_TO_idel) begincnt_s_bit<=set_cnt_s_bit; //在設置時間確定之后將設置的值賦給計時器endelse if (add_cnt_s_bit) beginif (end_cnt_s_bit) begincnt_s_bit<=0;endelsecnt_s_bit<=cnt_s_bit+1;endendassign add_cnt_s_bit=end_cnt; assign end_cnt_s_bit=add_cnt_s_bit&&cnt_s_bit==9;//秒計時器---十位(0~5) always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_s_ten<=0;endelse if(set_time_TO_idel) begincnt_s_ten<=set_cnt_s_ten;endelse if (add_cnt_s_ten) beginif (end_cnt_s_ten) begincnt_s_ten<=0;endelsecnt_s_ten<=cnt_s_ten+1;endendassign add_cnt_s_ten=end_cnt_s_bit; assign end_cnt_s_ten=add_cnt_s_ten&&cnt_s_ten==5;//分計時器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_m_bit<=0;endelse if(set_time_TO_idel) begincnt_m_bit<=set_cnt_m_bit;endelse if (add_cnt_m_bit) beginif (end_cnt_m_bit) begincnt_m_bit<=0;endelsecnt_m_bit<=cnt_m_bit+1;endendassign add_cnt_m_bit=end_cnt_s_ten; assign end_cnt_m_bit=add_cnt_m_bit&&cnt_m_bit==9;//分計時器---十位(0~5) always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_m_ten<=0;endelse if(set_time_TO_idel) begincnt_m_ten<=set_cnt_m_ten;endelse if (add_cnt_m_ten) beginif (end_cnt_m_ten) begincnt_m_ten<=0;endelsecnt_m_ten<=cnt_m_ten+1;endendassign add_cnt_m_ten=end_cnt_m_bit; assign end_cnt_m_ten=add_cnt_m_ten&&cnt_m_ten==5;//時計時器---個位(0~9) always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_h_bit<=0;endelse if(set_time_TO_idel) begincnt_h_bit<=set_cnt_h_bit;endelse if (add_cnt_h_bit) beginif (end_cnt_h_bit) begincnt_h_bit<=0;endelsecnt_h_bit<=cnt_h_bit+1;endendassign add_cnt_h_bit=end_cnt_m_ten; assign end_cnt_h_bit=add_cnt_h_bit&&cnt_h_bit==cnt_flag;//時計時器---十位(0~2) always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt_h_ten<=0;endelse if(set_time_TO_idel) begincnt_h_ten<=set_cnt_h_ten;endelse if (add_cnt_h_ten) beginif (end_cnt_h_ten) begincnt_h_ten<=0;endelsecnt_h_ten<=cnt_h_ten+1;endendassign add_cnt_h_ten=end_cnt_h_bit; assign end_cnt_h_ten=add_cnt_h_ten&&cnt_h_ten==2;//判斷小時計時器十位是否記到 2 always @(*) beginif (cnt_h_ten==2) begincnt_flag=4'd3;endelsecnt_flag=4'd9; endassign idel_dout={cnt_h_ten,cnt_h_bit,cnt_m_ten,cnt_m_bit,cnt_s_ten,cnt_s_bit}; //拼接成 HH:MM:SS /// /////dout_time輸出 always @(posedge clk or negedge rst_n) beginif (!rst_n) begindout_time<=20'b0;endelse begincase (state_c)IDEL:dout_time<=idel_dout; //控制數碼管顯示對應狀態的值SET_TIME:dout_time<=set_time_dout;SET_CLOCK:dout_time<=clock_dout;default :dout_time<=IDEL; endcaseend endassign beep_r=clock_dout==idel_dout; //比較設置的鬧鐘與現在的時間,結果輸出給beep模塊,到點鬧鈴 endmodule //counter2.seg_driver
module seg_driver (input wire clk,input wire rst_n,input wire [19:0] dout_time,output reg [5:0] sel,output reg [7:0] seg ); reg [3:0] seg_flag; reg dot; //小數點 用來顯示 HH.MM.SS 這樣的格式//10ms計時器---用來切換數碼管位選,以達到輪流顯示時間的各位(肉眼可以看到動態的時間計數) reg [15:0] cnt; wire add_cnt; wire end_cnt;parameter MAX_CNT =50_000 ,ZERO =7'b100_0000,ONE =7'b111_1001,TWO =7'b010_0100,THREE =7'b011_0000,FOUR =7'b001_1001,FIVE =7'b001_0010,SIX =7'b000_0010,SEVEN =7'b111_1000,EIGHT =7'b000_0000,NINE =7'b001_0000;//計時器 always @(posedge clk or negedge rst_n) beginif(!rst_n) begincnt<=0;endelse if(add_cnt) beginif (end_cnt) begincnt<=0;endelsecnt<=cnt+1;end end assign add_cnt=1'b1; assign end_cnt=add_cnt&&cnt==MAX_CNT-1;//切換數碼管位選 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsel<=6'b111_110;endelse if(cnt==MAX_CNT-1) beginsel<={sel[4:0],sel[5]};end end //切換數碼管段選 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginseg_flag<=0;endelse begincase (sel)6'b111_110: begin seg_flag<=dout_time[19:18]; dot<=1'b1;end //小時 十位6'b111_101: begin seg_flag<=dout_time[17:14]; dot<=1'b0;end //小時 個位6'b111_011: begin seg_flag<=dout_time[13:11]; dot<=1'b1;end //分鐘 十位6'b110_111: begin seg_flag<=dout_time[10:7]; dot<=1'b0;end //分鐘 個位6'b101_111: begin seg_flag<=dout_time[6:4]; dot<=1'b1;end //秒 十位6'b011_111: begin seg_flag<=dout_time[3:0]; dot<=1'b1;end //秒 個位default :seg_flag<=0;endcaseend end//段選譯碼 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginseg<=8'b1111_1111;endelse begincase (seg_flag) 0: seg<={dot,ZERO} ;1: seg<={dot,ONE} ;2: seg<={dot,TWO} ;3: seg<={dot,THREE} ;4: seg<={dot,FOUR} ;5: seg<={dot,FIVE} ;6: seg<={dot,SIX} ;7: seg<={dot,SEVEN} ;8: seg<={dot,EIGHT} ;9: seg<={dot,NINE} ;default: seg<=8'b1111_1111;endcaseend endendmodule //seg_driver3.key_debounce
module key_debounce ( input wire clk, //系統時鐘 50MHzinput wire rst_n, //復位信號input wire key, //按鍵輸入信號output reg key_done //消抖之后的按鍵信號 );reg key_r0; //同步信號(濾波作用,濾除小于一個周期的抖動) reg key_r1; //打拍 reg flag; //標志位 wire nedge; //下降沿檢測(檢測到下降沿代表開始抖動)//計時器定義 reg [19:0] cnt; wire add_cnt; //計時器開啟 wire end_cnt; //計時記滿parameter MAX_CNT=20'd1_000_000; //20ms延時//同步 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_r0<=1'b1;endelsekey_r0<=key; end//打拍 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_r1<=1'b1; endelsekey_r1<=key_r0; endassign nedge = ~key_r0 & key_r1; //檢測到下降沿拉高//標志位 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag<=1'b0; endelse if (nedge) beginflag<=1'b1; endelse if (end_cnt) beginflag<=1'b0;end end//延時模塊 always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt<=20'b0;endelse if (add_cnt) beginif (end_cnt) begincnt<=20'b0;endelsecnt<=cnt+1;end endassign add_cnt=flag; //計時器開啟 assign end_cnt=add_cnt&&cnt==MAX_CNT-1; //計時器關閉//key_done輸出 always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_done<=1'b0; endelse if (end_cnt) begin //延時滿20ms采樣key_done<=~key_r0;endelsekey_done<=1'b0; endendmodule //key_debounce4.beep
module beep (input wire clk,input wire rst_n,input wire beep_r,output reg beep_out ); reg [25:0] cnt; wire add_cnt; wire end_cnt;parameter MAX_CNT=26'd50_000_000;//計時器 always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt<=0;endelse if(add_cnt) beginif (end_cnt) begincnt<=0;endelsecnt<=cnt+1;end end assign add_cnt=1; assign end_cnt=add_cnt&&cnt==MAX_CNT-1;always @(posedge clk or negedge rst_n) beginif (!rst_n) beginbeep_out<=1;endelse if(beep_r) beginbeep_out<=0;endelse if (end_cnt) beginbeep_out<=1;endelsebeep_out<=beep_out;endendmodule //beep5.頂層模塊
module top (input wire clk , //系統時鐘input wire rst_n , //復位信號input wire [2:0] key , //三個按鍵output wire [5:0] sel , //數碼管位選output wire [7:0] seg , //數碼管段選output wire beep_out ); wire [19:0] dout_time; wire [2:0] key_done; wire beep_r; //例化計時模塊 counter u_counter(.clk (clk) ,.rst_n (rst_n) ,.key (key_done) ,.dout_time (dout_time) , //輸出時間 HH:MM:SS.beep_r (beep_r) );//例化數碼管驅動 seg_driver u_seg_driver(.clk (clk) ,.rst_n (rst_n) ,.sel (sel) ,.seg (seg) ,.dout_time (dout_time) );//例化按鍵消抖 key_debounce key_debounce2( .clk (clk), //系統時鐘 50MHz.rst_n (rst_n), //復位信號.key (key[0]), //按鍵輸入信號.key_done (key_done[0]) //消抖之后的按鍵信號 ); key_debounce key_debounce3( .clk (clk), //系統時鐘 50MHz.rst_n (rst_n), //復位信號.key (key[1]), //按鍵輸入信號.key_done (key_done[1]) //消抖之后的按鍵信號 ); key_debounce key_debounce4( .clk (clk), //系統時鐘 50MHz.rst_n (rst_n), //復位信號.key (key[2]), //按鍵輸入信號.key_done (key_done[2]) //消抖之后的按鍵信號 );//例化鬧鐘模塊 beep u_beep(.clk (clk),.rst_n (rst_n),.beep_r (beep_r),.beep_out (beep_out) ); endmodule //top三丶模塊原理圖
四丶管腳信息
五丶上板驗證
數碼管電子時鐘(設置時間+設置鬧鐘)
六丶源碼
https://github.com/xuranww/update_digital_clock.git
總結
以上是生活随笔為你收集整理的【FPGA】数码管电子时钟(可设置时间和闹钟)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多个微服务在服务器后台启停脚本
- 下一篇: siki学院API补充的笔记