- `timescale 1ns / 1ps
- //按键调试数码管显示,key1 归零,key2 +1。数值为0~9
- module a(
- input clk,
- input [1:0] key,
- output [7:0] dig,
- output [0:5] sel
- );
- //寄存器定义
- reg [19:0] delay; //延时20ms,判断按键
- reg [1:0] key_scan;//扫描20mS后按键
- reg [1:0] key_scan_r;//扫描按键
- reg [7:0] numb;//需要显示的初始值
- reg [3:0] ha; //选择数字
- initial begin ha = 4'd5;end
- initial begin
- numb <= 8'b0;
- key_scan <= 2'b11;
- key_scan_r <= 2'b11; //初值都为1,计算后结果与key_true初值相同,在开始时不会触发numb变化,才会显示初值5
- delay <= 20'd0;
- end
- //*************扫描按键**************
- //说明:分两个寄存器采样,一个使用时钟频率,一个使用时钟频率分频后的频率,既可看成一个为检测初始信号,另一个延时20mS做确认
- always @(posedge clk) //扫描20mS后的按键
- begin
- if (delay == 20'd999_999)//999_999
- begin
- delay <= 20'b0;
- key_scan <= key; //若计满20ms采样按键输入
- end
- else delay <= delay + 20'b1; //计数加一
- end
- always @(posedge clk) //扫描按键
- key_scan_r <= key;
- wire [1:0] key_true = (~key_scan[1:0]) & (key_scan_r[1:0]);//确认按键
- //*****被选择数字存入寄存器*******
- always @(ha)
- case (ha)
- 4'd0: numb <= 8'hc0;
- 4'd1: numb <= 8'hf9;
- 4'd2: numb <= 8'ha4;
- 4'd3: numb <= 8'hb0;
- 4'd4: numb <= 8'h99;
- 4'd5: numb <= 8'h92;
- 4'd6: numb <= 8'h82;
- 4'd7: numb <= 8'hf8;
- 4'd8: numb <= 8'h80;
- 4'd9: numb <= 8'h90;
- default: numb <= 8'hc0;
- endcase
-
- //***********按键选择数字*****************
- always @(posedge clk)
- begin
- if(key_true[0]) ha <= 4'b0000;
- if(key_true[1])
- begin
- if(ha < 4'd9)
- ha <= ha + 4'd1;
- else ha <= 4'd9;
- end
- end
- //*****取出当前显示数值(BCD译码)*********
- assign dig = numb;
- assign sel = 6'b1101_11;
- endmodule
复制代码
这是我的程序,下边的“BCD译码”还未写可以忽略,这个程序出现的问题是,逻辑看起来并没有任何问题,但烧进去后,按键并未使它正确+1。程序中设定是按到9就不再加了,但我按一次就会直接跳到9。我在二楼贴出别人的程序别人可以正常使用的程序并提出我的一些其他疑问。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- //按键控制数码管加减一
- //功能:通过两个按键key1和key2分别控制共阳带小数点的数码管加减一
- //调试环境:ISE 10.1;火龙刀实验板
- //本程序参考了 EDN助学—CPLD学习小组 ilove314 的练习例程
- //////////////////////////////////////////////////////////////////////////////////
- module a(clk,key1,key2,led_cs,led_db);
- input clk,key1,key2;
- output led_cs; //数码管的选择,本实例只用其中一个数码管,所以直接连续赋值assign led_cs=1'b1;
- output [7:0] led_db; //七段数码管,带小数点,共阳
- reg [7:0] led_dbr; //7段数码管寄存器
- reg [19:0] cnt;
- reg[3:0] num; //显示数值
- /*初始化,因为实验板上的复位键失灵,没有多余的按键了,所以取消复位初始化reset,改用initial*/
- initial begin num=4'd0;end
- initial begin cnt=20'h00000;end
- always [url=home.php?mod=space&uid=72445]@[/url] (posedge clk)
- cnt <= cnt+1'b1; //循环计数
- parameter seg0 = 8'hc0, //共阳七段数码管的值
- seg1 = 8'hf9,
- seg2 = 8'ha4,
- seg3 = 8'hb0,
- seg4 = 8'h99,
- seg5 = 8'h92,
- seg6 = 8'h82,
- seg7 = 8'hf8,
- seg8 = 8'h80,
- seg9 = 8'h90;
- always @ (num)
- case (num)
- 4'd0: led_dbr<= seg0;
- 4'd1: led_dbr<= seg1;
- 4'd2: led_dbr<= seg2;
- 4'd3: led_dbr<= seg3;
- 4'd4: led_dbr<= seg4;
- 4'd5: led_dbr<= seg5;
- 4'd6: led_dbr<= seg6;
- 4'd7: led_dbr<= seg7;
- 4'd8: led_dbr<= seg8;
- 4'd9: led_dbr<= seg9;
- default: ;
- endcase
-
-
- reg key1_flag,key2_flag,key1_flag_r,key2_flag_r;
- initial begin key1_flag=1'b0;key2_flag=1'b0;key1_flag_r=1'b0;key2_flag_r=1'b0;end //定义存储键值的寄存器,并初始化
- always @ (posedge clk) //如有按键按下,延时8'hfffff后,把键值赋予寄存器key1_flag和key2_flag
- if(cnt==20'hfffff)
- begin
- key1_flag<=key1;
- key2_flag<=key2;
- end
- always @ (posedge clk)
- begin
- key1_flag_r<=key1_flag;
- key2_flag_r<=key2_flag;
- end
- wire key1_f=(~key1_flag)&&key1_flag_r; //相当于wire key1_f; assign key1_f=(~key1_flag)&&key1_flag_r;
- wire key2_f=(~key2_flag)&&key2_flag_r;
- always @(posedge clk)
- begin
- if(key1_f)
- begin
- if(num<9) num<=num+4'd1; //按键key1一次,数码管加一
- else num<=9;
- end
-
- if(key2_f)
- begin
- if(num>0)
- num<=num-4'd1;//按键key2一次,数码管减一
- else num<=0;
- end
- end
- assign led_db=led_dbr; //数码管输出
- assign led_cs=1'b0;//数码管常亮
- endmodule
复制代码这是别人的程序我原封未动。在这个程序中可以看见,他的default后面是没有写东西的,若我的程序这么写,会出现“Latch xx has unsafe behavior”的警告。
PS:我的FPGA的数码管是共阳的,位选低电平有效,按键低电平有效。
直接加到9的问题应该是按键没有去抖所致
一周热门 更多>