原理
数码管原理
并且该数码管是共阳极,所以段选低电平有效,片选低电平有效
段选共用8个引脚
实现
思路:
分三个模块实现:
1)按键消抖 :按键消抖
2)计数器模块:产生需要的时钟信号数据
3)数码管驱动:将输入的数据转换为段选、片选信号
1)按键消抖:
这里按键数量用参数代替,增加可重用性
用同步打拍方式检测下降沿
用计数器自检测到下降沿开始计数20ms
输出信号为计数器计数完成后输入取反的值
module key_debounce #(parameter KEY_W = 3,TIME_20MS = 1000_000)(
input clk ,
input rst_n ,
input [KEY_W-1:0] key_in ,
output reg [KEY_W-1:0] key_out //检测到按下,输出一个周期的高脉冲,其他时刻为0
);
//信号定义
reg [19:0] cnt ;
wire add_cnt ;
wire end_cnt ;
reg add_flag;
reg [KEY_W-1:0] key_r0 ;//同步按键输入
reg [KEY_W-1:0] key_r1 ;//打拍
wire [KEY_W-1:0] nedge ;//检测下降沿
//计数器 检测到下降沿的时候,开启计数器延时20ms
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 0;
end
else if(add_cnt)begin
if(end_cnt)
cnt <= 0;
else
cnt <= cnt + 1'b1;
end
end
assign add_cnt = add_flag;
assign end_cnt = add_cnt && cnt == TIME_20MS-1;
//检测到下降沿的时候,拉高计数器计数使能信号,延时结束时,再拉低使能信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
add_flag <= 1'b0;
end
else if(nedge)begin
add_flag <= 1'b1;
end
else if(end_cnt)begin
add_flag <= 1'b0;
end
end
//同步按键输入,并打一拍,以检测下降沿
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
key_r0 <= {
KEY_W{
1'b1}};
key_r1 <= {KEY_W{1'b1}};
end
else begin
key_r0 <= key_in;//同步
key_r1 <= key_r0;//打拍
end
end
assign nedge = ~key_r0 & key_r1;
//延时20ms结束的时钟周期,输出按键的状态,若按下输出一个周期的高脉冲,否则输出0
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
key_out <= 0;
end
else begin
key_out <= end_cnt?~key_r1:0;
end
end
endmodule
2)计数器模块
定义了6个计数器分别代表每位数码管的显示数据
key[0] 作为设置键,按键信号有效,则可以进行设置操作
key[1] 作为选择键,用计数器记录当前选择项,默认为m个位
key[2] 作为+键,按一下当前项+1
除了正常产生时间数据的计数器,在+1条件中添加了按键设置,即当key[0]有效,key[2]拉高,当前选择项+1
最后将产生数据组合在一起形成输出数据,每4位代表一个数码管的数据
module count(
input clk ,
input rst_n ,
input [2:0] key ,
output [23:0