TA的每日心情 | 慵懒 2017-2-27 03:33 |
---|
签到天数: 1 天 连续签到: 1 天 [LV.1]初来乍到
|
刚开始系统学习FPGA,写了一个带按键消抖的按键数码管计数器,但是有一个问题,复位以后数码管显示的不是0,是1,有点不理解。
贴代码:
`timescale 1ns / 1ps
module prj_keyseg
(
//输入端口
clk,rst_n,key,
//输出端口
SEG_DATA,SEG_EN
);
//---------------------------------------------------------------------------
//-- 外部端口声明
//---------------------------------------------------------------------------
input clk; //时钟的端口,开发板用的50MHz晶振
input rst_n; //复位的端口,低电平复位
input key; //对应开发板上的key
output SEG_EN; //数码管使能端口
output [6:0]SEG_DATA; //数码管数据端口(查看管脚分配文档或者原理图)
//--------------------------------------------------------------------------
//----按键消抖程序
//--------------------------------------------------------------------------
reg key_rst;
always @(posedge clk or negedge rst_n)
if (!rst_n) key_rst <= 1'b1;
else key_rst <= key;
reg key_rst_r;
always @ ( posedge clk or negedge rst_n )
if (!rst_n) key_rst_r <= 1'b1;
else key_rst_r <= key_rst;
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire key_an = key_rst_r & ( ~key_rst);
//---------------------------------------------------------------------------
reg[19:0] cnt; //计数寄存器
always @ (posedge clk or negedge rst_n)
if (!rst_n) cnt <= 20'd0; //异步复位
else if(key_an) cnt <=20'd0;
else cnt <= cnt + 1'b1;
reg low_sw;
always @(posedge clk or negedge rst_n)
if (!rst_n) low_sw <= 1'b1;
else if (cnt == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中 cnt == 20'hfffff
low_sw <= key;
//---------------------------------------------------------------------------
reg low_sw_r;
always @ ( posedge clk or negedge rst_n )
if (!rst_n) low_sw_r <= 1'b1;
else low_sw_r <= low_sw;
//当寄存器low_sw由1变为0时,seg_ctrl的值变为高,维持一个时钟周期
wire seg_ctrl = low_sw_r & ( ~low_sw);
reg[3:0] num; //显示数值
always @ (posedge clk or negedge rst_n)
if(!rst_n) num <= 4'h0; //复位数字清零
else if(seg_ctrl)
begin
if(num<4'h9) num<=num+1'd1; //按键按一次,数码管加一
else num<=4'h0;
end
//-------------------------------------------------------------------------------
/* 共阴极 :不带小数点
;0, 1, 2, 3, 4, 5, 6, 7,
db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h
;8, 9, a, b, c, d, e, f , 灭
db 7fh,6fh,77h,7ch,39h,5eh,79h,71h,00h*/
parameter seg0 = 7'h3f,
seg1 = 7'h06,
seg2 = 7'h5b,
seg3 = 7'h4f,
seg4 = 7'h66,
seg5 = 7'h6d,
seg6 = 7'h7d,
seg7 = 7'h07,
seg8 = 7'h7f,
seg9 = 7'h6f;
reg[6:0] SEG_DATAR; //7段数码管(不包括小数点)
always @ (num)
case (num) //NUM值显示在两个数码管上
4'h0: SEG_DATAR <= seg0;
4'h1: SEG_DATAR <= seg1;
4'h2: SEG_DATAR <= seg2;
4'h3: SEG_DATAR <= seg3;
4'h4: SEG_DATAR <= seg4;
4'h5: SEG_DATAR <= seg5;
4'h6: SEG_DATAR <= seg6;
4'h7: SEG_DATAR <= seg7;
4'h8: SEG_DATAR <= seg8;
4'h9: SEG_DATAR <= seg9;
default: ;
endcase
assign SEG_DATA = SEG_DATAR;
assign SEG_EN = 1'b0; //数码管常开
endmodule
|
|