1. How to shake the button
Figure 1: Key jitter
We usually use the key for mechanical elastic switch, due to the elastic effect of the contact, the button will not be immediately stable when closed, but there is a period of jitter, in the disconnection will not immediately disconnect. The jitter time is determined by the mechanical characteristics of the keys, generally 5ms~10ms. So we have to add a shake-out process when we do the key detection.
There are two main ways to shake keys:
One is time-lapse resampling, and the second is continuous sampling.
Theoretically, the accuracy of time-lapse (such as 10ms) resampling is certainly less than continuous sampling.
2. Press
the method of the key to eliminate shaking
(1) Time-lapse resamplingTime-lapse resampling means that when the first detection of a key value changed from ' 1 ' to ' 0 ', the delay period (such as 10ms) is again sampled to confirm whether it is still ' 0 '; if ' 0 ' is considered to be ' 0 ' at this time, otherwise, the detection process is re-executed. This program in the privileged classmate of the "in-depth play to FPGA" p191 has a routine;the defect of the scheme: a. If the delay is too short, it is possible to have a jitter time of two samples, which may cause false positives;B. If the delay is too long, the key transformation may not be detected
(2) Continuous samplingThe principle of continuous sampling is that when a key is detected at a certain level (such as ' 0 '), the level of the key is continuously detected in the following n clock cycles, and if it remains constant, the level value of the key (such as ' 0 ') is read out.Advantages of continuous sampling: a. Enough samples to reduce the likelihood of miscalculation. B. For key presses (' 1 ', ' 0 '), press release (' 0 ', ' 1 ') can be detected. the disadvantage of continuous sampling is that the duration of continuous detection is too long (greater than the time difference between press and release), and the key transformation may not be detected.
1) Detection of individual keysThe output of the key detection is available in two ways: 1. Level output, when the button function is like a dip switch. 2. Pulse output, at this time each press the Next button, output a pulse signal. Figure 2. The key detection output waveform 2 shows that the output of the KEY_OUT1 is the same as that of the key_in, except that the jitter component is filtered out; Key_out2 is a high-level pulse when the key is pressed. In most applications, the functionality shown in Key_out2 is used.
output as level (for Level judging event, similar to switch selection)Module key_scan# (Parameter DURATION = +)//the number of CLK period (input wire CLK,//120mhzinput wire rst_n,input wire key_in, output reg Key_out); Key jitter filterreg[11:0] low_cnt;reg[11:0] high_cnt;always @ (Posedge CLK or Negedge rst_n) beginif (!rst_n) beginlow_ CNT <= 0;high_cnt <= 0;key_out <= 1 ' b1;endelsebeginif (key_in = 1 ' b0) beginhigh_cnt <= 0;if (low_cnt = DURATION ) begin low_cnt <= low_cnt; Key_out <= 1 ' b0; endelselow_cnt <= low_cnt + 1 ' b1;endelse//key_in = 1 ' b1beginlow_cnt <= 0;if (high_cnt = DURATION) begin high_cnt &L t;= high_cnt;key_out <= 1 ' B1; endelsehigh_cnt <= high_cnt + 1 ' b1;endendendendmodule
output as pulse (for pulse trigger event)Module key_scan# (Parameter DURATION = +)//the number of CLK period (input wire CLK,//120mhzinput wire rst_n,input wire key_in, output wire key_out); Key jitter filterreg[11:0] low_cnt;always @ (Posedge CLK or Negedge rst_n) beginif (!rst_n) low_cnt <= 0;elsebeginif ( key_in = = 1 ' b0) beginif (low_cnt = = DURATION) low_cnt <= low_cnt;elselow_cnt <= low_cnt + 1 ' b1;endelse//key_in = 1 ' b1 low_cnt <= 0;endend Assign key_out = (low_cnt = = DURATION-1)? 1 ' b1:1 ' B0; Endmodule
2) Scanning of multiple independent keys (scan for key values)
function: A. You can detect which keys are pressed, and even which keys are pressed at the same time.
B. After the key value update, output a pulse signal, improve the update completed;
c. The key value remains until the next update is complete. module key_counter_scan# (Parameter key_width = 4) (//global clockinput clk,input rst_n, //key interfaceinput [key_width-1:0] Key_data, //user interfaceoutput reg key_flag,output reg [key_width-1:0] key_value//H Valid); //-----------------------------------//register key_data for Comparereg [key_width-1:0] key_data_r;always @ ( Posedge CLK or Negedge rst_n) beginif (!rst_n) key_data_r <= {key_width{1 ' b1}};elsekey_data_r <= key_data;end //-----------------------------------//continue 20mslocalparam delay_top = D1000_000;//localparam Delay_ TOP = ' d1000; Just for Testreg [19:0] delay_cnt;//-----------------------------------//key Scan via Counter detect.always @ (Posedge CLK or Negedge rst_n) beginif (!rst_n) delay_cnt <= 0;elsebeginif ((key_data = key_data_r) && (key_data! = {KEY_W Idth{1 ' B1}))//20ms counter jitterbeginif (delay_cnt < delay_top) delay_cnt <= delay_cnt + 1 ' b1;elsedelay_cnt <= delay_top;endelsedelay_cnt <= 0;ENDEND&Nbsp; //-----------------------------------//the complete of key_data capturewire Key_trigger = (delay_cnt = = Delay _top-1 ' B1)? 1 ' b1:1 ' b0; //-----------------------------------//output the valid key_value via key_trigger[email Protected] (Posedge CLK or Negedge rst_n) beginif (!rst_n) key_value <= {key_width{1 ' b0}};else if (key_trigger) Key_ Value <= ~key_data_r;elsekey_value <= key_value;end //---------------------------------//lag 1 clock for Valid read Enable[email protected] (Posedge CLK or Negedge rst_n) beginif (!rst_n) key_flag <= 0;elsekey_flag <= Key_trigger;end endmodule
The ultimate solution for key suppression