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

一,项目要求

在这里插入图片描述

二,理论原理

通过按键来控制状态机的状态,在将状态值传送到各个模块进行驱动,在空闲状态下,数码管显示基础时钟,基础时钟是由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计时,当计时结束蜂鸣器拉高停止响,这里我也同样做了按键停止,但是效果差不多,就只展示计时停止
在这里插入图片描述

六,结果展示

上板验证

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AlexNet卷积神经网络-笔记

AlexNet卷积神经网络-笔记 AlexNet卷积神经网络2012年提出 测试结果为&#xff1a; 通过运行结果可以发现&#xff0c; 在眼疾筛查数据集iChallenge-PM上使用AlexNet&#xff0c;loss能有效下降&#xff0c; 经过5个epoch的训练&#xff0c;在验证集上的准确率可以达到94%左右…

电源控制--品质因素Q值全解

什么是品质因素Q值&#xff1f; 在电源控制中&#xff0c;品质因素 Q 值通常用于描述电源滤波器的性能。电源滤波器用于减小电源中的噪声和干扰&#xff0c;以提供干净稳定的电源供应给电子设备。 品质因素 Q 值在电源滤波器中表示滤波器的带宽和中心频率之比&#xff0c;用于…

SpringBoot集成百度人脸识别实现登陆注册功能Demo(二)

前言 上一篇SpringBoot集成百度人脸demo中我使用的是调用本机摄像头完成人脸注册&#xff0c;本次demo根据业务需求的不同我采用文件上传的方式实现人脸注册。 效果演示 注册 后端响应数据&#xff1a; 登录 后端响应数据&#xff1a; 项目结构 后端代码实现 1、BaiduAiUtil…

【C++学习】STL容器——list

目录 一、list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 list的构造 1.2.2 list iterator的使用 1.2.3 list capacity 1.2.4 list element access 1.2.5 list modifiers 1.2.6 list 迭代器失效 二、list的模拟实现 2.1 模拟实现list 三、list和vector的对比…

8月1日上课内容 第一章web基础与http协议

dns与域名 网络是基于tcp/ip协议进行通信和连接的 应用层--传输层---网络层----数据链路层-----物理层 ip地址&#xff0c;我们每一台主机都有一个唯一的地址标识(固定的ip地址)&#xff0c;区分用户和计算机通信。 ip地址:32位二进制数组成的&#xff0c;不方便记忆 192.168.…

SpringMVC -- REST风格开发,RESTful快速开发、RESTful注解开发

&#x1f40c;个人主页&#xff1a; &#x1f40c; 叶落闲庭 &#x1f4a8;我的专栏&#xff1a;&#x1f4a8; c语言 数据结构 javaweb 石可破也&#xff0c;而不可夺坚&#xff1b;丹可磨也&#xff0c;而不可夺赤。 REST 一、REST简介1.1REST风格简介 二、RESTful入门案例2.…

绘制曲线python

文章目录 import matplotlib.pyplot as plt# 提供的数据 x= [1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,2,2.1,2.2,2.3,2.4,2.5,2.6,2.7,2.8,2.9,3,3.1,3.2,3.3,3.4,3.5,3.6,3.7,3.8,3.9,4,4.1,4.2,4.3,4.4,4.5,4.6,4.7,4.8,4.9,5,5.1,5.2,5.3,5.4,5.5,5.6,5.7,5.8,5.9,6,6.1,6.2…

门面模式(C++)

定义 为子系统中的一组接口提供一个一致(稳定) 的界面&#xff0c;Facade模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用(复用)。 应用场景 上述A方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合&#xff0c;随着外部客户程序和各子…

代码随想录算法训练营day55

文章目录 Day55 判断子序列题目思路代码 不同的子序列题目思路代码 Day55 判断子序列 392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; 题目 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以…

java文件

一.File类 二.扫描指定目录&#xff0c;并找到名称中包含指定字符的所有普通文件&#xff08;不包含目录&#xff09;&#xff0c;并且后续询问用户是否要删除该文件 我的代码: import java.io.File; import java.io.IOException; import java.util.Scanner;public class Tes…

Excel功能总结

1&#xff09;每一张表格上都打印表头 “页面布局”-->“打印标题”-->页面设置“工作表”页-->打印标题“顶端标题行” 如&#xff1a;固定第1~2行&#xff0c;设置成“$1:$2” 2&#xff09;将页面内容打印在一页【缩印】 1.选好需要打印的区域&#xff0c;“页面布…

数据结构 | 利用二叉堆实现优先级队列

目录 一、二叉堆的操作 二、二叉堆的实现 2.1 结构属性 2.2 堆的有序性 2.3 堆操作 队列有一个重要的变体&#xff0c;叫作优先级队列。和队列一样&#xff0c;优先级队列从头部移除元素&#xff0c;不过元素的逻辑顺序是由优先级决定的。优先级最高的元素在最前&#xff…

全志D1-H (MQ-Pro)驱动 OV5640 摄像头

内核配置 运行 m kernel_menuconfig 勾选下列驱动 Device Drivers ---><*> Multimedia support --->[*] V4L platform devices ---><*> Video Multiplexer[*] SUNXI platform devices ---><*> sunxi video input (camera csi/mipi…

C++11 新特性 ---- 模板的优化

C11 模板机制:① 函数模板② 类模板模板的使用&#xff1a;① 范围&#xff1a;模板的声明或定义只能在全局或类范围进行&#xff0c;不可以在局部范围&#xff08;如函数&#xff09;② 目的&#xff1a;为了能够编写与类型无关的代码函数模板&#xff1a;- 格式&#xff1a;t…

软件工程:帕金森定律

在软件开发中&#xff0c;你是否遇到过这种情况&#xff1a; 团队要开发一个简单的购物车应用&#xff0c;项目预期时间是2周工期。负责开发的工程师默认利用完整的2周时间来完成任务。在第一周&#xff0c;工程师会认为任务很轻松&#xff0c;有充足的时间来完成任务&#xff…

SPM(Swift Package Manager)开发及常见事项

SPM怎么使用的不再赘述&#xff0c;其优点是Cocoapods这样的远古产物难以望其项背的&#xff0c;而且最重要的是可二进制化、对xcproj项目无侵入&#xff0c;除了网络之外简直就是为团队开发的项目库依赖最好的管理工具&#xff0c;是时候抛弃繁杂低下的cocoapods了。 一&…

Camunda 7.x 系列【2】开源工作流引擎框架

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址&#xff1a;https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. 开源工作流引擎框架2.1 jBPM2.2 Activ…

Python识别抖音Tiktok、巨量引擎滑块验证码识别

由于最近比较忙&#xff0c;所以本周搞了一个相对简单的验证码&#xff0c;就是抖音Tiktok的滑块验证码&#xff0c;这也是接到客户的一个需求。这种验证码通常在电脑端登录抖音、巨量引擎的的时候出现。 首先看一下最终的效果&#xff1a; 验证码识别过程 1、利用爬虫采集图…

jenkins的cicd操作

cicd概念 持续集成&#xff08; Continuous Integration&#xff09; 持续频繁的&#xff08;每天多次&#xff09;将本地代码“集成”到主干分支&#xff0c;并保证主干分支可用 持续交付&#xff08;Continuous Delivery&#xff09; 是持续集成的下一步&#xff0c;持续…