Usually, the switches used for buttons are mechanical elastic switches. When the mechanical contacts are opened and closed, due to the elastic effect of the mechanical contacts, a button switch will not be stably connected immediately when closed, nor will it be completely disconnected at once when disconnected. Instead, it will be accompanied by a series of jitters at the moment of closing and disconnecting, as shown in Figure 8-10.
Figure 8-10 Button jitter status diagram
The length of the key stable closing time is determined by the operator, usually more than 100ms. If you deliberately press it quickly, it can reach about 40-50ms, and it is difficult to be lower. The jitter time is determined by the mechanical characteristics of the key, and is generally within 10ms. In order to ensure that the program responds only once to a key closing or disconnection, the key must be debounced. When a key state change is detected, it does not respond immediately, but waits for the closing or disconnection to stabilize before processing. Key debounce can be divided into hardware debounce and software debounce.
Hardware debounce is to connect a capacitor in parallel to the key, as shown in Figure 8-11, and use the charge and discharge characteristics of the capacitor to smooth the voltage burrs generated during the jitter process, thereby achieving debounce. However, in actual applications, the effect of this method is often not very good, and it also increases the cost and circuit complexity, so it is not often used in practice.
Figure 8-11 Hardware capacitor debounce
In most cases, we use software, i.e. programs, to achieve debounce. The simplest debounce principle is that after detecting a change in the key state, wait for a delay of about 10ms to allow the jitter to disappear before performing another key state detection. If the state is the same as the state just detected, it can be confirmed that the key has stabilized. Slightly modify the previous program to obtain a new program with debounce function as follows.
Download this program to the board and try it out. Is the problem of adding numbers multiple times when pressing a button solved? Does it feel good to solve the problem?
This program uses a simple algorithm to achieve key debounce. As a simple demonstration program, we can write it like this, but when actually developing a project, the program is often very large and has many status values. The while(1) main loop needs to constantly scan various status values to see if they have changed and schedule tasks in a timely manner. If this delay operation is added in the middle of the program, it is very likely that an event has occurred, but our program is still in the delay operation. When the event has occurred, the program is still in the delay operation. When we check again after the delay is completed, it is too late and the event cannot be detected. In order to avoid this situation, we should try to shorten the time taken by the while(1) loop once. If a long delay operation is required, we must think of other ways to deal with it.
So how to deal with the delay required for debounce operation? In fact, in addition to this simple delay, we have better ways to deal with the key jitter problem. For example, we enable a timer interrupt, interrupt once every 2ms, scan the key status once and store it, scan 8 times in a row, and see if the key status of these 8 consecutive times is consistent. The time for 8 key presses is about 16ms. If the key status remains consistent within 16ms, it can be determined that the key is now in a stable stage, not in a jitter stage, as shown in Figure 8-12.
Figure 8-12 Key continuous scanning judgment
If the time on the left is the starting time 0, it will move left every 2ms. Each time it moves, it will determine whether the current 8 consecutive key states are all 1 or all 0. If they are all 1, it will be determined as a bounce, if they are all 0, it will be determined as a press. If 0 and 1 are interlaced, it will be considered as a jitter, and no judgment will be made. Think about it, is this more reliable than a simple delay?
Using this method, we can avoid occupying the execution time of the microcontroller through delay and de-jittering, and instead transform it into a key state judgment rather than a key process judgment. We only judge the 8 consecutive states of the current key for 16ms, and no longer care about what it has done in these 16ms. Then, we will implement it with a program according to this idea, and also take K4 as an example.
This algorithm is a good method that we often use in actual projects. I would like to introduce it to you. You can use this method to eliminate jitter in the future. Of course, there are other methods to eliminate jitter, and the program implementation is even more diverse. You can also consider other algorithms and expand your ideas.
Keywords:MCU
Reference address:MCU key debounce program
Figure 8-10 Button jitter status diagram
The length of the key stable closing time is determined by the operator, usually more than 100ms. If you deliberately press it quickly, it can reach about 40-50ms, and it is difficult to be lower. The jitter time is determined by the mechanical characteristics of the key, and is generally within 10ms. In order to ensure that the program responds only once to a key closing or disconnection, the key must be debounced. When a key state change is detected, it does not respond immediately, but waits for the closing or disconnection to stabilize before processing. Key debounce can be divided into hardware debounce and software debounce.
Hardware debounce is to connect a capacitor in parallel to the key, as shown in Figure 8-11, and use the charge and discharge characteristics of the capacitor to smooth the voltage burrs generated during the jitter process, thereby achieving debounce. However, in actual applications, the effect of this method is often not very good, and it also increases the cost and circuit complexity, so it is not often used in practice.
Figure 8-11 Hardware capacitor debounce
In most cases, we use software, i.e. programs, to achieve debounce. The simplest debounce principle is that after detecting a change in the key state, wait for a delay of about 10ms to allow the jitter to disappear before performing another key state detection. If the state is the same as the state just detected, it can be confirmed that the key has stabilized. Slightly modify the previous program to obtain a new program with debounce function as follows.
New window with plain text
- #include
- sbit ADDR0 = P1^0;
- sbit ADDR1 = P1^1;
- sbit ADDR2 = P1^2;
- sbit ADDR3 = P1^3;
- sbit ENLED = P1^4;
- sbit KEY1 = P2^4;
- sbit KEY2 = P2^5;
- sbit KEY3 = P2^6;
- sbit KEY4 = P2^7;
- unsigned char code LedChar[] = { // Digital tube display character conversion table
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- void delay();
- void main(){
- bit keybuf = 1; // Temporary storage of key values, temporarily saving the scanned values of keys
- bit backup = 1; //Backup the key value and save the previous scan value
- unsigned char cnt = 0; //Key counting, record the number of times the key is pressed
- ENLED = 0; //Select digital tube DS1 for display
- ADDR3 = 1;
- ADDR2 = 0;
- ADDR1 = 0;
- ADDR0 = 0;
- P2 = 0xF7; //P2.3 is set to 0, i.e. KeyOut1 outputs low level
- P0 = LedChar[cnt]; //Display the initial value of the number of key presses
- while (1){
- keybuf = KEY4; //temporarily store the current scan value
- if (keybuf != backup){ //The current value is not equal to the previous value, indicating that the key is in action
- delay(); //delay about 10ms
- if (keybuf == KEY4){ //Judge whether the scan value has changed, that is, the key is jittering
- if (backup == 0){ //If the previous value is 0, it means the current action is a pop-up
- cnt++; //Number of key presses + 1
- //Only one digital tube is used for display, so when it is added to 10, it will be reset to zero and start again
- if (cnt >= 10){
- cnt = 0;
- }
- P0 = LedChar[cnt]; //The count value is displayed on the digital tube
- }
- backup = keybuf; //Update the backup to the current value for the next comparison
- }
- }
- }
- }
- /* Software delay function, delay about 10ms */
- void delay(){
- unsigned int i = 1000;
- while (i--);
- }
This program uses a simple algorithm to achieve key debounce. As a simple demonstration program, we can write it like this, but when actually developing a project, the program is often very large and has many status values. The while(1) main loop needs to constantly scan various status values to see if they have changed and schedule tasks in a timely manner. If this delay operation is added in the middle of the program, it is very likely that an event has occurred, but our program is still in the delay operation. When the event has occurred, the program is still in the delay operation. When we check again after the delay is completed, it is too late and the event cannot be detected. In order to avoid this situation, we should try to shorten the time taken by the while(1) loop once. If a long delay operation is required, we must think of other ways to deal with it.
So how to deal with the delay required for debounce operation? In fact, in addition to this simple delay, we have better ways to deal with the key jitter problem. For example, we enable a timer interrupt, interrupt once every 2ms, scan the key status once and store it, scan 8 times in a row, and see if the key status of these 8 consecutive times is consistent. The time for 8 key presses is about 16ms. If the key status remains consistent within 16ms, it can be determined that the key is now in a stable stage, not in a jitter stage, as shown in Figure 8-12.
Figure 8-12 Key continuous scanning judgment
If the time on the left is the starting time 0, it will move left every 2ms. Each time it moves, it will determine whether the current 8 consecutive key states are all 1 or all 0. If they are all 1, it will be determined as a bounce, if they are all 0, it will be determined as a press. If 0 and 1 are interlaced, it will be considered as a jitter, and no judgment will be made. Think about it, is this more reliable than a simple delay?
Using this method, we can avoid occupying the execution time of the microcontroller through delay and de-jittering, and instead transform it into a key state judgment rather than a key process judgment. We only judge the 8 consecutive states of the current key for 16ms, and no longer care about what it has done in these 16ms. Then, we will implement it with a program according to this idea, and also take K4 as an example.
New window with plain text
- #include
- sbit ADDR0 = P1^0;
- sbit ADDR1 = P1^1;
- sbit ADDR2 = P1^2;
- sbit ADDR3 = P1^3;
- sbit ENLED = P1^4;
- sbit KEY1 = P2^4;
- sbit KEY2 = P2^5;
- sbit KEY3 = P2^6;
- sbit KEY4 = P2^7;
- unsigned char code LedChar[] = { // Digital tube display character conversion table
- 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
- };
- bit KeySta = 1; //Current key status
- void main(){
- bit backup = 1; //Backup the key value and save the previous scan value
- unsigned char cnt = 0; //Key counting, record the number of times the key is pressed
- EA = 1; // Enable general interrupt
- ENLED = 0; //Select digital tube DS1 for display
- ADDR3 = 1;
- ADDR2 = 0;
- ADDR1 = 0;
- ADDR0 = 0;
- TMOD = 0x01; //Set T0 to mode 1
- TH0 = 0xF8; //Assign the initial value 0xF8CD to T0, and set the timing to 2ms
- TL0 = 0xCD;
- ET0 = 1; // Enable T0 interrupt
- TR0 = 1; //Start T0
- P2 = 0xF7; //P2.3 is set to 0, i.e. KeyOut1 outputs low level
- P0 = LedChar[cnt]; //Display the initial value of the number of key presses
- while (1){
- //KeySta = KEY4; //temporarily save the current scan value
- if (KeySta != backup){ //The current value is not equal to the previous value, indicating that the key is in action
- if (backup == 0){ //If the previous value is 0, it means the current action is a pop-up
- cnt++; //Number of key presses + 1
- if (cnt >= 10){ //Only one digital tube is used for display, so when it is added to 10, it will be reset to zero and start again
- cnt = 0;
- }
- P0 = LedChar[cnt]; //The count value is displayed on the digital tube
- }
- //Update the backup to the current value in preparation for the next comparison
- backup = KeySta;
- }
- }
- }
- /* T0 interrupt service function, used to scan and debounce the key status*/
- void InterruptTimer0() interrupt 1{
- //Scan buffer, save the scan value within a period of time
- static unsigned char keybuf = 0xFF;
- TH0 = 0xF8; //Reload initial value
- TL0 = 0xCD;
- // Shift the buffer left by one bit and move the current scan value into the lowest bit
- keybuf = (keybuf<<1) | KEY4;
- //When the values of 8 consecutive scans are all 0, that is, only the pressing state is detected within 16ms, it can be considered that the key is pressed.
- if (keybuf == 0x00){
- KeySta = 0;
- //When the scan value is 1 for 8 consecutive times, that is, only the pop-up state is detected within 16ms, it can be considered that the key has popped up.
- }else if (keybuf == 0xFF){
- KeySta = 1;
- }
- else{
- //Other cases indicate that the key status is not stable yet, so the KeySta variable value will not be updated
- }
- }
Previous article:MCU key scanning method
Next article:51 MCU PWM control motor
Recommended ReadingLatest update time:2024-11-15 17:25
AVR MCU Tutorial - Button Status
Today we are going to talk about buttons. There are 4 buttons on the lower right corner of the development board, and there will be a noticeable "click" sound when pressed. How to detect whether the button is pressed? First, the button must be connected to the microcontroller directly or indirectly. Unlike the 4 LEDs
[Microcontroller]
Detailed description of bit operations and their applications in C51 language of microcontroller
In the process of programming the microcontroller, bit alignment operations are often encountered. The C51's position control ability is very powerful. From this point, we can see that C not only has the flexibility of a high-level language, but also has the characteristics of a low-level language that is close to the
[Microcontroller]
MCU crash cause check, Crash dump stack backtrace technology can easily solve
If you are using MCU for development, as the functions and codes increase in the later stages of the project, crashes seem to be inevitable. Whenever you encounter this problem, you usually need to use an emulator to locate code defects, but if you encounter a problem that is very difficult to reproduce, or the
[Microcontroller]
Design of ANopen protocol monitoring panel based on PIC18F258 microcontroller
Virtual instruments are the product of the deep integration of electronic measurement technology and computer technology. Through the combination of software and hardware, various functions of traditional instruments are realized, which greatly breaks through the limitations of traditional instruments in data process
[Microcontroller]
[51 MCU STC89C52] Comprehensive chapter on steering gear control
1. Project Overview 1. Function description Ultrasonic module, vibration sensor, button control SG90 servo When detecting the proximity, the trash can will automatically open the lid with a beep sound and close the lid after 2 seconds. When vibration occurs, the lid of the trash can will automatically open with a be
[Microcontroller]
ATMEGA128 MCU timer + digital tube display
#define SS 0 #define SCK 1 #define MOSI 2 #define MISO 3 #define SS_H() PORTB|=(1 SS) #define SS_L() PORTB&=~(1 SS) //Be careful not to miss () #define led0_en() {DDRB|=1 4;PORTB|=(1 4);} //Open the first digital tube bit selection #define led0_dis() {DDRB|=1 4;PORTB&=~(1 4);} //Close the first digital tube bit select
[Microcontroller]
PIC microcontroller reads and writes 9346EEPROM data
Experimental purpose: Familiar with the SPI bus and the reading and writing of 9346EEPROM ;When the RBO key is pressed, DATA and DATA2 are written into the unit with EE-ADDR as the address in the EEPROM. ;After completion, a single digital display "9" is displayed as a completion mark ;When the RB1 key is pressed, the
[Microcontroller]
Detailed explanation of the classic experimental examples of single-chip microcomputers (with source code) (VI)
6. Infrared remote control sound and light tester
Here we are going to use the microcontroller experimental board to make an infrared remote control sound and light tester. Infrared remote controls are widely used in household appliances such as TVs, VCDs, and stereos. After long-term use, some minor faults may oc
[Analog Electronics]
- Popular Resources
- Popular amplifiers
- Wireless Sensor Network Technology and Applications (Edited by Mou Si, Yin Hong, and Su Xing)
- Modern Electronic Technology Training Course (Edited by Yao Youfeng)
- Modern arc welding power supply and its control
- Small AC Servo Motor Control Circuit Design (by Masaru Ishijima; translated by Xue Liang and Zhu Jianjun, by Masaru Ishijima, Xue Liang, and Zhu Jianjun)
Recommended Content
Latest Microcontroller Articles
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
MoreDaily News
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
Guess you like
- TPS61040 boost circuit abnormality
- [Atria AT32WB415 series Bluetooth BLE 5.0 MCU] + CAN communication
- What does it mean when a pushpin icon is displayed during STM32CubeMX pin configuration?
- Does TI C6678 support flash partitioning?
- 6678 SRIO: About QMSS, CPPI and SRIO Socket
- 【Top Micro Intelligent Display Module】VI: A comprehensive interface for controls
- Please tell me how this formula is calculated.
- RISC-V MCU IDE MRS (MounRiver Studio) development: Setting the engineering encoding character set
- Why are some MCU register addresses 00H and some 0000H? Is there a difference? How many addresses are there from 80H to FFH?
- How can the signal source of Proteus change the phase of the emitted square wave signal?