实战项目——多功能电子时钟
一,项目要求
二,理论原理
通过按键来控制状态机的状态,在将状态值传送到各个模块进行驱动,在空闲状态下,数码管显示基础时钟,基础时钟是由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&×!= 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计时,当计时结束蜂鸣器拉高停止响,这里我也同样做了按键停止,但是效果差不多,就只展示计时停止
六,结果展示
上板验证
相关文章:

实战项目——多功能电子时钟
一,项目要求 二,理论原理 通过按键来控制状态机的状态,在将状态值传送到各个模块进行驱动,在空闲状态下,数码管显示基础时钟,基础时钟是由7个计数器组合而成,当在ADJUST状态下可以调整时间&…...
【es6】对象解构赋值
es6中对象解构赋值: 代码 let { foo: baz } { foo: rose, bar: jeck }; baz // "rose"let obj { first: tom, last: rose }; let { first: f, last: l } obj; f // tom l // roselet { foo: baz } { foo: rose, bar: jeck }中的foo:baz部分ÿ…...
腾讯云服务器CVM标准型S6详细介绍_性能测评
腾讯云服务器CVM标准型S6实例是最新一代的标准型实例,CPU采用Intel Xeon Ice Lake处理器,主频2.7GHz,睿频3.3GHz,内存采用最新 DDR4,默认网络优化,最高内网收发能力达1900万pps,最高内网带宽可支…...

时间序列预测任务下探索深度学习参数对模型预测性能的影响
时间序列相关的项目在我之前的很多博文中都有涉及,覆盖的数据领域也是比较广泛的,很多任务或者是项目中往往是搭建出来指定的模型之后就基本完成任务了,比较少去通过实验的维度去探索分析不同参数对模型性能的影响,这两天正好有时…...

React Dva项目 简单引入models中的所有JS文件
我们前面接触的 Dva项目 models目录下的文件还要一个一个引入 其实体验并不是很好 而且如果项目很大那就比较麻烦了 我们可以在 models 下创建一个 index.js 文件 编写代码如下 const context require.context("./", false, /\.js$/); export default context.key…...

ROS入门-第 1 章 ROS概述与环境搭建
目录 第 1 章 ROS概述与环境搭建 1.1 ROS简介 1.1.1 ROS概念 1.1.2 ROS设计目标 1.1.3 ROS发展历程 1.3 ROS快速体验 1.3.1 HelloWorld实现简介 1.3.2 HelloWorld(C版) 步骤 1:创建工作空间 步骤 2:创建发布者节点 步骤…...

spring之AOP简单介绍
1.AOP的概念 AOP,Aspect Oriented Programming,面向切面编程,是对面向对象编程OOP的升华。OOP是纵向对一个 事物的抽象,一个对象包括静态的属性信息,包括动态的方法信息等。而AOP是横向的对不同事物的抽象,…...
使用Spark ALS模型 + Faiss向量检索实现用户扩量实例
1、通过ALS模型实现用户/商品Embedding的效果,获得其向量表示 准备训练数据, M (U , I, R) 即 用户集U、商品集I、及评分数据R。 (1)商品集I的选择:可以根据业务目标确定商品候选集,比如TopK热度召回、或…...

Jmeter入门之digest函数 jmeter字符串连接与登录串加密应用
登录请求中加密串是由多个子串连接,再加密之后传输。 参数连接:${var1}${var2}${var3} 加密函数:__digest (函数助手里如果没有该函数,请下载最新版本的jmeter5.0) 函数助手:Options > …...

uni-app实现图片上传功能
效果 代码 <uni-forms-item name"ViolationImg" label"三违照片 :"><uni-file-picker ref"image" limit"1" title"" fileMediatype"image" :listStyles"listStyles" :value"filePathsL…...

golang协程池库tunny实践
前言 线程池大家都听过,其主要解决的是线程频繁创建销毁带来的性能影响,控制线程数量。 go协程理论上支持百万协程并发,协程创建调度的消耗极低,但毕竟也是消耗对吧。 而且协程池可以做一些额外的功能,比如限制并发&…...

Android性能优化—数据结构优化
优化数据结构是提高Android应用性能的重要一环。在Android开发中,ArrayList、LinkedList和HashMap等常用的数据结构的正确使用对APP性能的提升有着重大的影响。 一、ArrayList ArrayList内部使用的是数组,默认大小10,当数组长度不足时&…...
STL模板——vector详解
一、vector对象的定义和初始化方式 vector 中的数据类型 T 可以代表任何数据类型,如 int、string、class、vector(构建多维数组) 等,就像一个可以放下任何东西的容器,因此 vector 也常被称作容器。字符串类型 string …...

国际顶级学术会议ISSTA召开,中山大学与微众银行联合发表区块链最新研究成果
美国当地时间7月17日,软件工程领域顶级会议ISSTA 2023在西雅图正式召开。ISSTA (The 32nd ACM SIGSOFT International Symposium on Software Testing and Analysis )是软件测试与分析方面最著名的国际会议之一,也是中国计算机学会…...
Android开发从0开始(图形与按钮)
Drawable: drawable是抽象类。包括图片,色块,画板,背景。 drawable-ldpi 存放低分辨率图片。drawable-hdpi 高分辨率。drawable-xxhdpi 超高分辨率。 Android:src”drawable/image” 即可使用 Shape: 形状图形。圆角,矩形等常见几…...

Git入门到精通——保姆级教程(涵盖GitHub、Gitee、GitLab)
文章目录 前言一、Git1.Git-概述1.1.Git-概述-版本控制介绍1.2.Git-概述-分布式版本控制VS集中式版本控制1.3.Git-概述-代码托管中心1.4.Git-概述-安装和客户端的使用 2.Git-命令(常用命令)2.1.Git-命令-设置用户签名2.2.Git-命令-初始化本地库2.3.Git-命令-查看本地库状态2.4.…...
题解 | #J.Permutation and Primes# 2023牛客暑期多校8
J.Permutation and Primes 构造 题目大意 给定一个正整数 n n n ,构造一个 n n n 的排列,使得每对相邻元素的和或差的绝对值为一奇素数 解题思路 两个数的和或差是奇数,那么它们的奇偶性一定是不同的,因此所求排列中&#…...

用vim打开后中文乱码怎么办
Vim中打开文件乱码主要是文件编码问题。用户可以参考如下解决方法。 1、用vim打开.vimrc配置文件 vim ~/.vimrc**注意:**如果用户根目录下没有.vimrc文件就把/etc/vim/vimrc文件复制过来直接用 cp /etc/vim/vimrc ~/.vimrc2、在.vimrc中加入如下内容 set termen…...

自然语言处理: 第六章Transformer- 现代大模型的基石
理论基础 Transformer(来自2017年google发表的Attention Is All You Need (arxiv.org) ),接上面一篇attention之后,transformer是基于自注意力基础上引申出来的结构,其主要解决了seq2seq的两个问题: 考虑了原序列和目…...
01-Hadoop集群部署(普通用户)
Hadoop集群部署(普通用户) 环境准备 1)准备3台客户机(关闭防火墙、静态IP、主机名称) 如果这一步已经配置过了,可以忽略 # 1 关闭防火墙 systemctl stop firewalld.service # 关闭当前防火墙 systemctl…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

【JVM】- 内存结构
引言 JVM:Java Virtual Machine 定义:Java虚拟机,Java二进制字节码的运行环境好处: 一次编写,到处运行自动内存管理,垃圾回收的功能数组下标越界检查(会抛异常,不会覆盖到其他代码…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...

Unity VR/MR开发-VR开发与传统3D开发的差异
视频讲解链接:【XR马斯维】VR/MR开发与传统3D开发的差异【UnityVR/MR开发教程--入门】_哔哩哔哩_bilibili...