按键的使用方法(三)-------verilog

按键的使用方法三:一键三用: 点击、长击和双击、

 

代码:

  

    /********************************Copyright**************************************                           
001    **----------------------------File information--------------------------
002    ** File name  :key_function_3.v  
003    ** CreateDate :2015.03
004    ** Funtions   :按键的用法(三):一个按键完成单击,长击,双击的作用。
005    ** Operate on :M5C06N3L114C7
006    ** Copyright  :All rights reserved. 
007    ** Version    :V1.0
008    **---------------------------Modify the file information----------------
009    ** Modified by   :
010    ** Modified data :        
011    ** Modify Content:
012    *******************************************************************************/
013     
014     module  key_function_3 (
015                                     clk,
016                                     rst_n,
017                     
018                                     key_6,
019                                     
020                                     led_S,
021                               led_L,
022                                     led_D
023                                     
024                                         );
025     input          clk;
026     input          rst_n;
027     
028     input          key_6;
029     
030     output         led_S;
031     output         led_L;
032     output         led_D;
033     
034    //--------------------------------------------
035    /* 定时:100ms,2s */
036      reg           count_en;
037      localparam  t_1s = 25'd23999999;
038        localparam  t_100ms = 22'd2399999;
039
040    //  localparam  t_1s = 25'd2399;         /* //测试使用 */
041    //    localparam  t_100ms = 22'd239;       /* //测试使用 */
042
043      localparam  t_2s = 2'd2;
044        
045        reg      [24:0]      count;
046     always @(posedge clk or negedge rst_n)
047     begin
048      if(!rst_n)
049       begin
050            count <= 0;
051        end
052      else if(count_en)
053        begin
054           if(count == t_1s)
055                     count <= 0;
056                else 
057                    count <= count + 1;
058        end
059       else
060              count <= 0;    
061      end
062     
063     reg     [1:0]   count1;
064     always @(posedge clk or negedge rst_n)
065     begin
066      if(!rst_n)
067       begin
068           count1 <= 0;
069        end
070      else if(count_en)
071        begin
072             if(count1 == t_2s)
073                 count1 <= 2'd2;
074             else if(count == t_1s)
075                  count1 <= count1 + 1;
076        end
077       else
078              count1 <= 0;
079      end
080        
081    //-------------------------------
082     /* 取key_6的上升沿和下降沿   */
083     reg    [2:0]    key_6_reg;
084     wire            key_6_pos;
085     wire            key_6_neg;
086     always @(posedge clk or negedge rst_n)
087     begin
088      if(!rst_n)
089       begin
090           key_6_reg  <= 3'b111;
091        end
092      else 
093        begin
094           key_6_reg  <= {key_6_reg[1:0],key_6};
095        end
096      end
097        assign  key_6_pos = (key_6_reg[2:1] == 2'b01);
098        assign  key_6_neg = (key_6_reg[2:1] == 2'b10);
099     
100     //------------------------------
101     /*  状态机 */
102      reg   [2:0]   state;
103      reg           key_S;
104        reg           key_L;
105        reg           key_D;
106        always @(posedge clk or negedge rst_n)
107         begin
108          if(!rst_n)
109           begin
110               state <= 'd0;
111                     count_en <= 0;
112                     key_S <= 0;
113                     key_L <= 0;
114                     key_D <= 0;
115            end
116          else 
117            begin
118              case(state)
119                     'd0:
120                        begin
121                               count_en <= 0;
122                                 key_S  <= 0;
123                           key_L  <= 0;
124                                 key_D <= 0;
125                          if(key_6_neg)          /* 按键按下  */ 
126                                  state <= 'd1;
127                                else
128                                    state <= 'd0;
129                         end
130                        'd1:
131                          begin
132                                if(key_6_pos)            /* 按键释放   */      
133                                    begin
134                                          count_en  <= 0; 
135                                            state <= 'd3;    
136                                        end
137                                 else  if((key_6_reg == 3'b000)&&(count1 == t_2s))     /* 按键长击   */
138                                     begin
139                                            count_en  <= 0; 
140                                            state <= 'd2;
141                                            key_L <= 1;
142                                            end
143                                else 
144                                    count_en  <= 1;
145                            end        
146                         'd2:
147                           begin
148                                 key_L <= 0;     
149                                 if(key_6_pos)
150                                      state <= 'd7; 
151                                    else 
152                                        state <= 'd2;
153                             end
154                        'd3:
155                              begin
156                            state <= 'd4;
157                                 end
158                        'd4:                                                      /* 决定单击还是双击 */
159                          begin
160                                if((key_6_neg)&&((count1 == 0)&&(count < t_100ms)))       /* 双击 *//* 按键按下  */ 
161                                  begin
162                                         count_en  <= 0;
163                                         state <= 'd6;          
164                                         key_D <= 1;
165                                        end
166                                 else if((count1 == 0)&&(count > t_100ms))             /* 单击 */
167                                     begin
168                                         count_en  <= 0;
169                                         state <= 'd5;          
170                                         key_S <= 1;                                          
171                                     end
172                                 else 
173                                   count_en  <= 1;                                    
174                                end
175                            'd5:
176                              begin
177                                    state <= 'd8;        
178                                    key_S <= 0;                                                         
179                                end
180                            'd6:
181                              begin                                       
182                                    key_D <= 0;     
183                                    if(key_6_pos)                                     /* 按键释放 */  
184                                        state <= 'd8;    
185                                    else 
186                                        state <= 'd6;   
187                                    end
188                            'd8:
189                              begin
190                                      state <= 'd0;    
191                                    end                                
192                      default:state <= 'd0;
193                    endcase
194                    
195            end
196          end
197
198      reg  [2:0]    led;
199        always @(posedge clk or negedge rst_n)
200         begin
201          if(!rst_n)
202           begin
203              led <= 3'b000;
204            end
205          else 
206            begin
207             if(key_S)
208                      led[0]<= ~led[0];    
209                 else if(key_L)
210                      led[1]<= ~led[1];
211                 else if(key_D)
212                      led[2]<= ~led[2];
213            end
214          end
215            
216    //------------------------------
217    assign {led_D,led_L,led_S} = led;
218
219    endmodule
220
221
222     
223     
224
View Code

 

难点:单击与双击的处理部分,状态机部分

 

测试代码

 

    /********************************Copyright**************************************                           
01    **----------------------------File information--------------------------
02    ** File name  :key_function_testbench.v  
03    ** CreateDate :2015.03
04    ** Funtions   :按键功能的测试文件
05    ** Operate on :M5C06N3L114C7
06    ** Copyright  :All rights reserved. 
07    ** Version    :V1.0
08    **---------------------------Modify the file information----------------
09    ** Modified by   :
10    ** Modified data :        
11    ** Modify Content:
12    *******************************************************************************/
13    `timescale 1 ns/1 ns
14    module  key_function_3_tb;
15     reg          clk;
16     reg          rst_n;
17     
18     reg          key_6;
19     
20     wire         led_S;
21     wire         led_L;
22     wire         led_D;
23     
24     key_function_3 key_function_3_1(
25                                                 .clk,
26                                                 .rst_n,
27                                                 
28                                                 .key_6,
29                                                 
30                                                 .led_S,
31                                                 .led_L,
32                                                 .led_D
33                                                 
34                                                     );
35
36    parameter  tck = 24;
37    parameter  t = 1000/tck;
38
39    always  #(t/2)   clk = ~clk;
40
41        initial 
42            begin
43          clk = 0;
44                rst_n = 0;
45                key_6 = 1;
46            
47              #(100*t)  rst_n = 1;
48                
49                #(800*t);
50                
51                
52                /* 点击 */
53                #(100*t)  key_6 = 1;
54              #(300*t)   key_6 = 0;
55                #(100*t)  key_6 = 1;
56                
57                /* 长击 */
58                #(1000*t);
59                #(100*t)   key_6 = 1;
60              #(300*t)   key_6 = 0;
61                #(5000*t);
62                #(100*t)   key_6 = 1;
63                
64                
65                        /* 双击 */
66                #(1000*t);
67                #(100*t)  key_6 = 1;
68              #(300*t)  key_6 = 0;
69                #(300*t)  key_6 = 1;
70              #(100*t)  key_6 = 0;
71                #(300*t)  key_6 = 1;
72        end
73        
74    endmodule
75
View Code

 

 

仿真波形

注:参考资料来自网络。

posted @ 2015-03-26 11:30  远航路上ing  阅读(2285)  评论(0编辑  收藏  举报