目录

  • 前言
  • 一丶需求分析
    • 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 //counter

2.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_driver

3.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_debounce

4.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 //beep

5.顶层模块

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】数码管电子时钟(可设置时间和闹钟)相关推荐

  1. 【FPGA】数码管电子时钟

    目录 一丶数码管介绍 二丶任务描述 三丶系统框图 四丶模块调用 五丶模块原理图 六丶工程源码 1.计数器模块 2.数码管驱动模块 3.顶层模块 七丶仿真测试 1.TestBench 2.仿真结果 八丶 ...

  2. python数码时钟代码_用python写一个程序,以电子时钟格式打印时间,每隔一秒刷新一次...

    1. 写一个程序,以电子时钟格式打印时间: 时间格式为: HH:MM:SS 时间每隔一秒刷新一次 代码如下 import time def showtime(): s = time.localtime ...

  3. 十分详细的数码管电子时钟(基于51单片机)

    数码管由于内部由多段LED灯构成,也被称为多段式LED数码管. 从数码管里面包含的LED个数来分,可以分为七段式.八段式.十四段式等. 七段式数码管: 八段式数码管(比七段式右下角多了一个小点): 十 ...

  4. 4位数码管中间的冒号c语言,单片机4位数码管电子时钟(带闹钟,冒号为秒闪烁)...

    经过几天的努力,第一个51单片机电子时钟终于出炉了,通过4位数码管来显示时间,系统晶振11.0592MHZ,仿真图中用二极管代替时钟冒号闪烁,非门代替三极管,让仿真速度与真实速度达到一致,本设计用了6 ...

  5. 6位数码管电子时钟c语言程序,51单片机的六位数码管时钟表仿真及C程序

    本帖最后由 liuda 于 2015-1-21 22:38 编辑 Proteus仿真截图 /****************************************************** ...

  6. android 手动设置时间 过期闹钟被触发

    最近在做闹钟的一个小程序,发现了一个问题.这个问题在网上都没有找到合适的答案,最后还是在闹钟的源码里面找到答案的. 相信很多人都和我一样,都遇到了这样的问题. 当你设置好闹钟以后,闹钟会准时触发,然后 ...

  7. 51单片机学习2——DS1302制作简易数码管电子时钟

    目录 一.硬件电路 二.DS1302 1.DS1302概述 2.ds1302控制寄存器 3.DS1302时序图 (1)读字节程序: (2)写字节程序 (3)初始化程序 (4)转换时间程序 三.数码管 ...

  8. c51时钟数码管显示流程图_基于51单片机的8位数码管电子时钟仿真图及源代码详细资料概述...

    描述 利用8位数码管显示时间,原理与4位数码管显示的基本一样 仿真图: 程序源代码: 本程序已经通过在线软件仿真和硬件制作. org 0000h ;程序开始入口地址 sjmp main ;跳转至主程序 ...

  9. 基于51的数码管电子时钟(显示时、分、秒)——定时器

    视频效果: 基于51单片机的数码管时钟设计 Proteus 仿真电路图: C51代码: #include<reg51.h>typedef unsigned char uchar; type ...

最新文章

  1. Java编码技巧之高效代码50例
  2. Weblogic 10.3.6 for linux 集群安装
  3. php的$_FILES如何生成以及如何与上传文件对象产生联系
  4. zabbix 3.2.1 升级3.4.1
  5. mysql删除端口配置文件,linux中的Mysql的安装、重置安装密码、修改权限详解
  6. ZOJ-3494 BCD Code (ac自动机+数位dp)
  7. [转载] Python学习笔记——运维和Shell
  8. 搭配购买(信息学奥赛一本通-T1387)
  9. ios整理(六)关于用富文本在tableview的cell去加载html字符串的优化方案
  10. java求几何周长面积_JAVA:编写求解几何图形(如三角形,矩型,圆,多边型)的周长、面积的应用程序...
  11. Shopee跨境电商开店高频问题解答
  12. C++视频教程资源链接合集
  13. 不差钱!华为,给学生开百万年薪
  14. 神舟战神换cpu教程_神舟战神能换什么cpu 神舟战神Z7可以换CPU吗
  15. orbslam 2 运行 tum 数据集中的 walking xyz 序列
  16. 塑造元宇宙未来的5项技术
  17. 数组类型的修改和去重
  18. bps、Byte、MiB、bit、bits之间的关系
  19. 163电子邮箱注册登录入口是?企业邮箱和163邮箱有什么区别?
  20. matlab 振动信号 阀值去噪,基于MATLAB的振动信号去噪研究

热门文章

  1. swing美化包的应用
  2. python笔记本电脑推荐2020_2020 年有什么好的笔记本电脑推荐?
  3. wav C语言音频切割器 非常详细、400行代码搞定!!
  4. 头歌平台Docker企业级实训 第2章 Docker进阶之镜像 镜像管理
  5. aspx 中轻松实现文件上传
  6. 智慧校园源码:带部署文档和接口文档+智慧校园小程序源码
  7. 用户登录成功后的操作
  8. 购买云数据库与云服务器总结
  9. python金融数据缺失处理_顺利迈过Tushare+python3+mySql读取金融数据的坑
  10. 固安凤凰机器人_世界500强实力布局固安 保利京津冀成功摘得固安核心地块