I just started to learn 51 MCU programming recently. When I learned about key scanning, I saw a blog post on the Internet titled "New Key Scanning" written by Etual in 2008. I was very touched. For the introduction and application of key scanning, please refer to the original article. This article is just my thoughts and experience on the program. I can't find the link to the original article, so I'll reprint it here:
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=4308630&bbs_page_no=1&search_mode=4&search_text=atommann&bbs_id=9999
http://blog.21ic.com/user1/379/archives/2010/68144.html
http://blog.ednchina.com/zp2009/983530/Message.aspx
The main parts of the source program are as follows:
volatile unsigned char Trg;
volatile unsigned char Cont;
volatile unsigned char Release;
void KeyRead( void )
{
unsigned char ReadData = PINB^0xff; // 1 read key value
Trg = ReadData & (ReadData ^ Cont); // 2 Get the press trigger value
Release = (ReadData ^ Trg ^ Cont); // 3 Get the release trigger value
Cont = ReadData; // 4 Get all unreleased key values
}
First of all, I felt that the logic of the program could be optimized, so I took the initiative to use the logic optimization method on digital circuits.
void KeyRead( void )
{
unsigned char ReadData = (~PINB)&0xff; // 1 read key value
Trg = (~Cont) & ReadData; // 2 Get the press trigger value
Release = Cont & (~ReadData); // 3 Get the release trigger value
Cont = ReadData; // 4 Get all unreleased key values
}
This will help you better understand the meaning of Trg, Release, and cont. Take Trg as an example. It is 1 only when Cont=0 and ReadData=1, which corresponds to the rising edge of the ReadData waveform (because ReadData is inverted, the rising edge corresponds to the falling edge of the IO port waveform when the key is pressed).
Since it is to be used on a 51 board, the program has been modified accordingly. Four independent buttons are used here, corresponding to P1.0-P1.3 of P1 port. At the same time, the names of the variables are changed for easier understanding.
Trig---KeyPressDown represents the edge corresponding to the key being pressed.
ReadData---CurrKey The key value currently read is inverted, so that when the key is pressed, the corresponding bit is 1.
Cont -----LastKey The last key value
Release-----KeyRelease The edge corresponding to when the key is released
The program after modification to 51 is
#define KEYMASK 0x0f
//Button variables
unsigned char KeyPressDown = 0x00;
unsigned char KeyRelease=0x00;
unsigned char LastKey=0x00;
//Scan the buttons, execute once every 10ms
void KeyScan(void)
{
//The key value currently read
unsigned char CurrKey;
P1|=KEYMASK; //Set the IO corresponding to the key to input status
CurrKey=(~P1)&KEYMASK;
KeyPressDown=(~LastKey)&CurrKey;
KeyRelease=LastKey&(~CurrKey);
LastKey=CurrKey;
}
In order to test the program, I didn't think of a good way. I counted the keys with my eyes closed, counted the KeyPressDown, and then used the digital tube to display the count value. If I pressed 100 times, the digital tube should also display 100. But I tried all four keys, and there were several more than 100. I used an oscilloscope to look at the waveform of the IO port. In most cases, the waveform is a rectangular wave. Only in some cases, there will be an interference pulse (that is, jitter) at the moment of pressing or releasing. The program uses 10ms timing sampling. Since there is no correlation between the two, if the sampling happens to be at the moment of the interference pulse, this may cause the key to trigger multiple events in one key press.
If the key IO port is seriously interfered or the key contact is poor, a negative pulse may be generated when the key is not pressed, or a positive pulse may appear when the key is pressed steadily. Such a pulse may not be very wide, but once it is detected and sampled by the 10ms timing sampling of the program, it will cause a false trigger operation. Increasing the sampling time can reduce the probability, but it cannot be avoided.
In order to improve the algorithm and solve the problem of false triggering caused by interference pulses, I searched the Internet for a long time and finally found a blog post "A method of removing key jitter with software" and used it as a reference.
http://blog.csdn.net/meiyuli/article/details/5133708
http://z86k.blog.163.com/blog/static/90796156200962012657976/
The core algorithm is
Keradyn=Ktemp Kinput+Kreadyn-1 (Ktemp ⊙Kinput) (1)
Ktemp=Kinput (2)
To facilitate understanding, the variable names were modified again and additional variables were added.
LastReadKey represents the key value read by the last KeyScan() sampling
CurrReadKey; //Record the key value read by this KeyScan() sampling
LastKey represents the key value of the last valid judgment (the actual key value after logical judgment or correction)
CurrKey represents the effective judgment key value of this time.
According to the logical
CurrKey=(CurrReadKey&LastReadKey)|LastKey&(CurrReadKey^LastReadKey) (1)
Determine CurrKey: If the key values read by the last LastReadKey and the current CurReadKey are both 1, then the current valid key value CurrKey must be 1; if the key values read last and currently are different, then they are consistent with the last valid key value LastKey. This method is used to eliminate interference pulses.
The algorithm requires that the width of the interference pulse must be less than the program timing sampling period. If the program timing sampling is 20ms, then the interference pulse width must be less than 20ms. In fact, if the IO key interference pulse is greater than 20ms, it is necessary to consider whether there is a problem with the hardware design, or a filter capacitor should be connected to the key IO port.
Finally, the program after integrating the two algorithms is given
//Button variables
unsigned char KeyPressDown = 0x00;
unsigned char KeyRelease=0x00;
unsigned char LastKey=0x00;
//Scan the buttons, execute once every 10ms
void KeyScan(void)
{
static unsigned char LastReadKey=0x00; //Record the IO port key value read by KeyScan() last time
unsigned char CurrReadKey; //Record the IO port key value read by KeyScan() this time
unsigned char CurrKey; //Record the effective key value after debounce processing
P1|=KEYMASK; //Set the IO corresponding to the key to input status
CurrReadKey=(~P1)&KEYMASK; //Invert
//The debounce principle is very simple:
//If the key values read by LastReadKey and CurReadKey are both 1, then the current valid key value CurrKey must be 1
//If the key value read last time is different from the current one, keep it consistent with the last valid key value LastKey.
//To eliminate jitter in this way, the jitter time must be less than the keyscan() timing scan cycle, otherwise an error will occur.
CurrKey=(CurrReadKey&LastReadKey)|LastKey&(CurrReadKey^LastReadKey);
//Record key presses and releases
KeyPressDown=(~LastKey)&CurrKey;
KeyRelease=LastKey&(~CurrKey);
LastReadKey=CurrReadKey;
LastKey=CurrKey;
}
After downloading to the microcontroller, the old method is used for testing. This time, after pressing 100 times, the digital tube displays 100. It is much more stable than before. As for the performance of the key scanning program, it needs to be proved in future applications.
Previous article:A keyboard scanning program for a 51 single-chip microcomputer, the algorithm is simple and effective
Next article:51 UART configuration process
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- IoT Smart Parking Solutions
- Small and exquisite screenshot software
- EPWM1 A and B pulses are not complementary
- Find the parameters of the low-pass filter
- How to assign initial values to a continuous RAM range in C2000 chip
- [AT-START-F425 Review] Real-time Clock (ERTC)
- Bone vibration sensor and high-quality voice calls (including working principles)
- How to quickly improve the level of embedded systems?
- [Sipeed LicheeRV 86 Panel Review] 2-Use the shell to control the LED flashing
- Millimeter wave sensors