introduction
With the development of embedded systems, embedded software design is moving closer to software platforms. Microcontroller software design is no longer a single-threaded structure, but gradually adopts a multi-task design concept. Real-time operating systems make it easier to design, expand, and maintain real-time applications, and new functions can be added without major changes. However, as the number of tasks increases, the data required to be input will also increase, and the types will also be diversified. If the matrix scanning keyboard is still used, it will inevitably waste huge resources of the microcontroller and increase costs. If it is replaced by a standard PC PS/2 keyboard, the above contradictions can be resolved. This article introduces the design of a PS/2 keyboard driver based on the real-time operating system Small RTOS51, which has the advantages of fast response, strong portability, and low resource consumption.
1. Driver design
Drivers can be implemented in the following ways: ① Using tasks; ② Using messages; ③ Using semaphores. PS/2 keyboards do not require CPU cycle services and do not have their own interrupt devices. However, in order to achieve real-time response, this driver uses interrupts, uses global variables to transfer data, and wakes up processing tasks in the interrupt service program.
1.1 Interrupt Service Routine
The driver uses interrupts to receive partial scan codes of keys and caches them using global variables. Use a task to process these scan codes to obtain key values. By analyzing the scan codes of various keys, the scan codes can be divided into the following three cases: a. Ordinary keys. The pass code is a byte that uniquely identifies itself; the break code is 2 bytes. The first byte is F0H, and the second byte is the pass code. b. Function keys, such as CTR. The first byte of the pass code is E0H, and the second byte is the identification code that distinguishes it from other keys; the break code has 3 bytes, namely E0H, F0H and the identification code. c. Combination keys, such as G. The key sequence to get G is: press shift, press g, release g, and finally release shift. So the scan code should be: 12H, 34H, F0H, 34H, F0H, 12H.
From the above analysis, we can know that no matter what kind of key is pressed, as long as we know the first two bytes of the scan code, we can determine which key or key combination is pressed, and find the corresponding ASCII code by looking up the table. In this way, by only receiving 2 bytes, the number of interrupts can be greatly reduced, saving CPU resources. The interrupt program is as follows:
void Receive() interrupt 0 {
IE0=0;
dat>>=1; //Receive data, low→highif
(sda) dat|=0x80;
count++;
if(count==num) {
if(num==9) {
temp[0]=dat;
num=20;
}
else {
temp[1]=dat;
IE&=0xfe;
count=0;
num=9;
OSSendIntSignal(KeyCodeTranst_ID);
OSIntExt();
}
}
}
The program first calls the macro OS_Int_ENTER() according to the interrupt writing specification of Small RTOS51. If the user disables interrupt nesting management (EN_OS_Int_ENTER=0), then there is no need to call the macro. Next, receive the first two bytes of the scan code and store them in the array temp[2]. When it is determined that the reception is completed (count==20), the receive interrupt must be turned off to refuse to receive the subsequent scan codes sent by the keyboard. Then, directly call OSSendInt-Signal(KeyCodeTranst_ID) to make the key code conversion processing task ready. Finally, call the function OSIntExt() according to the interrupt writing specification of Small RTOS51 to notify the exit of the interrupt service program and perform task switching.
1.2 Key code processing task design
This task can be completed in the interrupt service, but in order to avoid receiving the latter part of the scan code, a certain delay must be made after receiving the first two bytes. If it is completed in the interrupt service, the interrupt delay will be increased. The key code processing task design mainly completes the first two bytes of the scan code returned from the interrupt service program, determines what type of key is, and finds the corresponding ASCII code by looking up the table. The task source code is as follows:
KeyCodeTranst() {
uint8Key;
PS2Int();//Keyboard initialization
OSQCreate(Key_ASCII,16);//Create a queue to store key ASCII code data
while(1) {
OSWait(K_SIG,0);//Wait for key
IE&=0x0fe;//Shield useless scan code
if(temp[1]==0xf0&&temp[0]!=0xe0)Key=noshift[temp[0]];//Key code conversion
else if(temp[0]==0xe0&&temp[1]!=0xf0)Key=noshift[temp[1]];
else if(temp[0]==0x12||temp[0]==0x59)Key=addshift[temp[1]];
OSWait(K_TMO,5);//Delay 5 ticks
IE0=0;
IE|=0x01; //Prepare to receive the next key press
OSQPost(Key_ASCII,Key); //Send ASCII code
}
}
The task first creates a message queue to store the ASCII codes of the keys, and then initializes PS2Int() for the PS/2 keyboard. During the initialization, you can simply start the interrupt used, or you can add some other user programs to this function.
The following service function begins to enter an infinite loop. OSWait(K_SIG,0); is the waiting signal. When the interrupt program receives the scan code, it will wake up the task through the function OSSendIntSignal(KeyCodeTranst_ID). At this time, the array temp[2] stores the first two bytes of the current key scan code:
If temp[1] is 0xf0 and temp[0] is not equal to 0xe0, it means it is a normal key. You can find the corresponding ASCII code by looking up the table noshift[temp[0]].
If temp[0] is 0xe0 and temp[0] is not equal to 0xf0, it means it is a function key. You can find the corresponding ASCII code by looking up the table noshift[temp[1]].
If temp[0] is 0x12 or 0x59, it means it is a combination of shift and a normal key. You can find the corresponding ASCII code by looking up the table addshift[temp[1]].
Then, the receiving key interrupt is turned off, and the function OSWait(K_TMO, 5) is called to delay 5 clock cycles to shield the remaining scan codes of the key. Finally, the obtained key ASCII code is sent to the message queue to wait for other tasks to perform corresponding processing.
2 Driver transplantation and use
This driver uses the resources of the 51 series microcontroller to connect one interrupt (external interrupt 0) and one common I/O port to the CLK and SDA of the PS/2 interface respectively. When porting, you must first define CLK and SDA in config.h, for example:
SbitSDA=P1^0;
SbitCLK=P3^2;
It is also necessary to define the priority of the key code processing task, #define KeyCodeTranst_ID 0. After these definitions, the driver can be moved to the operating system for use. When using it, you don't need to know how to implement it specifically, just call OSQPend (&Val_Key, Key_ASCII, 0) to get the ASCII code of the key, and then do the corresponding processing according to the ASCII code.
Conclusion
This driver does not initialize the PS/2 keyboard. As long as the power is on, the PS/2 keyboard will be initialized according to the default settings. Since there is no initialization, the keypad can only be used as the corresponding function keys, but not as numeric keys. Those who are interested can complete the initialization program.
References
[1] Chen Mingji, et al. Principles and Applications of Embedded Real-time Operating System Small RTOS51. Beijing: Beijing University of Aeronautics and Astronautics Press, 2004.
[2] Zhang Xiaohui. Embedded Operating System Driver Development. Journal of Anhui Electrical Engineering Vocational and Technical School, 2005(3).
[3] Zheng Wei, et al. Design of PS/2 Keyboard Driver in Single-Chip Microcomputer System. Single-Chip Microcomputer and Embedded System Application, 2005(4).
[4] Li Hua, et al. Practical Interface Technology of MCS-51 Single-Chip Microcomputer. Beijing: Beijing University of Aeronautics and Astronautics Press, 1993.
Previous article:Design of Background Debug Mode for Embedded Microcontroller MC68HC912B32
Next article:Research on wheeled intelligent robot based on distributed control system
Recommended ReadingLatest update time:2024-11-16 17:40
- Popular Resources
- Popular amplifiers
- Siemens Motion Control Technology and Engineering Applications (Tongxue, edited by Wu Xiaojun)
- Modern Product Design Guide
- 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)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Homemade IHM08M1 board based on FOC SDK5.3 library BLDC or PMSM motor drive: program + schematic + BOM and other all open source sharing
- How to convert the UCF file of FSM and MLC function configuration of LSM6DSOX into C code and embed it into MCU?
- About STM32 SDRAM reading and writing issues
- Live: TI Robot System Learning Kit is sweeping campuses. Can it become a practical tool for university electrical engineering courses?
- Which Little New Year's Eve should people from the south celebrate in the north?
- [Top Micro Intelligent Display Module Review] 6. The birth of a motor application platform based on the development board NUCLEO-F746ZG
- Is there a set of GD32 boards that you like?
- How to Design an RF Power Amplifier
- Summary of RC, LC, and RL circuit characteristics
- [Atria Development Board AT32F421 Review] - TEST04 Fast ADC Test