zoukankan      html  css  js  c++  java
  • 按键使用方法(二)------verilog

    这里我们要验证一键两用的情况:点击与长击,单击与双击

      代码:

        /********************************Copyright**************************************                           
        **----------------------------File information--------------------------
        ** File name  :key_function_2.v  
        ** CreateDate :2015.03
        ** Funtions   :按键的用法(二):点击和长击,单击和双击
        ** Operate on :M5C06N3L114C7
        ** Copyright  :All rights reserved. 
        ** Version    :V1.0
        **---------------------------Modify the file information----------------
        ** Modified by   :
        ** Modified data :        
        ** Modify Content:
        *******************************************************************************/
         
    001     module  key_function_2  (
    002                                         clk,
    003                                         rst_n,
    004                       
    005                                         key_4,
    006                                         key_5,
    007                                         
    008                                         led_d41,
    009                                         led_d42,
    010                                         led_d51,
    011                                         led_d52
    012                                         
    013                                             );
    014     input          clk;
    015     input          rst_n;
    016     
    017     input          key_4;                 //按键的点击与长击:按下按键后,2S内松开按键则为点击,2s后松开按键为长击,默认未按下为高。
    018     input          key_5;                /*按键的单击和双击,完成第一次按键后100ms之内第二次按下按键则为双击,否则为单击    */  
    019     
    020     output         led_d41;
    021     output         led_d42;
    022     output         led_d51;
    023     output         led_d52;
    024     
    025     //---------------------------
    026     //定时2s
    027     reg              cnt_en;
    028     localparam  t_1s = 25'd23999999;        /* //实际使用 */  
    029    // localparam  t_1s = 25'd239;           /* //测试使用 */
    030        
    031     localparam  t_2s = 2'd2;
    032     reg      [24:0]      cnt;
    033     always @(posedge clk or negedge rst_n)
    034     begin
    035      if(!rst_n)
    036       begin
    037            cnt <= 0;
    038        end
    039      else if(cnt_en)
    040        begin
    041           if(cnt == t_1s)
    042                     cnt <= 0;
    043                else 
    044                    cnt <= cnt + 1;
    045        end
    046       else
    047              cnt <= 0;    
    048      end
    049     
    050     reg     [1:0]   cnt1;
    051     always @(posedge clk or negedge rst_n)
    052     begin
    053      if(!rst_n)
    054       begin
    055           cnt1 <= 0;
    056        end
    057      else if(cnt_en)
    058        begin
    059             if(cnt1 == 2'd2)
    060                 cnt1 <= 2'd2;
    061             else if(cnt == t_1s)
    062                  cnt1 <= cnt1 + 1;
    063        end
    064       else
    065              cnt1 <= 0;
    066      end
    067        
    068     //-------------------------------
    069     /* 取key_4的上升沿和下降沿   */
    070     reg    [2:0]    key_4_reg;
    071     wire            key_4_pos;
    072     wire            key_4_neg;
    073     always @(posedge clk or negedge rst_n)
    074     begin
    075      if(!rst_n)
    076       begin
    077           key_4_reg  <= 3'b111;
    078        end
    079      else 
    080        begin
    081           key_4_reg  <= {key_4_reg[1:0],key_4};
    082        end
    083      end
    084        assign  key_4_pos = (key_4_reg[2:1] == 2'b01);
    085        assign  key_4_neg = (key_4_reg[2:1] == 2'b10);
    086     
    087     //------------------------------
    088     /*  状态机 */
    089      reg   [2:0]   state1;
    090      reg           key_S;
    091        reg           key_L;
    092        always @(posedge clk or negedge rst_n)
    093         begin
    094          if(!rst_n)
    095           begin
    096               state1 <= 'd0;
    097                     cnt_en <= 0;
    098                     key_S <= 0;
    099                     key_L <= 0;
    100            end
    101          else 
    102            begin
    103              case(state1)
    104                     'd0:
    105                        begin
    106                              cnt_en <= 0;
    107                                key_S  <= 0;
    108                          key_L  <= 0;
    109                          if(key_4_neg)          /* 按键按下  */ 
    110                                  state1 <= 'd1;
    111                                else
    112                                    state1 <= 'd0;
    113                         end
    114                        'd1:
    115                          begin
    116                                if(key_4_pos)            /* 按键释放   */
    117                                    begin
    118                                        cnt_en <= 0;    
    119                                        state1 <= 'd2;
    120                                        key_S  <= 1;  
    121                                     end
    122                                else if((key_4_reg==3'b000)&&(cnt1 == 2'd2))   /* 按键一直为低,延时2s之后  */
    123                                    begin
    124                                        cnt_en <= 0;    
    125                                        state1 <= 'd3;
    126                                        key_L  <= 1;
    127                                     end
    128                                else 
    129                                   cnt_en <= 1;                                    
    130                                end
    131                     'd2:                       /* 点击   */ 
    132                        begin
    133                                key_S  <= 0;  
    134                                  state1 <= 'd5;
    135                                end
    136                     'd3:
    137                        begin
    138                   key_L  <= 0;
    139                                 state1 <= 'd4;
    140                                end
    141                        'd4:
    142                          begin
    143                                if(key_4_pos)
    144                                 state1 <= 'd5; 
    145                                 else
    146                                     state1 <= 'd4;
    147                                end
    148                        'd5:
    149                          begin
    150                                    state1 <= 'd0;
    151                                end                            
    152                      default:state1 <= 'd0;
    153                    endcase
    154                    
    155            end
    156          end
    157            
    158     reg        led_s;
    159     reg        led_l;
    160     always @(posedge clk or negedge rst_n)
    161     begin
    162      if(!rst_n)
    163       begin
    164          led_s <= 0;
    165        end
    166      else if(key_S)
    167        begin
    168          led_s <= ~led_s;
    169        end
    170      end
    171        
    172     always @(posedge clk or negedge rst_n)
    173     begin
    174      if(!rst_n)
    175       begin
    176          led_l <= 0;
    177        end
    178      else if(key_L)
    179        begin
    180          led_l <= ~led_l;
    181        end
    182      end 
    183     
    184    //------------------------------------ 
    185     localparam  t_100ms = 22'd2399999;          /* //实际使用 */  
    186    // localparam  t_100ms = 22'd23;          /* //测试使用 */
    187     reg     [21:0]     cnnt;
    188     reg                cnnt_en;
    189     always @(posedge clk or negedge rst_n)
    190     begin
    191      if(!rst_n)
    192       begin
    193         cnnt <= 0;
    194        end
    195      else  if(cnnt_en)
    196        begin
    197          if(cnnt == t_100ms )
    198                   cnnt <= t_100ms;
    199                else 
    200                     cnnt <= cnnt + 1;
    201        end
    202        else 
    203             cnnt <= 0;
    204      end
    205    //-------------------------------
    206     /* 取key_5的上升沿和下降沿   */
    207     reg    [2:0]    key_5_reg;
    208     wire            key_5_pos;
    209     wire            key_5_neg;
    210     always @(posedge clk or negedge rst_n)
    211     begin
    212      if(!rst_n)
    213       begin
    214           key_5_reg  <= 3'b111;
    215        end
    216      else 
    217        begin
    218           key_5_reg  <= {key_5_reg[1:0],key_5};
    219        end
    220      end
    221        assign  key_5_pos = (key_5_reg[2:1] == 2'b01);
    222        assign  key_5_neg = (key_5_reg[2:1] == 2'b10);
    223        
    224     //------------------------------
    225     /*  状态机 */
    226      reg   [2:0]   state2;
    227      reg           key_SS;
    228        reg           key_D;
    229        always @(posedge clk or negedge rst_n)
    230         begin
    231          if(!rst_n)
    232           begin
    233               state2 <= 'd0;
    234                     cnnt_en <= 0;
    235                     key_SS <= 0;
    236                     key_D <= 0;
    237            end
    238          else 
    239            begin
    240              case(state2)
    241                     'd0:
    242                        begin
    243                              cnnt_en <= 0;
    244                                key_SS  <= 0;
    245                          key_D  <= 0;
    246                          if(key_5_neg)          /*第一次 按键按下  */ 
    247                                  state2 <= 'd1;
    248                                else
    249                                    state2 <= 'd0;
    250                         end
    251                        'd1:
    252                          begin
    253                              if(key_5_pos)            /*第一次 按键释放   */     
    254                                  begin
    255                                        state2 <= 'd2;    
    256                                     end
    257                               else     
    258                                    state2 <= 'd1;     
    259                            end
    260                        'd2:
    261                          begin
    262                                if((key_5_neg)&&(cnnt < t_100ms))    
    263                                    begin
    264                                        cnnt_en <= 0;    
    265                                        state2 <= 'd3;
    266                                        key_D  <= 1; 
    267                                    end
    268                                else if(cnnt ==t_100ms)    
    269                                  begin
    270                                        cnnt_en <= 0;    
    271                                        state2 <= 'd4;
    272                                        key_SS  <= 1;                                            
    273                                        end
    274                                else 
    275                                    cnnt_en <= 1;    
    276                                end
    277                        'd3: 
    278                          begin
    279                                key_D  <= 0;     
    280                                if(key_5_pos)    
    281                                    state2 <= 'd5;   
    282                                end
    283                        'd4: 
    284                          begin                
    285                                key_SS  <= 0;    
    286                                state2 <= 'd5;
    287                          end
    288                        'd5:
    289                          begin
    290                                 state2 <= 'd0;    
    291                                end                        
    292                      default:state2 <= 'd0;
    293                    endcase
    294                    
    295            end
    296          end
    297            
    298     reg        led_signal;
    299     reg        led_double;
    300     always @(posedge clk or negedge rst_n)
    301     begin
    302      if(!rst_n)
    303       begin
    304          led_signal <= 0;
    305        end
    306      else if(key_SS)
    307        begin
    308          led_signal <= ~led_signal;
    309        end
    310      end
    311        
    312     always @(posedge clk or negedge rst_n)
    313     begin
    314      if(!rst_n)
    315       begin
    316          led_double <= 0;
    317        end
    318      else if(key_D)
    319        begin
    320          led_double <= ~led_double;
    321        end
    322      end 
    323        
    324     //------------------------
    325      assign led_d41 = led_s;
    326        assign led_d42 = led_l; 
    327      assign led_d51 = led_signal;
    328        assign led_d52 = led_double;    
    329     
    330     endmodule
    331
    332
    333     
    View Code

    仿真代码:

      

        /********************************Copyright**************************************                           
        **----------------------------File information--------------------------
        ** File name  :key_function_testbench.v  
        ** CreateDate :2015.03
        ** Funtions   :按键功能的测试文件
        ** Operate on :M5C06N3L114C7
        ** Copyright  :All rights reserved. 
        ** Version    :V1.0
        **---------------------------Modify the file information----------------
        ** Modified by   :
        ** Modified data :        
        ** Modify Content:
        *******************************************************************************/
    001    `timescale 1 ns/1 ns
    002
    003    module  key_function_2_tb;
    004     reg          clk;
    005     reg          rst_n;
    006     
    007     reg          key_4;                 //按键的点击与长击:按下按键后,2S内松开按键则为点击,2s后松开按键为长击,默认未按下为高。
    008     reg          key_5;                /*按键的单击和双击,完成第一次按键后100ms之内第二次按下按键则为双击,否则为单击    */  
    009     
    010     wire         led_d41;
    011     wire         led_d42;
    012     wire         led_d51;
    013     wire         led_d52;
    014     
    015     
    016    key_function_2   key_function_2(
    017                                                             .clk,
    018                                                             .rst_n,
    019                                                             
    020                                                             .key_4,
    021                                                             .key_5,
    022                                                             
    023                                                             .led_d41,
    024                                                             .led_d42,
    025                                                             .led_d51,
    026                                                             .led_d52
    027                                                             
    028                                                                 );
    029     
    030     parameter  tck = 24;
    031    parameter  t = 1000/tck;
    032
    033    always  #(t/2)   clk = ~clk;
    034
    035        initial 
    036            begin
    037          clk = 0;
    038                rst_n = 0;
    039                key_4 = 1;
    040                key_5 = 1;
    041                
    042              #(100*t)  rst_n = 1;
    043                /* 点击 */
    044                #(100*t)  key_4 = 1;
    045              #(60*t)   key_4 = 0;
    046                #(100*t)  key_4 = 1;
    047                
    048                /* 长击 */
    049                #(100*t);
    050                #(100*t)  key_4 = 1;
    051              #(60*t)   key_4 = 0;
    052                #(1000*t);
    053                #(100*t)  key_4 = 1;
    054                
    055                /* 单击 */
    056                #(2000*t);
    057                #(100*t)  key_5 = 1;
    058              #(300*t)   key_5 = 0;
    059                #(100*t)  key_5 = 1;
    060                
    061                
    062                /* 双击 */
    063                #(2000*t);
    064                #(100*t)  key_5 = 1;
    065              #(300*t)  key_5 = 0;
    066                #(300*t)  key_5 = 1;
    067                #(10*t)   key_5 = 1;
    068              #(10*t)   key_5 = 0;
    069                #(300*t)  key_5 = 1;
    070                
    071                
    072            end
    073            
    074        endmodule 
    075                
    076
    View Code

    仿真波形:

    1、点击与长击

     

    2、单击与双击

      

    注:参考资料来自网络。

  • 相关阅读:
    Android的LinearLayout中orientation默认值为什么是HORIZONTAL
    Android中HttpURLConnection对象是怎么生成的
    记一个擦除硬盘数据,防止已删除文件被恢复的程序
    添加一个Android框架层的系统服务与实现服务的回调
    在 Activity 中实现 getContentView 操作
    (01)明明配置了log4j.properties为什么还是不打印日志
    (05)pom.xml文件报错web.xml is missing and <failOnMissingWebXml> is set to true
    (04)maven中的几个常用插件
    (03)开发环境eclipse、myEclipse本地tomcat调试发布maven项目遇到的糟心事
    (04)Storm与Kafka结合使用简单案例
  • 原文地址:https://www.cnblogs.com/fhyfhy/p/4368123.html
Copyright © 2011-2022 走看看