一个简单的数码管按键实验,预期效果是两个按键,按下一个数码管数字加1,按下另一个减一。实际效果是按下按键,数字乱跳,检查程序逻辑没有问题(自认为),请高手看看,是不是时间上出了问题。
下面是程序:
module digit_sw(clk,rst,sw1,sw2,data,data_en,led1);
input clk,rst;
input sw1,sw2;
output [7:0]data;//段选
output [3:0]data_en;//位选
output led1;
reg light;
reg [1:0]key;
reg [1:0]key_r;
always @(posedge clk or negedge rst)
if(!rst) key <= 2'b00;
else key <= {sw1,sw2};
always @(posedge clk or negedge rst)
if(!rst) key_r <= 2'b00;
else key_r <= key;
wire key_en = key_r & (~key);//脉冲边沿检测消痘
reg [19:0]cnt_key;
always @(posedge clk or negedge rst)
if(!rst) cnt_key <= 20'b0;
else if(key_en) cnt_key <= 20'b0;
else cnt_key <= cnt_key +1'b1;
reg [1:0]get;
reg [1:0]get_n;
always @(posedge clk or negedge rst)
if(!rst) get <= 2'b0;
else if(cnt_key == 20'hfffff) get <= {sw1,sw2};//得到按键值
always @(posedge clk or negedge rst)
if(!rst) get_n <= 2'b0;
else if(cnt_key == 20'h00fff)get_n <= get; //不加延时的话,可能会出现按键不能够识别的问题,所以一定要加延时
wire [1:0]key_con = get & (~get_n); //得到按键值
/*
always @ (posedge clk or negedge rst) //点灯程序,sw1关,sw2开
case(key_con)
2'b01:light <= 1'b1;
2'b10:light <= 1'b0;
default: ;
endcase
*/
reg [7:0]date;
reg [3:0]date_en;
reg [3:0]num;
always @(posedge clk) // 估计是时序的问题,num加(减)1的时候,并不能够在数码管上显示,而是按键,出现数字乱跳。
case(key_con)
2'b01:num <= 4'd6;//num + 1'b1;//
2'b10:num <= 4'd8;//num - 1'b1;//
default: ;
endcase
always @(num)
case(num)
4'd0:date <= 8'h03;
4'd1:date <= 8'h9f;
4'd2:date <= 8'h25;
4'd3:date <= 8'h0d;
4'd4:date <= 8'h99;
4'd5:date <= 8'h49;
4'd6:date <= 8'h41;
4'd7:date <= 8'h1f;
4'd8:date <= 8'h01;
4'd9:date <= 8'h09;
default: ;
endcase
assign led1 = light;//这个是为了验证按键是否有用,
开发板上证明是可有的
assign data = date;
assign data_en = 4'b1110;
endmodule