1 Introduction
In many embedded systems, especially those with frequent human-machine interaction (HMI), keyboards are the most widely used input devices. Due to the functional heterogeneity of embedded devices, it is not feasible to provide a universal keyboard for them. Generally, it is necessary to design the required special keyboard according to the actual functions of the embedded system and implement the corresponding driver. www.51kaifa.com
The common way to expand the keyboard on embedded devices is to use the CPU's GPIO port scanning. Obviously, this method will occupy the system's GPIO resources, especially in systems with tight GPIO resources and many keys. This problem is particularly prominent. Of course, it can also be achieved by expanding the GPIO (such as 8255, etc.) or expanding a dedicated keyboard interface (such as 8279, etc.), but this method obviously increases the complexity of the system and is quite inconvenient in actual system design.
This paper takes the implementation of a POS keyboard (8×8) on an ARM9 (AT91RM9200) embedded microprocessor as an example, presents a new design idea for extending multi-row and column keyboards on embedded devices, and implements the keyboard driver on the ARM-Linux system.
2. Hardware design of interface circuit
This article uses a design example to illustrate how to use a relatively simple method to implement an 8×8 POS machine matrix keyboard. The microprocessor used in the POS machine is the AT91RM9200 chip. AT91RM9200 is a high-performance 32-bit ARM9 processor produced by ATMEL. It is a general-purpose industrial-grade ARM chip that has been widely used in industrial control, intelligent instrumentation and other fields [3,4]. For detailed chip characteristics, please refer to the literature [2].
The keyboard expansion on AT91RM9200 is generally achieved through its GPIO port. Although AT91RM9200 provides 4×32 programmable GPIO ports. However, in order to reduce the chip size and power consumption, many of its GPIO ports are multiplexed with the system's peripheral device controller ports or address lines and data lines, so there are actually very few GPIO ports that can be used for expansion. For an 8×8 keyboard, if the traditional GPIO port expansion method is used, 16 GPIOs are required, which is difficult to meet in a more complex POS system, so other methods are needed to solve this problem.
Figure 1 Keyboard interface schematic
This article uses data latching to fully utilize the data width advantage of the 32-bit processor and uses data lines to replace the GPIO ports required for keyboard expansion, thereby reducing the occupation of system GPIO resources. The implementation principle of the keyboard interface is shown in Figure 1. In the circuit shown in Figure 1, U1301 (74LVCC4245) is a three-state buffer, and U1302 (74HC574) is a latch. The working principle of the system is described as follows:
The nOE end of U1301 is connected to the decoding output nKey_CS of the system. The component address is determined by the system decoding circuit. When writing data to this address, the nKey_CS signal is low level, and the data can pass through U1301. At the same time, the nKey_CS signal is delayed by two stages of inverters and used as a latch signal to latch the data to the output end of U1302 as the row scan signal of the keyboard, while the column scan signal of the keyboard still uses the system GPIO. Sending low-level signals to each row in turn and detecting the column signal connected to the GPIO at the same time can realize the scanning of the keyboard. In this system, only the lower 8 bits of the system's 32-bit data are used as row scan signals. In the case of realizing 8×8 matrix keyboard scanning, only 8 GPIO ports are needed. If the same method is used, using 16-bit data or 32-bit data as row scan signals, only 4 or 2 GPIOs are needed. Obviously, compared with the traditional method, this method can greatly save the system's GPIO resources. [page]
3. Keyboard driver module design
After completing the design of the interface circuit, you need to write the corresponding keyboard driver module. This article uses the AT91RM9200 chip which already runs the ARM-Linux operating system, which provides great convenience for the development of the keyboard driver. The keyboard driver module can be divided into three parts: hardware initialization, implementation of file operation functions, and keyboard scanning program.
3.1 Hardware Initialization
The development model of the keyboard driver is similar to the driver development steps of general character devices in the Linux system. For a detailed analysis of Linux device driver development, please refer to the literature [1]. The first thing to be completed is the initialization function and clearing function of the driver module. In the initialization function, in addition to completing the module registration, hardware initialization should also be performed. The following is the pseudo code of hardware initialization in the module initialization function based on the characteristics of the GPIO controller of the AT91RM9200 chip [2].
…
Set the GPIO port used to be controlled by the GPIO controller
Set the type of the GPIO port used to input
Enable input glitch filtering for the used GPIO ports
Enable the corresponding GPIO controller clock
Get the virtual address of the specified address and write data 0x0 to the address
…
3.2 Implementation of file operation functions
Because the keyboard generally only plays an input role in the system, the only file operation function that must be implemented in the file_operations structure of the keyboard driver is the file read function.
In addition, in actual applications, in order to prevent the loss of keyboard keys, the scan code of the pressed key is usually placed in a buffer until the application is ready to process a key. The size of the buffer generally depends on the needs of the application system. In this example, the buffer size is taken as 20 key codes. The buffer is implemented in the form of a circular queue. When a key is pressed, the scan code will be placed in the next empty position of the queue. If the buffer is full, the next key will be discarded. The application uses the keyboard read function read() to read the required number of key codes from the buffer position pointer; after completing the read operation, the key code that has been read must be deleted from the buffer queue and the buffer position pointer must be updated. The following is the pseudo code of the keyboard read function key_read() implemented in this example:
ssize_t key_read(……)
{
Define and initialize variables;
if the number of keys available for reading in the buffer is greater than 0;
Get the spin lock of the key code storage buffer;
Calculate the number of codes M that can be read in this read operation (the smaller of the number of codes that can be read in the buffer and the number required by the program);
Starting from the buffer position pointer, copy M key codes from the buffer to the user space buffer;
Update the buffer's position pointer and the number of key codes remaining in the buffer;
Release the spin lock
Returns the number of codes successfully read in this read operation.
Else
Returns -1
}[page]
3.3 Keyboard Scanner
The working principle of the keyboard is to determine whether any key is pressed by the state of the row and column lines of the keyboard. The function of the keyboard scanning program is to determine the specific position of the key in the pressed state and obtain the corresponding key code value. Therefore, the design of the scanning program is the core of the keyboard driver module.
There are two main ways to implement keyboard scanning programs, namely polling mode and interrupt mode [5]. In this example, the keyboard driver is designed by combining the operating system timer queue with the polling scanning mode, mainly based on the following two reasons. First, the interrupt signal line of the AT91RM9200 chip is a very valuable hardware resource. Each group of GPIO ports is only configured with one interrupt signal line, that is, 32 GPIO ports share one signal line. In this way, if the interrupt mode is used, at least one chip interrupt signal line needs to be occupied. For a keyboard with multiple rows and columns, if the GPIO ports used are not from the same group, multiple interrupt signal lines need to be occupied. Moreover, if the GPIO ports used by other devices belong to the same group as the GPIO ports used by the keyboard, then in the driver design of the two devices, interrupt sharing must be performed. This not only makes the system software design more complicated, but also easily causes problems such as interrupt loss and interrupt race, which affects the performance of the device. Second, the keyboard is a relatively low-speed device in the system, and the polling mode can fully meet the input requirements of the keyboard.
The ARM-Linux operating system provides a good timer mechanism. Therefore, through simple timer operations, it is possible to scan the keyboard status at fixed intervals and process key events. The size of the fixed interval can be configured according to system requirements. For detailed operations of the definer, please refer to the document [1]. As mentioned above, the function of the keyboard scanner is to judge and process the status of the keyboard. If no key is pressed, the scan returns directly; if a key is pressed, the position of the pressed key is judged and the corresponding key code value is written into the buffer. Because the keyboard in this example is configured for a POS machine, the accuracy of the key press is crucial. Therefore, the key value is verified multiple times in the scan code. The following is the pseudo code of the keyboard scanner used in this example:
int Scan_Keyboard()
{
Define and initialize variables;
Get the spin lock of the key code storage buffer;
if there is space in the buffer;
① Determine the status of each GPIO port in turn. If there is no low level, no key is pressed, and exit the if statement directly; otherwise, a key is pressed, and the row line connected to the currently tested GPIO port is the row where the key is located;
② Send high level to the data lines connected to the keyboard column lines in turn, and then determine the level state of the GPIO port where the key row line is located to get the column where the key is located;
Delay for a short time to eliminate keyboard jitter;
③ Then send low level to all the data lines connected to the keyboard column lines, and use code segment ① to determine again whether there is a key pressed. If so, get the row where the key is located;
④ Use code segment ② to re-determine the column where the key is located;
⑤ Determine whether the row and column of the key obtained for the first time are exactly the same as those for the second time. If they are exactly the same, proceed to the next step, otherwise exit the if statement;
⑥ Re-send low level to all data lines connected to the keyboard column lines, and determine whether the key is popped up. If it is still in the pressed state, continue to wait, otherwise convert it into the corresponding key value according to the row and column, and write it into the buffer;
The if statement ends;
Release the spin lock;
The function returns 0;
}
After completing the driver code writing, the keyboard driver can be loaded into the ARM-Linux kernel, either statically or dynamically. After loading, the keyboard is programmed and used in the application in the same way as other character devices. The keyboard designed using the method described in this article has been configured in the POS machine developed by the author and is being used by users. According to user tests, the keyboard's input accuracy and response time have met the design requirements.
4. Conclusion
Based on the AT91RM9200 system running ARM-Linux, this paper proposes a new design method for expanding special keyboards on ARM9, and explains in detail the hardware design and driver software development of keyboard expansion. This design method uses data latching to replace conventional GPIO expansion, improving the resource utilization of system hardware. This idea also provides a new design idea for expanding multi-row keyboards in other embedded devices.
References
[1] Wei Yongming, Luo Gang, Jiang Jun (translators). Linux Device Drivers (Second Edition) [M]. China Electric Power Press. April 2002
[2] ATMEL. AT91RM9200 User Manual. 2005
[3] Zhang Xiusong. Design of embedded industrial control system based on AT91RM9200[J]. Microcomputer Information, 2006, 1-2:45-47
[4] Wang Jianzhong, Tian Li, Wu Ling. AT91RM9200 microcontroller based on ARM920T core and its application in embedded home gateway [J]. Microcomputer Information, 2004, 20(5):49-51
[5] Ma Zhongmei. ARM&Linux Embedded System Tutorial[M]. Beijing University of Aeronautics and Astronautics Press. September 2004
Previous article:A LCD screen interface design based on S3C2410A
Next article:Research on SQLite Embedded Database Based on ARM-Linux
Recommended ReadingLatest update time:2024-11-16 17:55
- 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
- 【XMC4800 Relax EtherCAT Kit Review】01- Unboxing Photos---Kangaroo Brother
- Isolation and filtering of electromagnetic waves
- Designing Accurate and Versatile Li-ion Battery Testing Solutions
- Find library component modifications
- Please recommend a 485 automatic transceiver chip, 3.3V version.
- Which environment setup tutorial should I watch? -- ESP series development environment setup video navigation directory
- CC2640R2F-Q1 uses low-power Bluetooth technology to transform car access control systems
- Problems with opening KEIL in WIN10
- MSP430 MCU Development Record (25)
- BK3432 BK3432 BLE Bluetooth Chip DataSheet & Hardware Layout Guide