蜗牛

一起交流,共同进步
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Verilog HDL 4*4矩阵键盘扫描程序

Posted on 2009-05-07 18:08  路漫漫...  阅读(20300)  评论(19编辑  收藏  举报

硬件电路图如下:

 

 

  1module key
  2
  3(
  4
  5 clk,  //50MHZ
  6
  7 reset,
  8
  9 row,   //
 10
 11 col,   //
 12
 13 key_value  //键值
 14
 15);
 16
 17input clk,reset; 
 18
 19 input [3:0] row;
 20
 21 output [3:0] col;
 22
 23 output [3:0] key_value;
 24
 25 
 26 reg [3:0] col;
 27
 28 reg [3:0] key_value;
 29
 30 reg [5:0] count;//delay_20ms
 31
 32 reg [2:0] state;  //状态标志
 33
 34 reg key_flag;   //按键标志位
 35
 36 reg clk_500khz;  //500KHZ时钟信号
 37
 38 reg [3:0] col_reg;  //寄存扫描列值
 39
 40 reg [3:0] row_reg;  //寄存扫描行值
 41
 42
 43always @(posedge clk or negedge reset)
 44
 45   if(!reset) begin clk_500khz<=0; count<=0end
 46
 47   else
 48
 49    begin
 50
 51      if(count>=50begin clk_500khz<=~clk_500khz;count<=0;end
 52
 53      else count<=count+1;
 54
 55    end
 56
 57   
 58
 59 always @(posedge clk_500khz or negedge reset)
 60
 61   if(!reset) begin col<=4'b0000;state<=0;end
 62
 63   else 
 64
 65    begin 
 66
 67     case (state)
 68
 69      0
 70
 71         begin
 72
 73         col[3:0]<=4'b0000;
 74
 75         key_flag<=1'b0;
 76
 77         if(row[3:0]!=4'b1111) begin state<=1;col[3:0]<=4'b1110;end //有键按下,扫描第一行
 78
 79         else state<=0;
 80
 81         end 
 82
 83      1:  
 84
 85         begin
 86
 87          if(row[3:0]!=4'b1111) begin state<=5;end   //判断是否是第一行
 88
 89          else  begin state<=2;col[3:0]<=4'b1101;end  //扫描第二行
 90
 91         end 
 92
 93      2:
 94
 95         begin    
 96
 97         if(row[3:0]!=4'b1111) begin state<=5;end    //判断是否是第二行
 98
 99         else  begin state<=3;col[3:0]<=4'b1011;end  //扫描第三行
100
101         end
102
103      3:
104
105         begin    
106
107         if(row[3:0]!=4'b1111) begin state<=5;end   //判断是否是第三一行
108
109         else  begin state<=4;col[3:0]<=4'b0111;end  //扫描第四行
110
111         end
112
113      4:
114
115         begin    
116
117         if(row[3:0]!=4'b1111) begin state<=5;end  //判断是否是第一行
118
119         else  state<=0;
120
121         end
122
123      5:
124
125         begin  
126
127          if(row[3:0]!=4'b1111) 
128
129begin
130
131 col_reg<=col;  //保存扫描列值
132
133row_reg<=row;  //保存扫描行值
134
135state<=5;
136
137key_flag<=1'b1;  //有键按下
138
139 end             
140
141          else
142
143            begin state<=0;end
144
145         end    
146
147     endcase 
148
149    end           
150
151  
152
153 always @(clk_500khz or col_reg or row_reg)
154
155     begin
156
157        if(key_flag==1'b1) 
158
159                begin
160
161                     case ({col_reg,row_reg})
162
163                      8'b1110_1110:key_value<=0;
164
165                      8'b1110_1101:key_value<=1;
166
167                      8'b1110_1011:key_value<=2;
168
169                      8'b1110_0111:key_value<=3;
170
171                      
172
173                      8'b1101_1110:key_value<=4;
174
175                      8'b1101_1101:key_value<=5;
176
177                      8'b1101_1011:key_value<=6;
178
179                      8'b1101_0111:key_value<=7;
180
181 
182
183                      8'b1011_1110:key_value<=8;
184
185                      8'b1011_1101:key_value<=9;
186
187                      8'b1011_1011:key_value<=10;
188
189                      8'b1011_0111:key_value<=11;
190
191 
192
193                      8'b0111_1110:key_value<=12;
194
195                      8'b0111_1101:key_value<=13;
196
197                      8'b0111_1011:key_value<=14;
198
199                      8'b0111_0111:key_value<=15;     
200
201                     endcase 
202
203              end   
204
205   end       
206
207 endmodule
208