MCU key debounce program

Publisher:清晨微风Latest update time:2016-06-02 Source: eefocusKeywords:MCU Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
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.
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.
MCU key debounce program

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
 

  1. #include
  2.  
  3. sbit ADDR0 = P1^0;
  4. sbit ADDR1 = P1^1;
  5. sbit ADDR2 = P1^2;
  6. sbit ADDR3 = P1^3;
  7. sbit ENLED = P1^4;
  8. sbit KEY1 = P2^4;
  9. sbit KEY2 = P2^5;
  10. sbit KEY3 = P2^6;
  11. sbit KEY4 = P2^7;
  12.  
  13. unsigned char code LedChar[] = { // Digital tube display character conversion table
  14. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  15. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  16. };
  17.  
  18. void delay();
  19. void main(){
  20. bit keybuf = 1; // Temporary storage of key values, temporarily saving the scanned values ​​of keys
  21. bit backup = 1; //Backup the key value and save the previous scan value
  22. unsigned char cnt = 0; //Key counting, record the number of times the key is pressed
  23.  
  24. ENLED = 0; //Select digital tube DS1 for display
  25. ADDR3 = 1;
  26. ADDR2 = 0;
  27. ADDR1 = 0;
  28. ADDR0 = 0;
  29. P2 = 0xF7; //P2.3 is set to 0, i.e. KeyOut1 outputs low level
  30. P0 = LedChar[cnt]; //Display the initial value of the number of key presses
  31.  
  32. while (1){
  33. keybuf = KEY4; //temporarily store the current scan value
  34. if (keybuf != backup){ //The current value is not equal to the previous value, indicating that the key is in action
  35. delay(); //delay about 10ms
  36. if (keybuf == KEY4){ //Judge whether the scan value has changed, that is, the key is jittering
  37. if (backup == 0){ //If the previous value is 0, it means the current action is a pop-up
  38. cnt++; //Number of key presses + 1
  39. //Only one digital tube is used for display, so when it is added to 10, it will be reset to zero and start again
  40. if (cnt >= 10){
  41. cnt = 0;
  42. }
  43. P0 = LedChar[cnt]; //The count value is displayed on the digital tube
  44. }
  45. backup = keybuf; //Update the backup to the current value for the next comparison
  46. }
  47. }
  48. }
  49. }
  50. /* Software delay function, delay about 10ms */
  51. void delay(){
  52. unsigned int i = 1000;
  53. while (i--);
  54. }
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.
MCU key debounce program

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
 

  1. #include
  2.  
  3. sbit ADDR0 = P1^0;
  4. sbit ADDR1 = P1^1;
  5. sbit ADDR2 = P1^2;
  6. sbit ADDR3 = P1^3;
  7. sbit ENLED = P1^4;
  8. sbit KEY1 = P2^4;
  9. sbit KEY2 = P2^5;
  10. sbit KEY3 = P2^6;
  11. sbit KEY4 = P2^7;
  12.  
  13. unsigned char code LedChar[] = { // Digital tube display character conversion table
  14. 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
  15. 0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
  16. };
  17. bit KeySta = 1; //Current key status
  18.  
  19. void main(){
  20. bit backup = 1; //Backup the key value and save the previous scan value
  21. unsigned char cnt = 0; //Key counting, record the number of times the key is pressed
  22. EA = 1; // Enable general interrupt
  23. ENLED = 0; //Select digital tube DS1 for display
  24. ADDR3 = 1;
  25. ADDR2 = 0;
  26. ADDR1 = 0;
  27. ADDR0 = 0;
  28. TMOD = 0x01; //Set T0 to mode 1
  29. TH0 = 0xF8; //Assign the initial value 0xF8CD to T0, and set the timing to 2ms
  30. TL0 = 0xCD;
  31. ET0 = 1; // Enable T0 interrupt
  32. TR0 = 1; //Start T0
  33. P2 = 0xF7; //P2.3 is set to 0, i.e. KeyOut1 outputs low level
  34. P0 = LedChar[cnt]; //Display the initial value of the number of key presses
  35.  
  36. while (1){
  37. //KeySta = KEY4; //temporarily save the current scan value
  38. if (KeySta != backup){ //The current value is not equal to the previous value, indicating that the key is in action
  39. if (backup == 0){ //If the previous value is 0, it means the current action is a pop-up
  40. cnt++; //Number of key presses + 1
  41. 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
  42. cnt = 0;
  43. }
  44. P0 = LedChar[cnt]; //The count value is displayed on the digital tube
  45. }
  46. //Update the backup to the current value in preparation for the next comparison
  47. backup = KeySta;
  48. }
  49. }
  50. }
  51. /* T0 interrupt service function, used to scan and debounce the key status*/
  52. void InterruptTimer0() interrupt 1{
  53. //Scan buffer, save the scan value within a period of time
  54. static unsigned char keybuf = 0xFF;
  55.  
  56. TH0 = 0xF8; //Reload initial value
  57. TL0 = 0xCD;
  58. // Shift the buffer left by one bit and move the current scan value into the lowest bit
  59. keybuf = (keybuf<<1) | KEY4;
  60. //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.
  61. if (keybuf == 0x00){
  62. KeySta = 0;
  63. //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.
  64. }else if (keybuf == 0xFF){
  65. KeySta = 1;
  66. }
  67. else{
  68. //Other cases indicate that the key status is not stable yet, so the KeySta variable value will not be updated
  69. }
  70. }
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

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]
Detailed description of bit operations and their applications in C51 language of 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]
MCU crash cause check, Crash dump stack backtrace technology can easily solve
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]
Design of ANopen protocol monitoring panel based on PIC18F258 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]
[51 MCU STC89C52] Comprehensive chapter on steering gear control
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]
PIC microcontroller reads and writes 9346EEPROM data
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]
Detailed explanation of the classic experimental examples of single-chip microcomputers (with source code) (VI)
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号