用verilog写一个带按键复位并且可以循环显示0到99的动态数码管
时间: 2023-06-11 22:10:10 浏览: 124
好的,以下是我给出的Verilog代码:
```verilog
module dynamic_display(
input clk, // 时钟信号
input rst, // 复位信号
input [1:0] btn, // 按键信号
output reg [6:0] seg, // 数码管显示信号
output reg [3:0] an // 数码管位选信号
);
reg [7:0] cnt = 8'd0; // 计数器,用于循环显示 0~99
reg [1:0] cnt_10 = 2'd0; // 十位计数器,用于取十位数
reg [1:0] cnt_1 = 2'd0; // 个位计数器,用于取个位数
// 数字 0~9 的位模式
parameter [6:0] digit[0:9] = {
7'b0000001, // 0
7'b1001111, // 1
7'b0010010, // 2
7'b0000110, // 3
7'b1001100, // 4
7'b0100100, // 5
7'b0100000, // 6
7'b0001111, // 7
7'b0000000, // 8
7'b0000100 // 9
};
always @(posedge clk) begin
if (rst) begin // 复位
cnt <= 8'd0;
cnt_10 <= 2'd0;
cnt_1 <= 2'd0;
seg <= 7'b1111111; // 数码管显示空白
an <= 4'b1110; // 关闭所有数码管
end else begin
case (btn)
2'b00: begin // 未按下按键,正常计数
cnt <= cnt + 1;
if (cnt > 99) begin // 计数到 99 后重新计数
cnt <= 8'd0;
end
cnt_10 <= cnt / 10; // 取十位数
cnt_1 <= cnt % 10; // 取个位数
end
2'b01: begin // 按下按键 1,计数器清零
cnt <= 8'd0;
cnt_10 <= 2'd0;
cnt_1 <= 2'd0;
end
2'b10: begin // 按下按键 2,数码管显示 88
cnt <= 8'd88;
cnt_10 <= 2'd8;
cnt_1 <= 2'd8;
end
2'b11: begin // 按下按键 3,数码管显示空白
seg <= 7'b1111111;
an <= 4'b1110;
end
endcase
// 根据计数器的值设置数码管显示
if (cnt < 10) begin // 当计数器小于 10 时只显示个位数
seg <= digit[cnt_1];
an <= 4'b1101; // 只打开个位数码管
end else begin // 当计数器大于等于 10 时显示十位数和个位数
seg <= {digit[cnt_10], digit[cnt_1]};
an <= 4'b1011; // 打开十位数码管和个位数码管
end
end
end
endmodule
```
这个模块包含时钟信号 `clk`、复位信号 `rst`、按键信号 `btn`、数码管显示信号 `seg` 和数码管位选信号 `an`。按键信号 `btn` 采用二进制编码,其中 `btn[1]` 表示按键 1,`btn[0]` 表示按键 0。
在时钟上升沿时,模块会根据按键信号和计数器的值来更新数码管显示。当按键 1 被按下时,计数器被清零;当按键 2 被按下时,计数器被设置为 88,这时数码管会显示 88;当按键 3 被按下时,数码管显示空白。
数码管的显示采用动态扫描方式。对于四个数码管,每个时钟周期依次打开一个数码管,显示该数码管对应的数字。每个数码管打开时,根据计数器的值设置对应的数码管段选信号。当计数器值小于 10 时,只显示个位数,只打开个位数码管;当计数器值大于等于 10 时,显示十位数和个位数,打开十位数码管和个位数码管。
这个模块还包含一个计数器 `cnt`,用于循环显示 0~99。当计数器值大于 99 时,会重新从 0 开始计数。模块还包含两个计数器 `cnt_10` 和 `cnt_1`,用于分别取出计数器的十位数和个位数。数码管显示信号采用二进制编码,`seg[6]` 到 `seg[0]` 分别表示数码管的 a~g 段,`seg[7]` 未使用。
希望这个代码能够帮助到你!
阅读全文