硬件电路图如下:
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<=0; end
46
47 else
48
49 begin
50
51 if(count>=50) begin 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
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<=0; end
46
47 else
48
49 begin
50
51 if(count>=50) begin 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