|
4*4矩阵键盘(未消抖):
module Matrix_keyboard(clk,in_s,out_s,num);
//定义模块端口信息
input clk;
input [3:0] in_s;
output [3:0] out_s;
output [4:0] num;
//定义输出信号类型及局部变量
reg [4:0] num;
reg [1:0] cnt = 0;
reg [1:0] tmp = 0;
reg [3:0] o_ut_st = 0;
wire [7:0] dsample;
//将扫描输出和输入信号级联,得到矩阵扫描结果
assign dsample = {o_ut_st, in_s};
assign out_s = o_ut_st;
//产生按钮矩阵的列扫描信号
always @(posedge clk)
begin
cnt <= cnt + 1'b1;
case (cnt)
2'b00: o_ut_st <= 4'b1000;
2'b01: o_ut_st <= 4'b0100;
2'b10: o_ut_st <= 4'b0010;
2'b11: o_ut_st <= 4'b0001;
endcase
end
//根据按钮的列扫描信号和行输入信号判断按钮是否被按下
always @(posedge clk)
begin
//如果无按钮按下,定义num=16为无效状态
if (in_s == 4'b0000)
begin
if (tmp == 3)
begin
num <= 16; //无按键输入,输出16
tmp <= 0;
end
else
begin
num <= num;
tmp <= tmp + 1'b1; //扫描周期,3个时钟周期
end
end
else
begin
tmp <= 0;
case (dsample)
//第1列扫描结果
8'b1000_0001: num <= 0;
8'b1000_0010: num <= 1;
8'b1000_0100: num <= 2;
8'b1000_1000: num <= 3;
//第2列扫描结果
8'b0100_0001: num <= 4;
8'b0100_0010: num <= 5;
8'b0100_0100: num <= 6;
8'b0100_1000: num <= 7;
//第3列扫描结果
8'b0010_0001: num <= 8;
8'b0010_0010: num <= 9;
8'b0010_0100: num <= 10;
8'b0010_1000: num <= 11;
//第4列扫描结果
8'b0001_0001: num <= 12;
8'b0001_0010: num <= 13;
8'b0001_0100: num <= 14;
8'b0001_1000: num <= 15;
endcase
end
end
endmodule
独立按键消抖程序:
module Btn_without_shake(Clk_50MHz,PB_UP,PB_Out,count_sel);
//定义模块端口信息
input Clk_50MHz; //模块时钟50MHz
input PB_UP; //按钮输入
output PB_Out; //去抖后按钮输出
output [1:0] count_sel; //计数器输出
//定义输出信号类型及局部变量
reg [19:0] count_high = 0; //按钮输入高电平计数器
reg [19:0] count_low = 0; //按钮输入低电平计数器
reg PB_reg = 0;
reg [1:0] count_sel_reg = 0;
//输出赋值
assign PB_Out = PB_reg;
assign count_sel = count_sel_reg;
//对输入进行采样,计数
always @(posedge Clk_50MHz)
if(PB_UP == 1'b0)
count_low <= count_low + 1'b1;
else
count_low <= 20'h0_0000;
always @(posedge Clk_50MHz)
if(PB_UP == 1'b1)
count_high <= count_high + 1'b1;
else
count_high <= 20'h0_0000;
//防抖输出
always @(posedge Clk_50MHz)
if(count_high == 20'h7_FFFF) //判断高电平信号是否符合输出条件10ms
PB_reg <= 1'b1; //如果符合条件,则防抖输出高电平
else
if(count_low == 20'h7_FFFF) //判断低电平信号是否符合输出条件10ms
PB_reg <= 1'b0; //如果符合条件,则防抖输出低电平
else
PB_reg <= PB_reg;
//使用去抖输出PB_reg控制count_sel计数
always @(posedge PB_reg)
count_sel_reg <= count_sel_reg + 1'b1;
endmodule
初学,参考书上的《Verilog HDL程序设计与实践》,准备用状态机做一下矩阵键盘,恩,坛子里也有,不过还是自己尝试一下,坛里老牛很多呀! |
阿莫论坛20周年了!感谢大家的支持与爱护!!
该献的血还是要献的。你不献他不献。难道让我去献? --- 出自坛友:lovejp1981
|