Development of PS/2 Keyboard Driver Based on Small RTOS51

Publisher:koimqerolulkLatest update time:2012-02-01 Source: 单片机与嵌入式系统应用 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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.

Reference address:Development of PS/2 Keyboard Driver Based on Small RTOS51

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

New hybrid transaxle (P810) system technology analysis
Toyota unveiled a hybrid version of the new Hilander mid-size SUV (U.S. version) at the New York International Auto Show in April 2019, and it will be available on the market from February 2020. The model is equipped with a newly developed hybrid transaxle (P810). Brief Introduction of New Hybrid Transaxl
[Embedded]
New hybrid transaxle (P810) system technology analysis
Development and implementation of I2C device driver under Linux
1 Introduction The I2C (Inter-Integrated Circuit) bus is a two-wire serial bus developed by PHILIPS for connecting microcontrollers and their peripherals. The main advantages of the I2C bus are its simplicity and effectiveness. Since the interface is directly on the component, the I2C bus occupies very little sp
[Microcontroller]
Development and implementation of I2C device driver under Linux
Huawei's OLED driver IC will be mass-produced next year, and the localization process of driver chips may be accelerated
In recent years, with the continuous efforts of domestic panel manufacturers, my country's OLED panels have made significant progress in technology and commercialization, and the market share has increased year by year. However, the only drawback is that my country is very dependent on imports for OLED driver ICs, whi
[Mobile phone portable]
Huawei's OLED driver IC will be mass-produced next year, and the localization process of driver chips may be accelerated
LED lamp driver power matching solution
Now let's take an 18" LED tube as an example to analyze the design ideas: Let's take the most commonly used 3528 lamp beads as an example. When LED lamp tubes first came out, due to the large price gap, light strip manufacturers all used LED chips with high current consistency and high brightness. The current of this
[Power Management]
Application of 4 common motor drive systems in new energy vehicles
China's automotive motors have obvious comparative advantages under global resource conditions and have great development potential. From the perspective of the industrial chain of new energy vehicles, the beneficiaries will mainly focus on the field of core components. The current situation of the domestic automoti
[Embedded]
Application of 4 common motor drive systems in new energy vehicles
Design of white LED driver based on TPS61040/41
The TPS61040/41 is a high-frequency, low-power boost converter designed for small and medium-sized LCD bias and white LED backlighting. It can generate an output voltage of up to 28V from two NiMH/NiCd batteries or a single Li-ion battery. The switching frequency of the TPS61040/41 is up to 1MHz, and the power consump
[Power Management]
Design of white LED driver based on TPS61040/41
Analysis and study of mini2440 I2C driver (Part 2)
Then analyze the i2c data transmission process. First, open the i2c device, such as open("/dev/i2c/0"), and call the following function in the kernel static int i2cdev_open(struct inode *inode, struct file *file) { unsigned int minor = iminor(inode); struct i2c_client *client; struct i2c_adapter *adap; str
[Microcontroller]
Proportional solenoid drive circuit
The proportional solenoid drive circuit is shown in Figure 1. In the drive circuit, R1 is a current limiting resistor that turns on the IRL3803 tube; D1 is a guide diode that provides the correct voltage polarity to the IRL3803 tube; and diode D2 plays a protective role to prevent damage to the proportional solenoid w
[Power Management]
Proportional solenoid drive circuit
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号