zoukankan      html  css  js  c++  java
  • 基于verilog——长短单击双击按键识别(改版)

      看着之前编写的,感觉有点问题。首先状态机格式就有点不对头,改了下,再加上了单击和双击的辨别。感觉这次好多了。

      不过还没完,还有个功能在研究中。。。看看怎么和NIOS II连接起来,做成一个完整的项目。

    module key(clk,reset,key_in,STOP_RUN,UPDOWN,RST,CONFIG);

    input clk;
    input reset;
    input key_in;
    output reg RST; //复位信号RST ,高电平有效
    output reg UPDOWN; //车行方向指示,为0是去行,为1时是回行
    output reg STOP_RUN; //停车态或行车态, 0停车态 1行车态
    output reg CONFIG; //CONFIG=1,表示进入设置状态



    reg [2:0] STATE; //状态

    parameter S0=3'b000,
    S1=3'b001,
    S2=3'b010,
    S3=3'b011,
    S4=3'b100,
    S5=3'b101,
    S6=3'b110,
    S7=3'b111; //状态机编码


    //**********************************************
    reg[19:0] cnt; //分频计数器

    always@(posedge clk or negedge reset)
    begin
    if(!reset)
    cnt<=20'd0;
    else if(cnt==20'd5_000)
    cnt<=20'd0; //计数50_000个时钟
    else
    cnt<=cnt+20'd1;
    end


    //**********************************************
    reg [9:0] count_d;
    reg [9:0] count; //
    //**********************************************
    always@(posedge clk or negedge reset)
    begin
    if(!reset)
    begin
    STATE<=S0;
    STOP_RUN <= 1'b0; //停车态
    UPDOWN <= 1'b0;
    RST <= 1'b0;
    CONFIG <= 1'b0;
    count_d <= 1'b0;
    count <= 1'b0;

    end
    else if(cnt==20'd4_999) //10ms扫描一次
    begin
    case(STATE)
    //----
    S0: //判别是否有按键按下
    begin
    if(key_in==0)
    STATE<=S1;
    else
    begin
    count <= 10'd0;
    //STATE<=S0;
    //STOP_RUN <= 1'b0;
    RST <= 1'b0;
    end
    end
    //----
    S1: //判别短单击
    begin
    if(key_in==0)
    begin
    if(count>=10'd210) //按键按下的时间超过2.1s,跳转下个状态
    STATE<=S2;
    else //
    count <= count + 10'd1;
    end
    else
    begin
    if(count>=10'd3) //30ms,防抖
    begin
    count <= 10'd0;
    STATE<=S5;
    end
    else //按键有按下,但时间太短,不允响应,跳转S0
    STATE<=S0;
    end
    end
    //----
    S2: //复位
    begin
    if(key_in==0)
    begin
    if(count>=10'd400)
    STATE<=S3;//按键按下的时间超过4s,跳转下个状态
    else
    count <= count + 10'd1;
    end

    else
    begin
    if(count>=10'd220) //大于等于2.2s 产生复位信号
    begin
    RST <= 1;
    count <= 10'd0;
    STATE<=S0;
    end
    else //按键有按下,但时间不足3s,不允响应,跳转S0
    STATE<=S0;
    end
    end
    //----
    S3: //设置指示
    begin
    if(key_in==0)
    begin
    if(count>=10'd800)
    STATE<=S4; //按键按下的时间超过8s,跳转下个状态
    else
    count <= count + 10'd1;
    end
    else
    begin
    if(count>=10'd420) //大于等于4.2s CONFIG置位
    begin
    CONFIG <= ~CONFIG;
    count <= 10'd0;
    STATE<=S0;
    end
    else //按键有按下,但时间不足5s,不允响应,跳转S0
    STATE<=S0;
    end
    end
    //----
    S4: //按键按下超过8s一直没放开
    begin
    if(key_in==0) //按键一直没有释放,一直处于S4
    STATE <= S4;
    else //按键释放,跳转S0
    STATE <= S0;
    end
    //----
    S5: //判别一次按键后短时间内是否有第二次按键
    begin
    if(key_in)
    begin
    if(count_d>=50)//两次按键如果大于0.5s ,则不予响应,跳转S6--STOP_RUN
    begin
    count_d <= 10'd0;
    STATE<=S6;
    end
    else
    count_d <= count_d + 10'd1;
    end
    else //两次按键如果小于0.5s,表明有双击,跳转S7
    STATE<=S7;
    end
    //----
    S6: //单击 输出STOP_RUN
    begin
    if(count_d==0)
    begin
    STOP_RUN <= ~STOP_RUN;
    STATE <= S0;
    end
    end
    //----
    S7: //双击 输出UPDOWN
    begin
    if(key_in)
    begin
    if(count_d<=49 && count_d>=2)
    begin
    UPDOWN <= ~UPDOWN;
    STATE <= S0;
    count_d <= 10'd0;
    end
    else //两次按键如果小于20ms ,表明有抖动,重新跳回S5
    STATE<=S5;
    end
    end
    //----
    default:
    STATE <= S0;
    //----
    endcase
    end

    else
    ;
    end

    //******************************************************************
    endmodule
  • 相关阅读:
    【开卷故意】JAVA正則表達式模版
    CSS控制显示超出部分,用省略号显示
    1星《微信软文营销实战技巧》:标题党,作者没有实战经验
    3星|《强势谈判》:有趣的绑匪谈判故事
    3星|《赢者的诅咒》:新晋诺奖得主92年作品,博弈论在拍卖、薪酬、股市、彩票、赛马、汇市等领域的应用,偏专业
    4星|《OKR实践指南》:老司机经验谈
    3星|《华为管理变革》:华为有史以来为了变革而开展的项目的概述。
    3星|《信号》:全球经济的坏消息
    2星|《麦肯锡图表工作法》:用图表做商业分析的入门演示
    2星|《麦肯锡与贝恩的团队管理智慧》:从投入、产出两个维度把下属分到4个象限
  • 原文地址:https://www.cnblogs.com/xuanxiaochen/p/2366625.html
Copyright © 2011-2022 走看看