查看: 135|回复: 0

[原创] 锆石A4学习之带按键消抖的按键数码管计数器

[复制链接]

9

主题

0

好友

138

积分

童生

Rank: 2

  • TA的每日心情
    开心
    2016-8-26 16:22
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2016-8-28 11:16:06 |显示全部楼层
    本人菜鸟,刚开始系统学习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




    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    站长推荐上一条 /6 下一条


    手机版|爱板网 |网站地图  

    GMT+8, 2016-12-6 22:10 , Processed in 0.213447 second(s), 9 queries , Memcache On.

    苏公网安备 32059002001056号

    Powered by Discuz!

    回顶部