实战项目——多功能电子时钟

news2024/11/29 10:31:28

一,项目要求

在这里插入图片描述

二,理论原理

通过按键来控制状态机的状态,在将状态值传送到各个模块进行驱动,在空闲状态下,数码管显示基础时钟,基础时钟是由7个计数器组合而成,当在ADJUST状态下可以调整时间,并且基础时间会随基础时钟的改变而改变,同过位置使能来确定更改的值在按下确定来更改基础时钟的时间,ALARM状态下可以设置闹钟的时间,设定方法和更改时钟方法一致,随后设置了一个beep_flag来驱动beep,当beep_flag为1且到达设定时间就响,若beep_flag不为1则停止响动,最后的秒表功能不多做赘述,之后通过状态机传出来的值,驱动数码管显示那个模块的输出值.

三,系统架构分析

本次系统架构分为:状态机模块,数码管驱动模块,基础时钟模块,调时模块,闹钟模块,秒表模块
在这里插入图片描述

三,状态转移图

在这里插入图片描述

四,源码展示

首先是状态机模块的实现,这里对应上边的状态转移图,通过传出的使能信号state来控制各个模块

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个状态机模块用来控制不同状态的转换
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module state_change( 
    input 	wire				clk		,
    input 	wire				rst_n	,
    input   wire    [3:0]       key_in  ,//按键输入
    input   wire                beep    ,
    output  reg     [1:0]       led_on  ,//led灯显示用来判断当前在什么状态
    output  reg     [1:0]       state    //状态输出
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter IDLE = 4'b0001,   //空闲状态表示显示基础时钟
          ADJUST = 4'b0010,//更改状态可以更改时钟的值
          ALARM  = 4'b0100,//闹钟状态,可以制定闹钟
          STOP   = 4'b1000;
//---------<内部信号定义>-----------------------------------------------------
reg     [3:0]   cstate;//现态
reg     [3:0]   nstate;//次态

//****************************************************************
//状态机
//****************************************************************
//三段式状态机第一段时序逻辑
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cstate <= IDLE;
    end
    else begin
        cstate <= nstate;
    end
end

//三段式状态机第二段组合逻辑
always @(*) begin
    case (cstate)
        IDLE    :begin
                    if (!key_in[0]) begin //当按键0按下时转到调时状态
                        nstate = ADJUST;
                    end
                    else if (!key_in[1]||!beep) begin
                        nstate = ALARM;
                    end
                    else if (!key_in[2]) begin
                        nstate = STOP ;
                    end
                    else begin
                        nstate = cstate; 
                    end
                end 
        ADJUST  :begin
                    if (!key_in[0]||!key_in[3]) begin//当按下按键0时转到基础时钟
                        nstate = IDLE;  
                    end
                    else if (!beep) begin//当蜂鸣器响立刻跳转到闹钟状态
                        nstate = ALARM;
                    end
                    else begin
                        nstate = cstate;
                    end
                end
        ALARM   :begin
                    if (!key_in[0]) begin//当按下按键0时转到基础时钟
                        nstate = IDLE;  
                    end
                    else begin
                        nstate = cstate;
                    end
                end
        STOP    :begin
                    if (!key_in[0]) begin
                        nstate = IDLE;
                    end
                    else if (!beep) begin//当蜂鸣器响立刻跳转到闹钟状态
                        nstate = ALARM;
                    end
                    else begin
                        nstate = cstate;
                    end
                end
        default: nstate = IDLE;
    endcase
end 

//三段式状态机第三段时序逻辑
always @(posedge clk or  negedge rst_n) begin
    if (!rst_n) begin
        state <= 2'b00;
    end
    else case (cstate)
        IDLE    : state <= 2'b00;
        ADJUST  : state <= 2'b01;
        ALARM   : state <= 2'b10;
        STOP    : state <= 2'b11;
        default: state <= 2'b00;
    endcase
end

//****************************************************************
//led显示状态,通过led的亮灭状态来看处在什么状态
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        led_on <= 2'b00;
    end
    else case (cstate)
        IDLE    : led_on <= 2'b00;
        ADJUST  : led_on <= 2'b01;
        ALARM   : led_on <= 2'b10;
        STOP    : led_on <= 2'b11;
        default: led_on <= 2'b00;
    endcase
end
endmodule

接下来是基础时钟模块,这个模块我为了后边的修改时钟模块方便所以我选择了使用七个计数器来实现。

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个基础时钟通过用标准的五个计数器实现
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module counter( 
    input 	wire				clk		,
    input 	wire				rst_n	,
    input   wire    [3:0]       key_in  ,
    input   wire    [1:0]       state   ,//状态
    input   wire    [2:0]       flag    ,//位置信号
    input   wire    [23:0]      adjust_time,     //时间调整
    output  wire    [23:0]      times       //当前时间寄存区
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter MAX1s = 26'd49_999_999;
reg			[25:0]	cnt_1s	;
wire				add_cnt	;
wire				end_cnt	;

//时钟内部参数
reg      [3:0]   sec_low    ;
reg      [3:0]   sec_high   ;
reg      [3:0]   mine_low   ;
reg      [3:0]   mine_high  ;
reg      [3:0]   hour_low   ;
reg      [3:0]   hour_high  ;
wire             add_sec_low;
wire             add_sec_high ;
wire             add_mine_low ;
wire             add_mine_high;
wire             add_hour_low ;
wire             add_hour_high;
wire             end_sec_low  ;
wire             end_sec_high ;
wire             end_mine_low ;
wire             end_mine_high;
wire             end_hour_low ;
wire             end_hour_high;
//---------<内部信号定义>-----------------------------------------------------
//****************************************************************
//1s计时器
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_1s <= 26'd0;
    end 
    else if(add_cnt&&(state != 4'b01))begin 
        if(end_cnt)begin 
            cnt_1s <= 26'd0;
        end
        else begin 
            cnt_1s <= cnt_1s + 1'b1;
        end 
    end
end 

assign add_cnt = 1;
assign end_cnt = add_cnt && cnt_1s == MAX1s;
    
//****************************************************************
//时钟计时
//****************************************************************

//****************************************************************
//秒钟计时,通过两个计数器来设定秒的个位和十位
//****************************************************************
always @(posedge clk or negedge rst_n ) begin
    if (!rst_n) begin
        sec_low <= 4'd0;
    end
    else if (add_sec_low) begin
        if (end_sec_low) begin
            sec_low <= 4'd0;
        end
        else begin
            sec_low <= sec_low + 1'd1;
        end
    end
    else if ((state == 2'b01)&&(!key_in[3])) begin
        sec_low <= adjust_time[3:0];
    end
    else begin
        sec_low <= sec_low;
    end   
end
assign add_sec_low = end_cnt&&((state != 2'b01)&&(flag != 3'd1));
assign end_sec_low = (sec_low == 4'd9)&&add_sec_low;

always @(posedge clk or negedge rst_n ) begin
    if (!rst_n) begin
        sec_high <= 4'd0;
    end
    else if (add_sec_high) begin
        if (end_sec_high) begin
            sec_high <= 4'd0;
        end
        else begin
            sec_high <= sec_high + 1'd1;
        end
    end
    else if ((state == 2'b01)&&(!key_in[3])) begin
        sec_high <= adjust_time[7:4];
    end
    else begin
        sec_high <= sec_high;
    end   
end
assign add_sec_high = end_sec_low&&(flag != 3'd2);
assign end_sec_high = (sec_high == 4'd5)&&add_sec_high;
//****************************************************************
//分钟计时器,通过两个计数器来控制分钟个位和十位
//****************************************************************
always @(posedge clk or negedge rst_n ) begin
    if (!rst_n) begin
        mine_low <= 4'd0;
    end
    else if (add_mine_low) begin
        if (end_mine_low) begin
            mine_low <= 4'd0;
        end
        else begin
            mine_low <= mine_low + 1'd1;
        end
    end
    else if ((state == 2'b01)&&(!key_in[3])) begin
        mine_low <= adjust_time[11:8];
    end
    else begin
        mine_low <= mine_low;
    end   
end
assign add_mine_low = end_sec_high&&(flag != 3'd3);
assign end_mine_low = (mine_low == 4'd9)&& add_mine_low;

always @(posedge clk or negedge rst_n ) begin
    if (!rst_n) begin
        mine_high <= 4'd0;
    end
    else if (add_mine_high) begin
        if (end_mine_high) begin
            mine_high <= 4'd0;
        end
        else begin
            mine_high <= mine_high + 1'd1;
        end
    end
    else if ((state == 2'b01)&&(!key_in[3])) begin
        mine_high <= adjust_time[15:12];
    end
    else begin
        mine_high <= mine_high;
    end   
end
assign add_mine_high = end_mine_low &&(flag != 3'd4);
assign end_mine_high = (mine_high == 4'd5)&& add_mine_high;
//****************************************************************
//小时计时器,通过两个计数器来控制小时的个位和十位
//****************************************************************
always @(posedge clk or negedge rst_n ) begin
    if (!rst_n) begin
        hour_low <= 4'd0;
    end
    else if (end_hour_high) begin
        hour_low <= 4'd0;
    end
    else if (add_hour_low) begin
        if (end_hour_low) begin
            hour_low <= 4'd0;
        end
        else begin
            hour_low <= hour_low + 1'd1;
        end
    end
    else if ((state == 2'b01)&&(!key_in[3])) begin
        hour_low <= adjust_time[19:16];
    end
    else begin
        hour_low <= hour_low;
    end   
end
assign add_hour_low = end_mine_high&&(flag != 3'd5) ;
assign end_hour_low = (hour_low == 4'd9)&& add_hour_low;

always @(posedge clk or negedge rst_n ) begin
    if (!rst_n) begin
        hour_high <= 4'd0;
    end
    else if (end_hour_high) begin
        hour_high <= 4'd0;
    end
    else if (add_hour_high) begin

        hour_high <= hour_high + 1'd1;
    end
    else if ((state == 2'b01)&&(!key_in[3])) begin
        hour_high <= adjust_time[23:20];
    end
    else begin
        hour_high <= hour_high;
    end   
end
assign add_hour_high = end_hour_low&&(flag != 3'd6);
assign end_hour_high = (hour_high == 4'd2)&&(hour_low >= 4'd4);
//拼接输出值
assign times = {hour_high , hour_low , mine_high , mine_low , sec_high , sec_low};
endmodule

接下来是修改时钟模块,这里通过定义了一个位置信号来达到选择到每一位,最后把修改的数值重新赋值给基础时钟

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个调时模块,通过位置信号和按键信号来更改
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module adjust_state( 
    input 	wire				clk		,//全局时钟
    input 	wire				rst_n	,
    input   wire    [3:0]       key_in  ,//按键输入
    input   wire    [1:0]       state   ,//状态
    input   wire    [23:0]      times   ,//基本时钟时间
    output  wire    [2:0]       flag    ,//位置信号
    output  wire    [23:0]      adjust_time//调整后时间
);								 
//---------<参数定义>--------------------------------------------------------- 
//调时参数定义
reg [2:0]   flag_r;//位置信号
//时钟参数定义
reg      [3:0]   sec_low    ;
reg      [3:0]   sec_high   ;
reg      [3:0]   mine_low   ;
reg      [3:0]   mine_high  ;
reg      [3:0]   hour_low   ;
reg      [3:0]   hour_high  ;

//---------<内部信号定义>-----------------------------------------------------

//****************************************************************
//位置信号驱动
//****************************************************************
//控制位置信号
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag_r <= 3'd0;
    end
    else if ((state == 2'b01)) begin
        if (!key_in[1]) begin
           if (flag_r == 3'd6) begin
            flag_r <= 3'd1;
        end
        else begin
            flag_r <= flag_r + 1'b1;
        end
        end
        else begin
            flag_r <= flag_r;
        end 
    end
    else begin
        flag_r <= 3'd0;
    end
end
assign  flag = flag_r;
//****************************************************************
//调时主要模块,当不在调时状态时使得值一直和时钟保持相等,在调时状态时
//根据位置信号和按键信号来加减值
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        sec_low   <= times[3:0];
        sec_high  <= times[7:4];
        mine_low  <= times[11:8];
        mine_high <= times[15:12];
        hour_low  <= times[19:16];
        hour_high <= times[23:20];
    end
    else if (state != 2'b01) begin
        sec_low   <= times[3:0];
        sec_high  <= times[7:4];
        mine_low  <= times[11:8];
        mine_high <= times[15:12];
        hour_low  <= times[19:16];
        hour_high <= times[23:20];
    end
    else if (state == 2'b01) begin
        if (flag_r == 3'd1) begin
            if (!key_in[2]) begin     //当在调时状态并且位置信号为1时按下按键2使得分钟个位加1,下放同理
                sec_low <= sec_low + 1'b1;
            end
            else if (sec_low == 4'd10) begin
                sec_low <= 4'd0;
            end
        end
        else if (flag_r == 3'd2) begin
            if (!key_in[2]) begin
                sec_high <= sec_high + 1'b1;
            end
            else if (sec_high == 4'd6) begin
                sec_high <= 4'd0;
            end
        end
        else if (flag_r == 3'd3) begin
            if (!key_in[2]) begin
                mine_low <= mine_low + 1'b1;
            end
            else if (mine_low == 4'd10) begin
                mine_low <= 4'd0;
            end
        end
        else if (flag_r == 3'd4) begin
            if (!key_in[2]) begin
                mine_high <= mine_high + 1'b1;
            end
            else if (mine_high == 4'd6) begin
                mine_high <= 4'd0;
            end
        end
        else if (flag_r == 3'd5) begin
            if (!key_in[2]) begin
                hour_low <= hour_low + 1'b1;
            end
            else if ((hour_low == 4'd10)&&(hour_high <= 4'd1)) begin
                hour_low<= 4'd0;
            end
            else if ((hour_low == 4'd4)&&(hour_high == 4'd2)) begin
                hour_low <= 4'd0;
            end
        end
        else if (flag_r == 3'd6) begin
            if (!key_in[2]) begin
                hour_high <= hour_high + 1'b1;
            end
            else if ((hour_high == 4'd2)&&(hour_low >=4'd4)) begin
                hour_high <= 4'd0;
            end
            else if ((hour_high == 4'd3)&&(hour_low < 4'd4)) begin
                hour_high <= 4'd0;
            end
        end
        else begin
            sec_low   <= sec_low  ;
            sec_high  <= sec_high ;
            mine_low  <= mine_low ;
            mine_high <= mine_high;
            hour_low  <= hour_low ;
            hour_high <= hour_high;
        end
    end
end
//调值后的信号输出
assign adjust_time = {hour_high ,hour_low,mine_high , mine_low , sec_high , sec_low} ;
endmodule

下面是对于闹钟模块的介绍,闹钟模块中定时跟修改模块一致,只是会让修改后的值一直保持,只要基础时钟时间跟定时想同就使使能拉高,按下按键或者等待5s使能自动拉低,使能拉高切时间达到就使得蜂鸣器响达到闹钟的效果

/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个闹钟模块,在调时模块的基础上,增加了蜂鸣器驱动信号,;来控制定时
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module alarm_clock( 
    input 	wire				clk		,
    input 	wire				rst_n	,
    input   wire    [3:0]       key_in  ,
    input   wire    [1:0]       state   ,//状态
    input   wire    [23:0]      times   ,//基础时钟时间
    output  reg                 beep    ,//蜂鸣器
    output  wire    [2:0]       flag_alarm,//闹钟位置信号
    output  wire    [23:0]      adjust_alarm,//设定闹钟时间
    output  wire                led_alarm    //定时led

);								 
//---------<参数定义>--------------------------------------------------------- 
parameter MAX1S = 26'd49_999_999;//1s;


//闹钟参数定义
reg [2:0]   flag_alarm_r;//位置信号
reg         flag_beep_r   ;//蜂鸣器使能
reg      [3:0]   sec_low    ;
reg      [3:0]   sec_high   ;
reg      [3:0]   mine_low   ;
reg      [3:0]   mine_high  ;
reg      [3:0]   hour_low   ;
reg      [3:0]   hour_high  ;

//1s计时器参数定义
reg			[25:0]	cnt	   	;
wire				add_cnt	;
wire				end_cnt	;
//5s计数器参数定义
reg			[2:0]	cnt_5s	   	;
wire				add_cnt_5s	;
wire				end_cnt_5s	;

reg                 led_r       ;//led信号寄存器
reg                 flag        ;//计时驱动
//---------<内部信号定义>-----------------------------------------------------


//****************************************************************
//flag驱动控制计时
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag <= 0;
    end
    else if (end_cnt_5s) begin
        flag <= 1'b0;
    end
    else if (adjust_alarm === times&&times!= 0) begin
        flag <= 1'b1;
    end
    else begin
        flag <= flag ;
    end

end
//****************************************************************
//1s计时器
//****************************************************************


always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt <= 26'd0;
    end 
    else if(add_cnt)begin 
        if(end_cnt)begin 
            cnt <= 26'd0;
        end
        else begin 
            cnt <= cnt + 1'b1;
        end 
    end
    else if (state != 2'b10) begin
        cnt <= 26'd0;
    end
    else begin
        cnt <= cnt;
    end
end 

assign add_cnt = flag;
assign end_cnt = add_cnt && cnt == MAX1S;

//****************************************************************
//5s计时器
//****************************************************************


always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_5s <= 3'd0;
    end 
    else if(add_cnt_5s)begin 
        if(end_cnt_5s)begin 
            cnt_5s <= 3'd0;
        end
        else begin 
            cnt_5s <= cnt_5s + 1'b1;
        end 
    end
    else if (state != 2'b10) begin
        cnt_5s<= 3'd0;
    end
    else begin
        cnt_5s <= cnt_5s;
    end
end 

assign add_cnt_5s = end_cnt;
assign end_cnt_5s = add_cnt_5s && cnt_5s == 3'd5;


//****************************************************************
//位置信号驱动
//****************************************************************
//控制位置信号
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag_alarm_r <= 3'd0;
    end
    else if ((state == 2'b10)) begin
        if (!key_in[1]) begin
           if (flag_alarm_r == 3'd6) begin
            flag_alarm_r <= 3'd1;
        end
        else begin
            flag_alarm_r <= flag_alarm_r + 1'b1;
        end
        end
        else if (!key_in[3]) begin
            flag_alarm_r <= 3'd0;
        end
        else begin
            flag_alarm_r <= flag_alarm_r;
        end 
    end
    else begin
        flag_alarm_r <= 3'd0;
    end
end
assign  flag_alarm = flag_alarm_r;
//****************************************************************
//是定闹钟的主要模块,当不在闹钟状态时使得值一直设定的值一样,在闹钟
//时根据位置信号和按键信号来加减值
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        sec_low   <= 4'd0;
        sec_high  <= 4'd0;
        mine_low  <= 4'd0;
        mine_high <= 4'd0;
        hour_low  <= 4'd0;
        hour_high <= 4'd0;
    end
    else if (state == 2'b10) begin
        if (flag_alarm_r == 3'd1) begin
            if (!key_in[2]) begin
                sec_low <= sec_low + 1'b1;
            end
            else if (sec_low == 4'd10) begin
                sec_low <= 4'd0;
            end
        end
        else if (flag_alarm_r == 3'd2) begin
            if (!key_in[2]) begin
                sec_high <= sec_high + 1'b1;
            end
            else if (sec_high == 4'd6) begin
                sec_high <= 4'd0;
            end
        end
        else if (flag_alarm_r == 3'd3) begin
            if (!key_in[2]) begin
                mine_low <= mine_low + 1'b1;
            end
            else if (mine_low == 4'd10) begin
                mine_low <= 4'd0;
            end
        end
        else if (flag_alarm_r == 3'd4) begin
            if (!key_in[2]) begin
                mine_high <= mine_high + 1'b1;
            end
            else if (mine_high == 4'd6) begin
                mine_high <= 4'd0;
            end
        end
        else if (flag_alarm_r == 3'd5) begin
            if (!key_in[2]) begin
                hour_low <= hour_low + 1'b1;
            end
            else if ((hour_low == 4'd10)&&(hour_high <= 4'd1)) begin
                hour_low<= 4'd0;
            end
            else if ((hour_low == 4'd4)&&(hour_high == 4'd2)) begin
                hour_low <= 4'd0;
            end
        end
        else if (flag_alarm_r == 3'd6) begin
            if (!key_in[2]) begin
                hour_high <= hour_high + 1'b1;
            end
            else if ((hour_high == 4'd2)&&(hour_low >=4'd4)) begin
                hour_high <= 4'd0;
            end
            else if ((hour_high == 4'd3)&&(hour_low < 4'd4)) begin
                hour_high <= 4'd0;
            end
        end
        else begin
            sec_low   <= sec_low  ;
            sec_high  <= sec_high ;
            mine_low  <= mine_low ;
            mine_high <= mine_high;
            hour_low  <= hour_low ;
            hour_high <= hour_high;
        end
    end
end

assign adjust_alarm = {hour_high ,hour_low,mine_high , mine_low , sec_high , sec_low} ;

//****************************************************************
//闹钟判断和蜂鸣器模块
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        beep <= 1'b1;
    end
    else if ((adjust_alarm === times)&&flag_beep_r) begin//当时间达到并且使能为1时beep响
        beep <= 1'b0;
    end
    else if (!flag_beep_r) begin//当时能为0时
        beep <= 1'b1;
    end
    else begin
        beep <= beep;
    end
end
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag_beep_r <= 1'b0;
    end
    else if (end_cnt_5s) begin//当计时结束后使得使能自动归0停止闹钟
        flag_beep_r <= 1'b0;
    end
    else if (!key_in[3]&&(state == 2'b10)) begin//当按下第四个按键时翻转用来控制开始和结束
        flag_beep_r <= ~flag_beep_r;
    end
    else begin
       flag_beep_r <= flag_beep_r; 
    end
end
//****************************************************************
//led显示
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        led_r <= 1'b0;
    end
    else if (flag_beep_r == 1) begin//当使能为1即设定了闹钟led就亮否则不亮
        led_r <= 1'b1;
    end
    else begin
        led_r <= 1'b0;
    end
end
assign led_alarm = led_r;
endmodule    
    

下面是数码管驱动模块,这里我为了让选择到的哪一位频闪所以采用了一个巧妙的三位运算符的方法来控制,大家可以自己看一下

/**************************************功能介绍***********************************
Date	: 2023.8.2
Author	: WZY.
Version	: 
Description: 这是一个数码管显示模块,用来显示各个功能的值
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module seg_dirver( 
    input 	wire				clk		,
    input 	wire				rst_n	,
    input   wire    [1:0]       state   ,//状态
    input   wire    [23:0]      times ,     //基础时钟寄存器
    input   wire    [5:0]       point   ,//点控制寄存器
    input   wire    [2:0]       flag    ,//调时位选信号
    input   wire    [23:0]      adjust_time,//调时显示寄存器
    input   wire    [2:0]       flag_alarm,//闹钟位选信号
    input   wire    [23:0]      adjust_alarm,//闹钟显示寄存器
    input   wire    [23:0]      adjust_clock,//计时器寄存器
    output  reg     [5:0]       sel     ,//位选
    output  reg     [7:0]       seg     //段选
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter MAX20US = 10'd999;
parameter MAX_500MS = 25'd24_999_999;//500ms
//数码管译码参数
parameter   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    ,
            A               =   7'b000_1000    ,
            B               =   7'b000_0011    ,
            C               =   7'b100_0110    ,
            D               =   7'b010_0001    ,
            E               =   7'b000_0110    ,
            F               =   7'b000_1110    ,
            DARK             =  7'b111_1111     ;//全灭
//---------<内部信号定义>-----------------------------------------------------
//20us计数器
reg			[9:0]	cnt	   	;
wire				add_cnt	;
wire				end_cnt	;
//500ms计数器
reg			[24:0]	cnt_500ms	   	;
wire				add_cnt_500ms	;
wire				end_cnt_500ms	;
reg                 flash;//闪烁信号

reg         [23:0]   num     ;//位选赋值寄存器
reg         [4:0]      seg_temp;//seg单位值
reg                 point_r ;//点位控制
//****************************************************************
//20us计数器
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt <= 10'd0;
    end 
    else if(add_cnt)begin 
        if(end_cnt)begin 
            cnt <= 10'd0;
        end
        else begin 
            cnt <= cnt + 1'b1;
        end 
    end
end 

assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == MAX20US;

//****************************************************************
//500ms计数器
//****************************************************************

always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt_500ms <= 25'd0;
    end 
    else if(add_cnt_500ms)begin 
        if(end_cnt_500ms)begin 
            cnt_500ms <= 25'd0;
        end
        else begin 
            cnt_500ms <= cnt_500ms + 1'b1;
        end 
    end
    else begin
        cnt_500ms <= 25'd0;
    end
end 

assign add_cnt_500ms = (state == 2'b01)||(state == 2'b10);
assign end_cnt_500ms = add_cnt_500ms && cnt_500ms == MAX_500MS;
//****************************************************************
//驱动闪烁信号
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flash <= 1'b0;
    end
    else if (end_cnt_500ms) begin//每500ms翻转一次
        flash <= ~flash;
    end
    else if ((state != 2'b01)&&(state != 2'b10)) begin//当不在调时和闹钟状态归0
        flash <= 1'b0;
    end
    else begin
        flash <=flash;
    end
end
//****************************************************************
//seg显示选择.根据状态选择数码管显示的值
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        num <= 24'd0;
    end
    else if (state == 2'b00) begin
        num <=times;
    end
    else if (state == 2'b01) begin
        num <= adjust_time;
    end
    else if (state == 2'b10) begin
        num <= adjust_alarm;
    end
    else if (state == 2'b11) begin
        num <= adjust_clock;
    end
    else  begin
        num <= num;
    end
end
//****************************************************************
//驱动sel
//****************************************************************   
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        sel <= 6'b111_110;
    end 
    else if(end_cnt)begin 
        sel <= {sel[4:0],sel[5]};
    end 
    else begin 
       sel <= sel; 
    end 
end
//****************************************************************
//位选赋值,当选择到哪一位哪一位进行频闪
//****************************************************************
always @(*) begin
    case (sel)
        6'b011111:begin seg_temp = (flash&&((flag==3'd1||(flag_alarm == 3'd1))))?5'd15 : num[3:0]         ; point_r = point[0];end
        6'b101111:begin seg_temp = (flash&&((flag==3'd2||(flag_alarm == 3'd2))))?5'd15 : num[7:4]         ; point_r = point[1];end
        6'b110111:begin seg_temp = (flash&&((flag==3'd3||(flag_alarm == 3'd3))))?5'd15 : num[11:8]        ; point_r = point[2];end
        6'b111011:begin seg_temp = (flash&&((flag==3'd4||(flag_alarm == 3'd4))))?5'd15 : num[15:12]       ; point_r = point[3];end
        6'b111101:begin seg_temp = (flash&&((flag==3'd5||(flag_alarm == 3'd5))))?5'd15 : num[19:16]       ; point_r = point[4];end
        6'b111110:begin seg_temp = (flash&&((flag==3'd6||(flag_alarm == 3'd6))))?5'd15 : num[23:20]       ; point_r = point[5];end
        default: seg_temp = 4'd0;
    endcase
end
//****************************************************************
//译码
//****************************************************************
always @(*) begin
    case (seg_temp)
        4'd0: seg = {point_r,ZERO  };
        4'd1: seg = {point_r,ONE   };
        4'd2: seg = {point_r,TWO   };
        4'd3: seg = {point_r,THREE };
        4'd4: seg = {point_r,FOUR  };
        4'd5: seg = {point_r,FIVE  };
        4'd6: seg = {point_r,SIX   };
        4'd7: seg = {point_r,SEVEN };
        4'd8: seg = {point_r,EIGHT };
        4'd9: seg = {point_r,NINE  };
        4'd15:seg = {point_r,DARK};
        default: seg = 8'b1111_1111;
    endcase
end
endmodule

最后是消抖和秒表比较简单
消抖

module key_debounce (
    input   wire            clk     ,
    input   wire            rst_n   ,
    input   wire    [3:0]   key_in  ,
    output  wire    [3:0]   key_out 
);

parameter MAX20ms = 20'd999_999;

wire            add_cnt;//倒计时开始使能
wire            end_cnt;//倒计时结束使能
reg    [19:0]   cnt_20ms;//20ms计数寄存器
reg    [3:0]    key_r0;//同步
reg    [3:0]    key_r1;//打拍
reg             start;//下降沿检测寄存器
reg    [3:0]    flag;
reg    [3:0]    key_out_r;//输出按键信号寄存器
wire            nedge;



//下降沿检测
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        key_r0 <= 4'b1111;
        key_r1 <= 4'b1111;
    end
    else begin
        key_r0 <= key_in;
        key_r1 <= key_r0;
    end
end

assign nedge = (~key_r0[0]&key_r1[0])||(~key_r0[1]&key_r1[1])||(~key_r0[2]&key_r1[2])||(~key_r0[3]&key_r1[3]);

//20ms计时器
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_20ms <= 20'd0;
    end
    else if (nedge) begin
        cnt_20ms <= 20'd0;
    end
    else if (add_cnt) begin
        if (end_cnt) begin
            cnt_20ms <= 20'd0;
        end
        else begin
            cnt_20ms <= cnt_20ms + 1'b1;
        end
    end
    else begin
        cnt_20ms <= 20'd0;
    end
end

assign add_cnt = start;
assign end_cnt = add_cnt && (cnt_20ms == MAX20ms);

//约束start
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        start <= 1'b0;
    end
    else if (nedge) begin
        start <= 1'b1;
    end
    else if (end_cnt) begin
        start <= 1'b0;
    end
    else begin
        start <= start ;
    end
end

//约束flag
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag <= 4'b1111;
    end
    else if (nedge) begin
        flag <= 4'b1111;
    end
    else if (end_cnt) begin
        flag <= key_r0;
    end
    else begin
        flag <= 4'b1111 ;
    end
end
//脉冲信号
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        key_out_r <= 4'b1111;
    end
    else if (!flag[0]) begin
        key_out_r <= 4'b1110;
    end
    else if (!flag[1]) begin
        key_out_r <= 4'b1101;
    end
    else if (!flag[2]) begin
        key_out_r <= 4'b1011;
    end
    else if (!flag[3]) begin
        key_out_r <= 4'b0111;
    end
    else begin
        key_out_r <= 4'b1111;
    end
end

// //持续信号
// always @(posedge clk or negedge rst_n) begin
//     if (!rst_n) begin
//         key_out_r <= 4'b1111;
//     end
//     else if (!flag[0]) begin
//         key_out_r <= 4'b1110;
//     end
//     else if (!flag[1]) begin
//         key_out_r <= 4'b1101;
//     end
//     else if (!flag[2]) begin
//         key_out_r <= 4'b1011;
//     end
//     else if (!flag[3]) begin
//         key_out_r <= 4'b0111;
//     end
//     else begin
//         key_out_r <= key_out_r;
//     end
// end

assign key_out = key_out_r;
endmodule```
秒表

```cpp
/**************************************功能介绍***********************************
Date	: 
Author	: WZY.
Version	: 
Description: 这是一个秒表
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module stop_watch( 
    input 	wire				clk		,
    input 	wire				rst_n	,
    input   wire    [3:0]       key_in  ,
    input   wire    [1:0]       state   ,
    output  wire    [23:0]      adjust_clock//秒表寄存器(分钟/秒/毫秒/)
);								 
//---------<参数定义>--------------------------------------------------------- 
parameter   max1ms = 19'd499_999;//100ms
reg  [3:0]  ms_low;
reg  [3:0]  ms_high;
reg  [3:0]  s_low;
reg  [3:0]  s_high;
reg  [3:0]  mine_low;
reg  [3:0]  mine_high;


reg			[18:0]	cnt	   	;
wire				add_cnt	;
wire				end_cnt	;

wire                add_cnt_ms_low;
wire                end_cnt_ms_low;
wire                add_cnt_ms_high;
wire                end_cnt_ms_high;
wire                add_cnt_s_low;
wire                end_cnt_s_low;
wire                add_cnt_s_high;
wire                end_cnt_s_high;
wire                add_cnt_mine_low;
wire                end_cnt_mine_low;
wire                add_cnt_mine_high;
wire                end_cnt_mine_high;

reg                 flag_clock;
//---------<内部信号定义>-----------------------------------------------------

//****************************************************************
//秒表使能
//****************************************************************
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag_clock <= 1'b0;
    end
    else if ((!key_in[1])&&(state == 2'b11)) begin
        flag_clock <= ~flag_clock;
    end
    else if ((state != 2'b11)||(!key_in[2])) begin
        flag_clock <= 1'b0;
    end
    else begin
        flag_clock <= flag_clock;
    end
end

//****************************************************************
//100ms计数器
//****************************************************************
always @(posedge clk or negedge rst_n)begin 
   if(!rst_n)begin
        cnt <= 19'd0;
    end 
    else if(add_cnt)begin 
        if(end_cnt)begin 
            cnt <= 19'd0;
        end
        else begin 
            cnt <= cnt + 1'b1;
        end 
    end
    else if ((state != 2'b11)||(!key_in[2])) begin
        cnt <= 19'd0;
    end
    else begin
        cnt <= cnt;
    end
end 

assign add_cnt = (state == 2'b11)&&(flag_clock);
assign end_cnt = add_cnt && (cnt == max1ms);

    
//****************************************************************
//秒表模块
//**************************************************************** 

//ms
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        ms_low <= 4'd0;
    end
    else if (add_cnt_ms_low) begin
        if (end_cnt_ms_low) begin
            ms_low <= 4'd0;
        end
        else begin
            ms_low <= ms_low + 1'd1;
        end
    end
    else if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begin
        ms_low <= 4'd0;
    end
    else begin
        ms_low <= ms_low;
    end
end

assign add_cnt_ms_low = end_cnt;
assign end_cnt_ms_low = add_cnt_ms_low&&(ms_low == 9);

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        ms_high <= 4'd0;
    end
    else if (add_cnt_ms_high) begin
        if (end_cnt_ms_high) begin
            ms_high <= 4'd0;
        end
        else begin
            ms_high <= ms_high + 1'd1;
        end
    end
    else if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begin
        ms_high <= 4'd0;
    end
    else begin
        ms_high <= ms_high;
    end
end

assign add_cnt_ms_high = end_cnt_ms_low;
assign end_cnt_ms_high = add_cnt_ms_high&&(ms_high == 5);

//s
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        s_low <= 4'd0;
    end
    else if (add_cnt_s_low) begin
        if (end_cnt_s_low) begin
            s_low <= 4'd0;
        end
        else begin
            s_low <= s_low + 1'd1;
        end
    end
    else if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begin
        s_low <= 4'd0;
    end
    else begin
        s_low <= s_low;
    end
end

assign add_cnt_s_low = end_cnt_ms_high;
assign end_cnt_s_low = add_cnt_s_low&&(s_low == 9);


always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        s_high <= 4'd0;
    end
    else if (add_cnt_s_high) begin
        if (end_cnt_s_high) begin
            s_high <= 4'd0;
        end
        else begin
            s_high <= s_high + 1'd1;
        end
    end
    else if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begin
        s_high <= 4'd0;
    end
    else begin
        s_high <= s_high;
    end
end

assign add_cnt_s_high = end_cnt_s_low;
assign end_cnt_s_high = add_cnt_s_high&&(s_high == 5);

//mine
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        mine_low <= 4'd0;
    end
    else if (add_cnt_mine_low) begin
        if (end_cnt_mine_low) begin
            mine_low <= 4'd0;
        end
        else begin
            mine_low <= mine_low + 1'd1;
        end
    end
    else if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begin
        mine_low <= 4'd0;
    end
    else begin
        mine_low <= mine_low;
    end
end

assign add_cnt_mine_low = end_cnt_s_high;
assign end_cnt_mine_low = add_cnt_mine_low&&(mine_low == 9);

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        mine_high <= 4'd0;
    end
    else if (add_cnt_mine_high) begin
        if (end_cnt_mine_high) begin
            mine_high <= 4'd0;
        end
        else begin
            mine_high <= mine_high + 1'd1;
        end
    end
    else if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begin
        mine_high <= 4'd0;
    end
    else begin
        mine_high <= mine_high;
    end
end

assign add_cnt_mine_high = end_cnt_mine_low;
assign end_cnt_mine_high = add_cnt_mine_high&&(mine_high == 5);


assign adjust_clock = {mine_high , mine_low ,s_high , s_low , ms_high,ms_low};


endmodule

顶层

/**************************************功能介绍***********************************
Date	: 2023.8.2
Author	: WZY.
Version	: 
Description: 这是一个顶层模块
*********************************************************************************/
    
//---------<模块及端口声名>------------------------------------------------------
module top( 
    input   wire		clk     ,
    input   wire		rst_n	,
    input   wire    [3:0]       key_in  ,
    output  wire    [3:0]       led_on  ,
    output  wire                beep    ,
    output  wire    [5:0]       sel     ,
    output  wire    [7:0]       seg    
);								 
//---------<参数定义>--------------------------------------------------------- 
wire    [3:0]   key_debounce;
wire    [1:0]   state;
wire    [2:0]   flag;
wire    [23:0]  times;
wire    [23:0]  adjust_time;
wire    [2:0]   flag_alarm;
wire    [23:0]  adjust_alarm;
wire    [23:0]  adjust_clock;
//---------<内部信号定义>-----------------------------------------------------

// // ****************************************************************
// // 模块例化
// // ****************************************************************   
// //消抖模块例化
// key_debounce key_debounce_inst(
//                 .clk     (clk),
//                 .rst_n   (rst_n),
//                 .key_in  (key_in),
//                 .key_out (key_debounce)
// );

// //状态机例化
// state_change state_change_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),//按键输入
//                 .beep           (beep)  ,
//                 .led_on         (led_on[1:0]),//led灯显示用来判断当前在什么状态
//                 .state          (state)  //状态输出
// );

// //基础时钟例化
// counter counter_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .flag           (flag),
//                 .times          (times),
//                 .adjust_time    (adjust_time)     //时间调整
// );	
// //调时模块例化
// adjust_state adjust_state_inst( 
//                 .clk	        (clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .times          (times),
//                 .flag           (flag),
//                 .adjust_time    (adjust_time)
// );	
// //闹钟模块例化
// alarm_clock alarm_clock_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .times          (times),
//                 .beep           (beep),
//                 .flag_alarm     (flag_alarm),
//                 .adjust_alarm   (adjust_alarm),
//                 .led_alarm      (led_on[3])

// );
// //秒表模块例化
// stop_watch stop_watch_inst( 
//                 .clk		    (clk),
//                 .rst_n	        (rst_n),
//                 .key_in         (key_debounce),
//                 .state          (state),
//                 .adjust_clock   (adjust_clock)//秒表寄存器(分钟/秒/毫秒/)
// );
// //数码管驱动例化
// seg_dirver seg_dirver_inst( 
//                 .clk		(clk),
//                 .rst_n	        (rst_n),
//                 .state          (state),
//                 .times          (times),
//                 .point          (6'b101011),
//                 .flag           (flag),//调时位选信号
//                 .adjust_time    (adjust_time),//调时显示寄存器
//                 .flag_alarm     (flag_alarm),//闹钟位选信号
//                 .adjust_alarm   (adjust_alarm),//闹钟显示寄存器
//                 .adjust_clock   (adjust_clock),//秒表显示寄存器
//                 .sel            (sel),
//                 .seg            (seg)
// );



// ****************************************************************
// 模块例化
// ****************************************************************   
//消抖模块例化
//状态机例化
state_change state_change_inst( 
                .clk		(clk),
                .rst_n	        (rst_n),
                .key_in         (key_in),//按键输入
                .beep           (beep)  ,
                .led_on         (led_on[1:0]),//led灯显示用来判断当前在什么状态
                .state          (state)  //状态输出
);

//基础时钟例化
counter counter_inst( 
                .clk		(clk),
                .rst_n	        (rst_n),
                .key_in         (key_in),
                .state          (state),
                .flag           (flag),
                .times          (times),
                .adjust_time    (adjust_time)     //时间调整
);	
//调时模块例化
adjust_state adjust_state_inst( 
                .clk	        (clk),
                .rst_n	        (rst_n),
                .key_in         (key_),
                .state          (state),
                .times          (times),
                .flag           (flag),
                .adjust_time    (adjust_time)
);	
//闹钟模块例化
alarm_clock alarm_clock_inst( 
                .clk		(clk),
                .rst_n	        (rst_n),
                .key_in         (key_in),
                .state          (state),
                .times          (times),
                .beep           (beep),
                .flag_alarm     (flag_alarm),
                .adjust_alarm   (adjust_alarm),
                .led_alarm      (led_on[3])

);
//秒表模块例化
stop_watch stop_watch_inst( 
                .clk		    (clk),
                .rst_n	        (rst_n),
                .key_in         (key_in),
                .state          (state),
                .adjust_clock   (adjust_clock)//秒表寄存器(分钟/秒/毫秒/)
);
//数码管驱动例化
seg_dirver seg_dirver_inst( 
                .clk		(clk),
                .rst_n	        (rst_n),
                .state          (state),
                .times          (times),
                .point          (6'b101011),
                .flag           (flag),//调时位选信号
                .adjust_time    (adjust_time),//调时显示寄存器
                .flag_alarm     (flag_alarm),//闹钟位选信号
                .adjust_alarm   (adjust_alarm),//闹钟显示寄存器
                .adjust_clock   (adjust_clock),//秒表显示寄存器
                .sel            (sel),
                .seg            (seg)
);
endmodule

四,测试文件

`timescale 1ns/1ns
    
module top_tb();

//激励信号定义 
reg		            clk     ;
reg		            rst_n	;
reg    [3:0]        key_in  ;
   
//输出信号定义	 
wire    [3:0]       led_on ;
wire                beep   ;
wire    [5:0]       sel    ;
wire    [7:0]       seg    ;
//时钟周期参数定义	
    parameter		CYCLE = 20; 
    defparam        top_inst.counter_inst.MAX1s = 10*CYCLE,
                    top_inst.seg_dirver_inst.MAX20US = CYCLE,
                    top_inst.seg_dirver_inst.MAX_500MS = 5*CYCLE,  
                    top_inst.alarm_clock_inst.MAX1S = 10*CYCLE;

//模块例化
    top top_inst( 
        .clk     (clk),
        .rst_n	 (rst_n),
        .key_in  (key_in),
        .led_on  (led_on),
        .beep    (beep),
        .sel     (sel),
        .seg     (seg)
);	

//产生时钟
    initial 		clk = 1'b0;
    always #(CYCLE/2) clk = ~clk;

//产生激励

// //调值模块仿真
//     initial  begin 
//         rst_n = 1'b1;
//         key_in = 4'b1111;
//         #(CYCLE*2);
//         rst_n = 1'b0;
//         #(CYCLE*20);
//        rst_n = 1'b1;
//        #(CYCLE*10000)  //延迟10000个周期来观察基础时钟
//        key_in = 4'b1110;//按下key0进入调时状态
//        #CYCLE
//        key_in = 4'b1111;
//        #(CYCLE*20)
//        key_in = 4'b1101;    //按下key1选择第一位
//        #CYCLE
//        key_in = 4'b1111;
//        #(CYCLE*20)
//        repeat(5)begin
//         key_in = 4'b1011;//连续按下key2使得秒的个位+1
//        #(CYCLE)
//        key_in = 4'b1111;
//        #(CYCLE*20);
//        end
//        #(CYCLE*100)
//        key_in = 4'b0111;//按下key3确定更改时间
//        #(CYCLE)
//        key_in = 4'b1111;
//        #(CYCLE*10000)
//         $stop;
//     end

//调值模块仿真
    initial  begin 
        rst_n = 1'b1;
        key_in = 4'b1111;
        #(CYCLE*2);
        rst_n = 1'b0;
        #(CYCLE*20);
       rst_n = 1'b1;
       key_in = 4'b1101;//按下key1进入闹钟状态
       #CYCLE
       key_in = 4'b1111;
       #(CYCLE*20)
       key_in = 4'b1101;    //按下key1选择第一位
       #CYCLE
       key_in = 4'b1111;
       #(CYCLE*20)
       key_in = 4'b1101;    //按下key1选择第二位
       #CYCLE
       key_in = 4'b1111;
       #(CYCLE*20)
       repeat(5)begin
        key_in = 4'b1011;//连续按下key2使得秒的个位+1使得计时50s
       #(CYCLE)
       key_in = 4'b1111;
       #(CYCLE*20);
       end
       key_in = 4'b0111;//按下key3确定设定闹钟
       #(CYCLE)
       key_in = 4'b1111;
       #(CYCLE*10000)  //延迟10000个周期等待闹钟触发
       #(CYCLE*10000)
        $stop;
    end

endmodule 

波形:
这是基础时钟的仿真波形,可以看到基础功能实现
在这里插入图片描述

这是修改时间模块的波形,可以看到当按键按下时状态改变并且当按下key1时位置信号变为001表示控制个位,之后按下key2个位数字+1并且按下key3时基础时钟的times变更为更改时间adjust_time的值说明更改成功基本功能实现
在这里插入图片描述

下面是闹钟模块的仿真波形,可以看到当设置闹钟后,等到基础时钟到达设定值,蜂鸣器拉低,开始5s计时,当计时结束蜂鸣器拉高停止响,这里我也同样做了按键停止,但是效果差不多,就只展示计时停止
在这里插入图片描述

六,结果展示

上板验证

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/843411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五、PC远程控制ESP32 LED灯

1. 整体思路 2. 代码 # 整体流程 # 1. 链接wifi # 2. 启动网络功能(UDP) # 3. 接收网络数据 # 4. 处理接收的数据import socket import time import network import machinedef do_connect():wlan = network.WLAN(network.STA_IF)wlan.active(True)if not wlan.isconnected(…

LVS集群

目录 1、lvs简介&#xff1a; 2、lvs架构图&#xff1a; 3、 lvs的工作模式&#xff1a; 1&#xff09; VS/NAT&#xff1a; 即&#xff08;Virtual Server via Network Address Translation&#xff09; 2&#xff09;VS/TUN &#xff1a;即&#xff08;Virtual Server v…

手写SpringCloud系列-一分钟理解微服务注册中心(Nacos)原理。

手写SpringCLoud项目地址&#xff0c;求个star github:https://github.com/huangjianguo2000/spring-cloud-lightweight gitee:https://gitee.com/huangjianguo2000/spring-cloud-lightweigh 一&#xff1a;什么是注册中心 1. 总结服务注册中心 我们可以理解注册中心就是一个…

LeetCode 热题 100JavaScript--2. 两数相加

给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数都不会以 0 …

手机上的照片怎么压缩?推荐这几种压缩方法

手机上的照片怎么压缩&#xff1f;如果你需要通过电子邮件或短信发送照片&#xff0c;则可能需要将其压缩为较小的文件大小以便于发送。另外&#xff0c;如果您你的手机存储空间有限&#xff0c;可以通过压缩照片来节省空间。下面就给大家介绍几种压缩手机照片的方法。 1、使用…

Spring5.2.x 源码使用Gradle成功构建

一 前置准备 1 Spring5.2.x下载 1.1 Spring5.2.x Git下载地址 https://gitcode.net/mirrors/spring-projects/spring-framework.git 1.2 Spring5.2.x zip源码包下载&#xff0c;解压后倒入idea https://gitcode.net/mirrors/spring-projects/spring-framework/-/…

地球人口承载力估计 解析和C++代码

Description 假设地球上的新生资源按恒定速度增长。照此测算&#xff0c;地球上现有资源加上新生资源可供x亿人生活a年&#xff0c;或供y亿人生活b年。 为了能够实现可持续发展&#xff0c;避免资源枯竭&#xff0c;地球最多能够养活多少亿人&#xff1f; Input 一行&#xf…

共治、公开、透明!龙蜥社区 7 月技术委员会会议顺利召开!

2023 年 7 月 14 日上午 10 点召开了龙蜥社区7月技术委员会线上会议&#xff0c;共计 39 人参会&#xff0c;本次会议由浪潮信息苏志远博士主持&#xff0c;开放原子 TOC 导师陈阳、霍海涛、徐亮、余杰共同参会&#xff0c;技术委员们来自 Arm、阿里云、飞腾、海光、红旗软件、…

springcloud:对象存储组件MinIO(十六)

0. 引言 在实际开发中&#xff0c;我们经常会面临需要存储文档、存储图片等文件存储需求&#xff0c;并且在分布式架构下&#xff0c;文件又需要实现各节点共享&#xff0c;类似于共享文件夹类的需求&#xff0c;在分布式服务器中创建共享文件夹成本较大&#xff0c;甚至当需要…

Java课题笔记~ 不使用 AOP 的开发方式(理解)

Step1&#xff1a;项目 aop_leadin1 先定义好接口与一个实现类&#xff0c;该实现类中除了要实现接口中的方法外&#xff0c;还要再写两个非业务方法。非业务方法也称为交叉业务逻辑&#xff1a; doTransaction()&#xff1a;用于事务处理 doLog()&#xff1a;用于日志处理 …

第一天 什么是CSRF ?

✅作者简介&#xff1a;大家好&#xff0c;我是Cisyam&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Cisyam-Shark的博客 &#x1f49e;当前专栏&#xff1a; 每天一个知识点 ✨特色专…

【小沐学C++】C++ 基于CMake构建工程项目(Windows、Linux)

文章目录 1、简介2、下载cmake3、安装cmake4、测试cmake4.1 单个源文件4.2 同一目录下多个源文件4.3 不同目录下多个源文件4.4 标准组织结构4.5 动态库和静态库的编译4.6 对库进行链接4.7 添加编译选项4.8 添加控制选项 5、构建最小项目5.1 新建代码文件5.2 新建CMakeLists.txt…

neo4j查询语言Cypher详解(二)--Pattern和类型

Patterns 图形模式匹配是Cypher的核心。它是一种用于通过应用声明性模式从图中导航、描述和提取数据的机制。在MATCH子句中&#xff0c;可以使用图模式定义要搜索的数据和要返回的数据。图模式匹配也可以在不使用MATCH子句的情况下在EXISTS、COUNT和COLLECT子查询中使用。 图…

Java Map集合详解 :HashMap类

Map 是一种键-值对&#xff08;key-value&#xff09;集合&#xff0c;Map 集合中的每一个元素都包含一个键&#xff08;key&#xff09;对象和一个值&#xff08;value&#xff09;对象。用于保存具有映射关系的数据。 Map 集合里保存着两组值&#xff0c;一组值用于保存 Map …

FAST协议详解1 不同数据类型的编码与解码

一、概述 FAST协议里不同的数据类型在编码时有非常大的区别&#xff0c;比如整数只需要将二进制数据转为十进制即可&#xff0c;而浮点数则需要先传小数点位数&#xff0c;再传一个整数&#xff0c;最后将二者结合起来才是最终结果。本篇使用openfast自设了一些数据并编码成FA…

一文了解 Android Auto 车载开发~

作者&#xff1a;牛蛙点点申请出战 背景 我的的产品作为一个海外音乐播放器&#xff0c;在车载场景听歌是一个很普遍的需求。在用户反馈中&#xff0c;也有很多用户提到希望能在车上播放音乐。同时车载音乐也可以作为提升用户消费时长一个抓手。 出海产品&#xff0c;主要服务…

[国产MCU]-BL602开发实例-定时器

定时器 文章目录 定时器1、BL602定时器介绍2、定时器驱动API介绍3、定时器使用实例3.1 单次计时3.2 持续计时通用定时器,用于定时,当时间到达我们所设置的定时时间会产生定时中断,可以用来完成定时任务。本文将详细介绍如何使用BL602的定时器功能。 1、BL602定时器介绍 BL6…

vscode自动添加注释说明

1. 安装vscode 双击安装程序,默认安装即可(如:VSCodeSetup-x64-1.70.2.exe) 2. 安装doxygen文档生成插件 1> 打开vscode软件,点击左侧插件管理菜单 2> 点击右上角’…‘按钮,选择’Install from VSIX’(联网状态可以直接搜索doxygen下载安装) 3> 选择doxygen离线安装…

torchvision.datasets数据加载失败

torchvision.datasets数据加载失败 如何使用torchvision.datasets进行自动下载数据失败&#xff0c;可以使用手动下载数据 Ctrl点击可以进入相关包文件&#xff0c;查找下载地址&#xff1a;https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz 手动下载之后解压&#x…

【Spring】(四)Bean 的作用域和生命周期

文章目录 前言一、Bean 的作用域1.1 被修改的 Bean 案例1.2 作用域的定义1.3 Bean 的六种作用域1.4 Bean 作用域的设置 二、Spring 的执行流程 和 Bean 的生命周期2.1 Spring 的执行流程2.2 Bean 的生命周期2.3 Bean 生命周期的演示 前言 Bean 是 Spring 框架中的一个核心概念…