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

一,项目要求

在这里插入图片描述

二,理论原理

通过按键来控制状态机的状态,在将状态值传送到各个模块进行驱动,在空闲状态下,数码管显示基础时钟,基础时钟是由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) beginif (!rst_n) begincstate <= IDLE;endelse begincstate <= nstate;end
end//三段式状态机第二段组合逻辑
always @(*) begincase (cstate)IDLE    :beginif (!key_in[0]) begin //当按键0按下时转到调时状态nstate = ADJUST;endelse if (!key_in[1]||!beep) beginnstate = ALARM;endelse if (!key_in[2]) beginnstate = STOP ;endelse beginnstate = cstate; endend ADJUST  :beginif (!key_in[0]||!key_in[3]) begin//当按下按键0时转到基础时钟nstate = IDLE;  endelse if (!beep) begin//当蜂鸣器响立刻跳转到闹钟状态nstate = ALARM;endelse beginnstate = cstate;endendALARM   :beginif (!key_in[0]) begin//当按下按键0时转到基础时钟nstate = IDLE;  endelse beginnstate = cstate;endendSTOP    :beginif (!key_in[0]) beginnstate = IDLE;endelse if (!beep) begin//当蜂鸣器响立刻跳转到闹钟状态nstate = ALARM;endelse beginnstate = cstate;endenddefault: nstate = IDLE;endcase
end //三段式状态机第三段时序逻辑
always @(posedge clk or  negedge rst_n) beginif (!rst_n) beginstate <= 2'b00;endelse 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) beginif (!rst_n) beginled_on <= 2'b00;endelse 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)begincnt_1s <= 26'd0;end else if(add_cnt&&(state != 4'b01))begin if(end_cnt)begin cnt_1s <= 26'd0;endelse 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 ) beginif (!rst_n) beginsec_low <= 4'd0;endelse if (add_sec_low) beginif (end_sec_low) beginsec_low <= 4'd0;endelse beginsec_low <= sec_low + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginsec_low <= adjust_time[3:0];endelse beginsec_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 ) beginif (!rst_n) beginsec_high <= 4'd0;endelse if (add_sec_high) beginif (end_sec_high) beginsec_high <= 4'd0;endelse beginsec_high <= sec_high + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginsec_high <= adjust_time[7:4];endelse beginsec_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 ) beginif (!rst_n) beginmine_low <= 4'd0;endelse if (add_mine_low) beginif (end_mine_low) beginmine_low <= 4'd0;endelse beginmine_low <= mine_low + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginmine_low <= adjust_time[11:8];endelse beginmine_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 ) beginif (!rst_n) beginmine_high <= 4'd0;endelse if (add_mine_high) beginif (end_mine_high) beginmine_high <= 4'd0;endelse beginmine_high <= mine_high + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginmine_high <= adjust_time[15:12];endelse beginmine_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 ) beginif (!rst_n) beginhour_low <= 4'd0;endelse if (end_hour_high) beginhour_low <= 4'd0;endelse if (add_hour_low) beginif (end_hour_low) beginhour_low <= 4'd0;endelse beginhour_low <= hour_low + 1'd1;endendelse if ((state == 2'b01)&&(!key_in[3])) beginhour_low <= adjust_time[19:16];endelse beginhour_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 ) beginif (!rst_n) beginhour_high <= 4'd0;endelse if (end_hour_high) beginhour_high <= 4'd0;endelse if (add_hour_high) beginhour_high <= hour_high + 1'd1;endelse if ((state == 2'b01)&&(!key_in[3])) beginhour_high <= adjust_time[23:20];endelse beginhour_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) beginif (!rst_n) beginflag_r <= 3'd0;endelse if ((state == 2'b01)) beginif (!key_in[1]) beginif (flag_r == 3'd6) beginflag_r <= 3'd1;endelse beginflag_r <= flag_r + 1'b1;endendelse beginflag_r <= flag_r;end endelse beginflag_r <= 3'd0;end
end
assign  flag = flag_r;
//****************************************************************
//调时主要模块,当不在调时状态时使得值一直和时钟保持相等,在调时状态时
//根据位置信号和按键信号来加减值
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsec_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];endelse if (state != 2'b01) beginsec_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];endelse if (state == 2'b01) beginif (flag_r == 3'd1) beginif (!key_in[2]) begin     //当在调时状态并且位置信号为1时按下按键2使得分钟个位加1,下放同理sec_low <= sec_low + 1'b1;endelse if (sec_low == 4'd10) beginsec_low <= 4'd0;endendelse if (flag_r == 3'd2) beginif (!key_in[2]) beginsec_high <= sec_high + 1'b1;endelse if (sec_high == 4'd6) beginsec_high <= 4'd0;endendelse if (flag_r == 3'd3) beginif (!key_in[2]) beginmine_low <= mine_low + 1'b1;endelse if (mine_low == 4'd10) beginmine_low <= 4'd0;endendelse if (flag_r == 3'd4) beginif (!key_in[2]) beginmine_high <= mine_high + 1'b1;endelse if (mine_high == 4'd6) beginmine_high <= 4'd0;endendelse if (flag_r == 3'd5) beginif (!key_in[2]) beginhour_low <= hour_low + 1'b1;endelse if ((hour_low == 4'd10)&&(hour_high <= 4'd1)) beginhour_low<= 4'd0;endelse if ((hour_low == 4'd4)&&(hour_high == 4'd2)) beginhour_low <= 4'd0;endendelse if (flag_r == 3'd6) beginif (!key_in[2]) beginhour_high <= hour_high + 1'b1;endelse if ((hour_high == 4'd2)&&(hour_low >=4'd4)) beginhour_high <= 4'd0;endelse if ((hour_high == 4'd3)&&(hour_low < 4'd4)) beginhour_high <= 4'd0;endendelse beginsec_low   <= sec_low  ;sec_high  <= sec_high ;mine_low  <= mine_low ;mine_high <= mine_high;hour_low  <= hour_low ;hour_high <= hour_high;endend
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) beginif (!rst_n) beginflag <= 0;endelse if (end_cnt_5s) beginflag <= 1'b0;endelse if (adjust_alarm === times&&times!= 0) beginflag <= 1'b1;endelse beginflag <= flag ;endend
//****************************************************************
//1s计时器
//****************************************************************always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt <= 26'd0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 26'd0;endelse begin cnt <= cnt + 1'b1;end endelse if (state != 2'b10) begincnt <= 26'd0;endelse begincnt <= 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)begincnt_5s <= 3'd0;end else if(add_cnt_5s)begin if(end_cnt_5s)begin cnt_5s <= 3'd0;endelse begin cnt_5s <= cnt_5s + 1'b1;end endelse if (state != 2'b10) begincnt_5s<= 3'd0;endelse begincnt_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) beginif (!rst_n) beginflag_alarm_r <= 3'd0;endelse if ((state == 2'b10)) beginif (!key_in[1]) beginif (flag_alarm_r == 3'd6) beginflag_alarm_r <= 3'd1;endelse beginflag_alarm_r <= flag_alarm_r + 1'b1;endendelse if (!key_in[3]) beginflag_alarm_r <= 3'd0;endelse beginflag_alarm_r <= flag_alarm_r;end endelse beginflag_alarm_r <= 3'd0;end
end
assign  flag_alarm = flag_alarm_r;
//****************************************************************
//是定闹钟的主要模块,当不在闹钟状态时使得值一直设定的值一样,在闹钟
//时根据位置信号和按键信号来加减值
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginsec_low   <= 4'd0;sec_high  <= 4'd0;mine_low  <= 4'd0;mine_high <= 4'd0;hour_low  <= 4'd0;hour_high <= 4'd0;endelse if (state == 2'b10) beginif (flag_alarm_r == 3'd1) beginif (!key_in[2]) beginsec_low <= sec_low + 1'b1;endelse if (sec_low == 4'd10) beginsec_low <= 4'd0;endendelse if (flag_alarm_r == 3'd2) beginif (!key_in[2]) beginsec_high <= sec_high + 1'b1;endelse if (sec_high == 4'd6) beginsec_high <= 4'd0;endendelse if (flag_alarm_r == 3'd3) beginif (!key_in[2]) beginmine_low <= mine_low + 1'b1;endelse if (mine_low == 4'd10) beginmine_low <= 4'd0;endendelse if (flag_alarm_r == 3'd4) beginif (!key_in[2]) beginmine_high <= mine_high + 1'b1;endelse if (mine_high == 4'd6) beginmine_high <= 4'd0;endendelse if (flag_alarm_r == 3'd5) beginif (!key_in[2]) beginhour_low <= hour_low + 1'b1;endelse if ((hour_low == 4'd10)&&(hour_high <= 4'd1)) beginhour_low<= 4'd0;endelse if ((hour_low == 4'd4)&&(hour_high == 4'd2)) beginhour_low <= 4'd0;endendelse if (flag_alarm_r == 3'd6) beginif (!key_in[2]) beginhour_high <= hour_high + 1'b1;endelse if ((hour_high == 4'd2)&&(hour_low >=4'd4)) beginhour_high <= 4'd0;endelse if ((hour_high == 4'd3)&&(hour_low < 4'd4)) beginhour_high <= 4'd0;endendelse beginsec_low   <= sec_low  ;sec_high  <= sec_high ;mine_low  <= mine_low ;mine_high <= mine_high;hour_low  <= hour_low ;hour_high <= hour_high;endend
endassign adjust_alarm = {hour_high ,hour_low,mine_high , mine_low , sec_high , sec_low} ;//****************************************************************
//闹钟判断和蜂鸣器模块
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginbeep <= 1'b1;endelse if ((adjust_alarm === times)&&flag_beep_r) begin//当时间达到并且使能为1时beep响beep <= 1'b0;endelse if (!flag_beep_r) begin//当时能为0时beep <= 1'b1;endelse beginbeep <= beep;end
end
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag_beep_r <= 1'b0;endelse if (end_cnt_5s) begin//当计时结束后使得使能自动归0停止闹钟flag_beep_r <= 1'b0;endelse if (!key_in[3]&&(state == 2'b10)) begin//当按下第四个按键时翻转用来控制开始和结束flag_beep_r <= ~flag_beep_r;endelse beginflag_beep_r <= flag_beep_r; end
end
//****************************************************************
//led显示
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginled_r <= 1'b0;endelse if (flag_beep_r == 1) begin//当使能为1即设定了闹钟led就亮否则不亮led_r <= 1'b1;endelse beginled_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)begincnt <= 10'd0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 10'd0;endelse 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)begincnt_500ms <= 25'd0;end else if(add_cnt_500ms)begin if(end_cnt_500ms)begin cnt_500ms <= 25'd0;endelse begin cnt_500ms <= cnt_500ms + 1'b1;end endelse begincnt_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) beginif (!rst_n) beginflash <= 1'b0;endelse if (end_cnt_500ms) begin//每500ms翻转一次flash <= ~flash;endelse if ((state != 2'b01)&&(state != 2'b10)) begin//当不在调时和闹钟状态归0flash <= 1'b0;endelse beginflash <=flash;end
end
//****************************************************************
//seg显示选择.根据状态选择数码管显示的值
//****************************************************************
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginnum <= 24'd0;endelse if (state == 2'b00) beginnum <=times;endelse if (state == 2'b01) beginnum <= adjust_time;endelse if (state == 2'b10) beginnum <= adjust_alarm;endelse if (state == 2'b11) beginnum <= adjust_clock;endelse  beginnum <= num;end
end
//****************************************************************
//驱动sel
//****************************************************************   
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginsel <= 6'b111_110;end else if(end_cnt)begin sel <= {sel[4:0],sel[5]};end else begin sel <= sel; end 
end
//****************************************************************
//位选赋值,当选择到哪一位哪一位进行频闪
//****************************************************************
always @(*) begincase (sel)6'b011111:begin seg_temp = (flash&&((flag==3'd1||(flag_alarm == 3'd1))))?5'd15 : num[3:0]         ; point_r = point[0];end6'b101111:begin seg_temp = (flash&&((flag==3'd2||(flag_alarm == 3'd2))))?5'd15 : num[7:4]         ; point_r = point[1];end6'b110111:begin seg_temp = (flash&&((flag==3'd3||(flag_alarm == 3'd3))))?5'd15 : num[11:8]        ; point_r = point[2];end6'b111011:begin seg_temp = (flash&&((flag==3'd4||(flag_alarm == 3'd4))))?5'd15 : num[15:12]       ; point_r = point[3];end6'b111101:begin seg_temp = (flash&&((flag==3'd5||(flag_alarm == 3'd5))))?5'd15 : num[19:16]       ; point_r = point[4];end6'b111110:begin seg_temp = (flash&&((flag==3'd6||(flag_alarm == 3'd6))))?5'd15 : num[23:20]       ; point_r = point[5];enddefault: seg_temp = 4'd0;endcase
end
//****************************************************************
//译码
//****************************************************************
always @(*) begincase (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) beginif (!rst_n) beginkey_r0 <= 4'b1111;key_r1 <= 4'b1111;endelse beginkey_r0 <= key_in;key_r1 <= key_r0;end
endassign 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) beginif (!rst_n) begincnt_20ms <= 20'd0;endelse if (nedge) begincnt_20ms <= 20'd0;endelse if (add_cnt) beginif (end_cnt) begincnt_20ms <= 20'd0;endelse begincnt_20ms <= cnt_20ms + 1'b1;endendelse begincnt_20ms <= 20'd0;end
endassign add_cnt = start;
assign end_cnt = add_cnt && (cnt_20ms == MAX20ms);//约束start
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginstart <= 1'b0;endelse if (nedge) beginstart <= 1'b1;endelse if (end_cnt) beginstart <= 1'b0;endelse beginstart <= start ;end
end//约束flag
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginflag <= 4'b1111;endelse if (nedge) beginflag <= 4'b1111;endelse if (end_cnt) beginflag <= key_r0;endelse beginflag <= 4'b1111 ;end
end
//脉冲信号
always @(posedge clk or negedge rst_n) beginif (!rst_n) beginkey_out_r <= 4'b1111;endelse if (!flag[0]) beginkey_out_r <= 4'b1110;endelse if (!flag[1]) beginkey_out_r <= 4'b1101;endelse if (!flag[2]) beginkey_out_r <= 4'b1011;endelse if (!flag[3]) beginkey_out_r <= 4'b0111;endelse beginkey_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
// endassign 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) beginif (!rst_n) beginflag_clock <= 1'b0;endelse if ((!key_in[1])&&(state == 2'b11)) beginflag_clock <= ~flag_clock;endelse if ((state != 2'b11)||(!key_in[2])) beginflag_clock <= 1'b0;endelse beginflag_clock <= flag_clock;end
end//****************************************************************
//100ms计数器
//****************************************************************
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt <= 19'd0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 19'd0;endelse begin cnt <= cnt + 1'b1;end endelse if ((state != 2'b11)||(!key_in[2])) begincnt <= 19'd0;endelse begincnt <= 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) beginif (!rst_n) beginms_low <= 4'd0;endelse if (add_cnt_ms_low) beginif (end_cnt_ms_low) beginms_low <= 4'd0;endelse beginms_low <= ms_low + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginms_low <= 4'd0;endelse beginms_low <= ms_low;end
endassign 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) beginif (!rst_n) beginms_high <= 4'd0;endelse if (add_cnt_ms_high) beginif (end_cnt_ms_high) beginms_high <= 4'd0;endelse beginms_high <= ms_high + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginms_high <= 4'd0;endelse beginms_high <= ms_high;end
endassign 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) beginif (!rst_n) begins_low <= 4'd0;endelse if (add_cnt_s_low) beginif (end_cnt_s_low) begins_low <= 4'd0;endelse begins_low <= s_low + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begins_low <= 4'd0;endelse begins_low <= s_low;end
endassign 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) beginif (!rst_n) begins_high <= 4'd0;endelse if (add_cnt_s_high) beginif (end_cnt_s_high) begins_high <= 4'd0;endelse begins_high <= s_high + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) begins_high <= 4'd0;endelse begins_high <= s_high;end
endassign 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) beginif (!rst_n) beginmine_low <= 4'd0;endelse if (add_cnt_mine_low) beginif (end_cnt_mine_low) beginmine_low <= 4'd0;endelse beginmine_low <= mine_low + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginmine_low <= 4'd0;endelse beginmine_low <= mine_low;end
endassign 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) beginif (!rst_n) beginmine_high <= 4'd0;endelse if (add_cnt_mine_high) beginif (end_cnt_mine_high) beginmine_high <= 4'd0;endelse beginmine_high <= mine_high + 1'd1;endendelse if ((state != 2'b11)||((state == 2'b11)&&(!key_in[2]))) beginmine_high <= 4'd0;endelse beginmine_high <= mine_high;end
endassign 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/1nsmodule 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进入闹钟状态#CYCLEkey_in = 4'b1111;#(CYCLE*20)key_in = 4'b1101;    //按下key1选择第一位#CYCLEkey_in = 4'b1111;#(CYCLE*20)key_in = 4'b1101;    //按下key1选择第二位#CYCLEkey_in = 4'b1111;#(CYCLE*20)repeat(5)beginkey_in = 4'b1011;//连续按下key2使得秒的个位+1使得计时50s#(CYCLE)key_in = 4'b1111;#(CYCLE*20);endkey_in = 4'b0111;//按下key3确定设定闹钟#(CYCLE)key_in = 4'b1111;#(CYCLE*10000)  //延迟10000个周期等待闹钟触发#(CYCLE*10000)$stop;endendmodule 

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

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

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

六,结果展示

上板验证

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

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

相关文章

17款奔驰S400升级原厂前排座椅通风系统,夏天必备的功能

通风座椅的主动通风功能可以迅速将座椅表面温度降至适宜程度&#xff0c;从而确保最佳座椅舒适性。该功能启用后&#xff0c;车内空气透过打孔皮饰座套被吸入座椅内部&#xff0c;持续时间为 8 分钟。然后&#xff0c;风扇会自动改变旋转方向&#xff0c;将更凉爽的环境空气从座…

拦截器——Interceptor及与过滤器区别

目录 spring中拦截器 过滤器跟拦截器的区别 HandlerInterceptor拦截器 拦截器工作原理 拦截器使用场景 定义拦截器 LoginInterceptor 注册拦截器 MethodInterceptor拦截器 方式一&#xff1a;继承 MethodInterceptor 方式二&#xff1a;基于注解的AspectJ方…

用于大型图像模型的 CNN 内核的最新内容

一、说明 由于OpenAI的ChatGPT的巨大成功引发了大语言模型的繁荣&#xff0c;许多人预见到大图像模型的下一个突破。在这个领域&#xff0c;可以提示视觉模型分析甚至生成图像和视频&#xff0c;其方式类似于我们目前提示 ChatGPT 的方式。 用于大型图像模型的最新深度学习方法…

基于自组织竞争网络的患者癌症发病预测(matlab代码)

1.案例背景 1.1自组织竞争网络概述 前面案例中讲述的都是在训练过程中采用有导师监督学习方式的神经网络模型。这种学习方式在训练过程中,需要预先给网络提供期望输出,根据期望输出来调整网络的权重,使得实际输出和期望输出尽可能地接近。但是在很多情况下,在人们认知的过程中…

第八篇: K8S Prometheus Operator实现Ceph集群企业微信机器人告警

Prometheus Operator实现Ceph集群企业微信告警 实现方案 我们的k8s集群与ceph集群是部署在不同的服务器上&#xff0c;因此实现方案如下&#xff1a; (1) ceph集群开启mgr内置的exporter服务&#xff0c;用于获取ceph集群的metrics (2) k8s集群通过 Service Endponit Ser…

【VALSE2023】0610 胡瀚《视觉自监督学习年度进展评述》

from&#xff1a; https://www.bilibili.com/video/BV1J44y1w79r 文章目录 自监督学习年度进展技术进展趋势一&#xff1a;掩码图像建模的改进技术进展二&#xff1a;发现掩码图像建模对**大模型**比较友好技术进展三&#xff1a;针对**小模型**的掩码图像建模训练技术进展四&a…

Unity Shader编辑器工具类ShaderUtil 常用函数和用法

Unity Shader编辑器工具类ShaderUtil 常用函数和用法 Unity的Shader编辑器工具类ShaderUtil提供了一系列函数&#xff0c;用于编译、导入和管理着色器。本文将介绍ShaderUtil类中的常用函数和用法。 编译和导入函数 CompileShader 函数签名&#xff1a;public static bool C…

web前端转正工作总结范文5篇

web前端转正工作总结&#xff08;篇1&#xff09; 来到__有限公司已经三个月了&#xff0c;目前的工作是前端开发&#xff0c;我是一名应届毕业生&#xff0c;之前没有过工作经验&#xff0c;在刚来到__这个大家庭的时候&#xff0c;我就被这里的工作气氛深深地吸引&#xff0…

Elastic的下载

文章目录 ElasticSearch的下载扩展1&#xff08;ElasticSearch 与 JDK 版本 适配&#xff09;扩展2&#xff08;访问 http://192.168.1.200:9200 没有显示信息&#xff09;扩展3&#xff08;免密登录&#xff09; ElasticSearch的下载 官方下载网址&#xff1a;https://www.el…

在 Ubuntu 上安装 Docker 桌面

Ubuntu 22.04 (LTS) 安装 Docker 桌面 要成功安装 Docker Desktop&#xff0c;您必须&#xff1a; 满足系统要求拥有 64 位版本的 Ubuntu Jammy Jellyfish 22.04 (LTS) 或 Ubuntu Impish Indri 21.10。对于非 Gnome 桌面环境&#xff0c;必须安装 gnome-terminal&#xff1a;…

数字孪生技术的实用价值体现在哪?

随着科技的不断进步&#xff0c;数字孪生技术已成为引领未来发展的重要驱动力。数字孪生是将现实世界与数字世界紧密结合的技术&#xff0c;通过创建虚拟的物理模型&#xff0c;实时模拟和分析真实世界中的物体和过程&#xff0c;让数字孪生在各个领域都展现出了巨大的潜力&…

nvm下载node导致npm报错无法使用

有个依赖库需要更新下node&#xff0c;用nvm下载后项目跑不起来了&#xff0c;npm -v 还报错 其实一开始是npm下载不来&#xff0c;然后换了淘宝镜像后还是报错 然后就只能手动下载下了 进入node.js官网 https://nodejs.org/en/download 下载后注意要安装在你nvm目录中&#x…

Dockerfile构建LNMP镜像

建立工作目录 [rootlocalhost ~]# mkdir lnmp [rootlocalhost ~]# cd lnmp/ 编写Dockerfile文件 [rootlocalhost lnmp]# vim Dockerfile [rootlocalhost lnmp]# ll 总用量 4 -rw-r--r--. 1 root root 774 8月 3 14:54 Dockerfile [rootlocalhost lnmp]# vim Dockerfile #基础…

【Spring Boot】(三)深入理解 Spring Boot 日志

文章目录 前言一、日志文件的作用二、Spring Boot 中的日志2.1 查看输出的日志信息2.2 日志格式二、Spring Boot 中的日志2.1 查看输出的日志信息2.2 日志格式 三、自定义日志输出3.1 日志框架3.2 日志对象的获取3.3 使用日志对象打印日志 四、日志级别4.1 日志级别的作用4.2 日…

人到中年不得已,保温杯里泡枸杞--送程序员

目录 一&#xff1a;你现在身体的体能状况如何&#xff1f;你有身体焦虑吗&#xff1f; 二&#xff1a;如何保持规律性运动&#xff1f; 三&#xff1a;你有哪些健康生活的好习惯&#xff1f; 大厂裁员&#xff0c;称35岁以后体能下滑&#xff0c;无法继续高效率地完成工作&…

Gof23设计模式之组合模式

1.定义 ​组合模式又名部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。这种类型的设计模式属于结构型模式&#xff0c;它创建了对象组的树形结构。 2.结构 组合模式主要包含三种…

无涯教程-Perl - endgrent函数

描述 此功能告诉系统您不再希望使用getgrent从groups文件中读取条目。 语法 以下是此函数的简单语法- endgrent返回值 此函数不返回任何值。 Perl 中的 endgrent函数 - 无涯教程网无涯教程网提供描述此功能告诉系统您不再希望使用getgrent从groups文件中读取条目。 语法以…

STM32——LED内容补充(寄存器点灯及反转的原理)

文章目录 点灯流程开时钟配置IO关灯操作灯反转宏定义最后给自己说 本篇文章使用的是STM32F103xC系列的芯片&#xff0c;四个led灯在PE2,PE3,PE4,PE5上连接 点灯流程 1.开时钟 2.配置IO口 &#xff08;1&#xff09;清零指定寄存器位 &#xff08;2&#xff09;设置模式为推挽输…

最新2024届【海康威视】内推码【GTK3B6】

最新2024届【海康威视】内推码【GTK3B6】 【内推码使用方法】 1.请学弟学妹们登录校招官网&#xff0c;选择岗位投递简历&#xff1b; 2.投递过程中填写内推码完成内推步骤&#xff0c;即可获得内推特权。 内推码&#xff1a;GTK3B6 内推码&#xff1a;GTK3B6 内推码&…

【广州华锐视点】海上石油钻井VR在线实训平台

随着科技的不断发展&#xff0c;VR元宇宙平台已经成为了越来越多领域的培训工具。在海上石油钻井实训中&#xff0c;VR元宇宙平台也能够发挥重要的作用&#xff0c;为学员提供更加真实、直观的培训体验。 首先&#xff0c;VR元宇宙平台可以模拟真实的海上钻井作业环境。通过VR眼…