A key switch is one of the basic input sources for a microcontroller. This section explains how a key switch signal is captured by a microcontroller.
To capture a key switch signal with a microcontroller, an input port of the microcontroller is used. An example of the basic configuration is shown below. In this example, input port P70 pin goes high when the key switch is not pressed (off), and goes low when it is pressed (on). When P7 is read by program, therefore, the key switch is not pressed if bit 0 is 1 and pressed if bit 0 is 0.
[Countermeasures against chattering]
The operating principle is as described above. However, the above example cannot be put into a practical use as it is because a switch is, in general, a mechanical component and has chattering. Therefore, the port must be read at specific time intervals. This is called sampling, and an image of sampling is illustrated below. Circles in this illustration indicate the reading (sampling) timing of the port, and indicate that the port is read periodically. The time of sampling should be longer than the time for which chattering occurs. It must be longer when variations and degradation of components are taken into consideration. By sampling the port, the envelope of the signal can be easily obtained and countermeasures against chattering can be taken. As it is, however, noise may be misunderstood as a signal if it occurs on the signal when sampled. To prevent noise from being taken as the signal, the signal is sampled two or more times in a row. If the same status of the signal is sampled successively, it is assumed that the value of the signal is correct. For a specific program, refer to [Chattering prevention processing].
[Key return interrupt/key interrupt] (78K0/Kx2)
As described above, data is captured from a key switch by periodically checking the port. In an actual application, however, the microcontroller may be used in such a way that it is kept in standby state to reduce power consumption and returns to the operating state when a key is pressed. For this, an interrupt is used. There is an interrupt designed for such an application in addition to the ordinary interrupt by edge detection. This interrupt is called a key return interrupt.
The key switch shown in the above example is usually keeps high level, and goes low when the key is pressed. The key return interrupt generates an interrupt by detecting this low level. The difference from the ordinary interrupt by edge detection is that it can detect the low level of any one of eight input signals KR0 to KR7.
The key return interrupt detects if a key is pressed and releases the microcontroller from standby state so that the CPU starts operating. After that, the port (P7) is read to confirm the key that is pressed.
The key return interrupt of the 78K0/Kx2 can be configured by combining a key for ordinary key input and a key for releasing the standby state because it has a mask function in bit units. In the following configuration, for example, eight key switches are used and pulled up by the internal pull-up resistors of the microcontroller. Key return interrupts are used for #1 to #4 connected to P70 (KR0) to P73 (KR3), and not used for #5 to #8 (masked by KRM). When one of the keys from #1 to #4 is pressed, standby state is released by a key return interrupt. However, standby state is not released when any of keys from #5 to #8 are pressed because no key return interrupt is generated. Keys can be used differently like this.
[Key detection by ordinary interrupt]
If a key cannot be detected by a key return interrupt, an ordinary edge detection interrupt input is used. Because the number of edge detection interrupts is limited, however, something has to be done about it. In the following example, Px0 to Px7 used for scanning keys are N-ch open-drain output ports. When an ordinary CMOS output port is used, a diode is connected in the direction shown in the figure, so that current does not flow out from the output port (refer to "Other ways").
In this way, a low level is output to one of the output ports for key scanning and the status of the INTPn pin at that time is monitored so that the status of a key is detected. If key #2 shown below is pressed, for example, the INTPn pin goes low only when Px1 connected to this key is low, and it goes high when any other output is low. In this way, it can be judged which key is pressed. Because the key is checked one by one, the keys must be scanned eight times in the worst case to identify the one that is pressed.
In this example, an interrupt is generated when one of the specified keys is pressed, as is in the case of the key return interrupt. To generate INTPn when a key from #1 to #3 is pressed, for example, a low level is output to the corresponding Px0 to Px3. When the interrupt is generated, the keys are scanned again, starting from Px0, to identify the key that is pressed.
Other ways |
What can be done if the microcontroller does not have N-ch open-drain output ports and a diode cannot be connected?
In this case, 0 is set to all the output latches of the port, and only the port to which a low level is output is set to the output mode by the PM register.
The other ports are set to input mode. In this way, the N-ch open-drain output can be simulated. This method can also shorten the scan time because the line can be raised to high level.
If the number of keys to be used is small, keys can be connected directly to ports. If there are many keys, however, connecting keys to as many ports is not efficient. Therefore, a key matrix should be used in combination with the output ports. An example of a 4 x 4 matrix is shown below. It is assumed that the input ports are pulled up by an internal resistor. It is also assumed that the output ports are N-ch open-drain ports.
If #1 and #5 are pressed at the same time, lines 1 and 2 are connected via key switches #1 and #5. If the output ports are ordinary CMOS output ports at this time, both a high level and a low level are output, causing the device to be damaged and a current higher than that rate to flow through the key switches. To avoid a problem like this, N-ch open-drain output ports must be used for scanning the keys. Changing between the input mode and output mode of a CMOS output port as described in "Other ways " may be an option.
If #6 is also pressed along with #1 and #5, another problem occurs. When line 1 is scanned, line 2 also goes low via #1 and #5. If #6 connected to line 2 is pressed in this state, I2 input also goes low. In other words, it is misunderstood that #2, which is not pressed, is also pressed. This is because current flows through #5 in the direction opposite the original direction. One of the countermeasures against this is to connect a diode so that current flows only in one direction (as shown in the lower right figure).
Although connecting a diode eliminates the need for the N-ch open-drain output port, the cost is increased as a diode has to be connected to each key switch.
In some cases, therefore, a diode is connected only to a key that is likely to be pressed with another key.
This applies to the case where a mechanical switch with a low ON resistance is used. If the ON resistance of the wiring and switch increases to some extent, a resistor-divided voltage, rather than an ON/OFF signal, is input. In this case, the signal cannot go low if it goes through three switches like in the above example where three switches are pressed, and therefore, malfunctioning can be avoided.
When a key matrix is used, which key is pressed is identified by using an output port and sequentially making scanned lines low and reading them from input ports one by one. An example of scanning keys using the above key matrix is given below.
For a program example, refer to [Chattering prevention processing for key scanning].
If input to I1 is low when line 1 is made low (scanned), it means that #1 is pressed. Similarly, if input to I1 goes low while line 2 is scanned, it means that #5 is pressed. In this way, the key that is pressed is identified by the combination of scanned line and input.
Note 2 |
In the case of an open-drain output port, the status of an input port does not immediately go high even when scanning is complete and the output signal is raised to high level. It is the pull-up resistor that makes the input port high. Because the capacitance of the input line must be charged by the resistor, the signal is late in rising. If the scanning interval is short, the input signal that has gone low when key #1 is pressed while line 1 is scanned remains until line 2 is scanned, and it is judged that #5, which is not pressed, is pressed. Therefore, the timing of scanning and checking the keys is shifted as shown in the following example. The result of previous scanning is checked by a timer interrupt that triggers scanning, and then scanning for the next key is started and the processing of interrupt is completed. This gives a margin of time during which the signal changes for the scanning interval.
In addition, the rise time of a line can be shortened by outputting a low level, checking the key, and making the output high. This is useful when the method of setting an input port when low level is not output by using the ordinary CMOS output as described in "Other ways ". Controlling output data in addition to input/output takes efforts but can shorten the scanning interval.
[Chattering prevention processing]
Two program examples of that prevent chattering are given below. Both these programs eliminate chattering and noise by using the P7 of the 78K0/Kx2 for key input and checking the status of 8-bit key input in the periodic interrupt of the interval timer. To use other devices, change the port from P7 to one suitable for the device. If the number of bits is 8 or less, mask the unused bits after key data is read. Include and execute these programs in periodically executed timer interrupt processing.
[Program example 1]
(1)Overview of program
This program compares two results of scanning and performs the following processing depending on its result.
When the key shows a change: For the bit corresponding to the key, data of the previously valid key is used as is.
When the key is the same as the previously scanned key: For the bit corresponding to the key, the current key-scan result is used.
The key scan result is not captured unless the same value is input more than once in a row. Therefore, noise that happens to be sampled can be eliminated. Taking a case where two or more keys are pressed at random into consideration, a change is identified by performing an operation on each bit, instead of using conditional branching.
Valid key input obtained by this program is input to KEYDATA. KEYDATA is referenced by the program as data for result output and previously valid key input. In addition, OLDDATA is used for work to hold the previous key data.
The read key data is saved in the variable OLDDATA so that it can be used for the next scanning, and is compared (XOR) with the previous scanning result stored in OLDDATA, so that a change in key data is detected.
By inverting the logic of the XOR result, a bit that has changed is cleared to 0 and ANDed with the scanning result. As a result, the bit that has changed is cleared to 0 and the bit that has not changed indicates the scanning result.
Key data that has been obtained and unchanged is saved, and bits that have changed and the previous valid key input saved to the variable KEYDATA are ANDed. As a result, the bit whose key data has not changed is cleared to 0 and the bit that has changed indicates the previous data.
The final result can be obtained by ORing the two results by the above operations, and this result is saved to the variable KEYDATA.
[Program example 2]
This program can obtain information on changes in keys (keys that are pressed and keys that are released). It is based on the first example program with processing to detect changes added. When a new key is pressed (when key input data goes to 0), the corresponding bit of PUSHKEY is set. When the key is released, the corresponding bit of RELKEY is set. In this way, information on changes in keys can be obtained. Note that this information is not saved but updated each time a key is scanned.
Note 3 |
Up to the fifth line of the two programs, the bit changed at the second key scan data is set to 1, the unchanged bit is set to 0, and then the data is saved to the A and X registers. The second program is the same as the first program so far. The next two instructions are different, but the result that can be obtained is the same.
Because a bit of OLDDATA is used for a bit that has not changed (key is captured), the bit that has changed (bit that is 1 in A or X) must be cleared. In the first example, therefore, a complement of the data of the A register is taken and ANDed with OLDDATA to clear the bit that has changed. In the second example, the bit of OLDDATA that has changed is set to 1 by ORing the A register and OLDDATA, and cleared by exclusive-ORing it with the X register. For the relationship between these two operations, refer to the following expression.
[Chattering prevention processing for key scanning]
(1)Overview of program
The key matrix of 16 keys (4 x 4) given as the example before is considered. The higher 4 bits of P7 are used to scan data and the lower 4 bits are used to read it. (P7 is an ordinary CMOS output port. Therefore, a diode is connected to it so that current flows from a scanned line to the port, or a diode is connected to each key as described in "Note ".) Change the port to be read or scanned depending on the configuration of the port to be used and the device.
(2)Operation of program
This program uses two interrupts: key return interrupt and timer (timer 51) interrupt. It first selects line 1 without scanning keys and waits using the key return interrupt until any one of the keys from #1 to #4 is pressed. When one of keys from #1 to #4 is pressed and the key return interrupt is generated, the timer is activated and key scanning is started. After key scanning is started, a line is scanned whenever the timer interrupt is generated (about every 10 ms). It is executed in the following rotation.
Line 1 → Line 2 → Line 3 → Line 4 → Line 1 ...
Scanning all the lines is completed when the timer interrupt is generated four times. The result of scanning is sequentially stored in KEYDATA1 to KEYDATA4, starting from that of line 1.
(3)Data area (variable)
The basic processing is the same as [Program example 1] of [Chattering prevention processing] described above. Data areas that are used each time a key is scanned are defined as follows and initialized to 0FH. Because these areas are accessed using the HL register, they do not have to be allocated to the SADDR area. In addition, one variable (SCANLINE) is provided to specify a scan line.
Because the processing of the program is periodically executed, an interval timer interrupt is used. Therefore, the program is divided into a part for initialization and a part for the actual processing. Include and execute this initialization processing in the initialization routine of the device. This initialization part selects a mode of the port and sets timer and key return interrupts. In the default status, keys are not scanned, and it is set so that the key return interrupt is generated when a key from #1 to #4 of line 1 (corresponding to P77) is pressed. The timer is only initialized and stopped.
(5)Initialization processing related to key scanning
This part performs setting of the scan port, initialization of variables, and initialization of the key return and timer functions. The key return and timer functions are not started yet.
(6)Key scanning start-up processing by key return interrupt
When the key return interrupt is generated and this processing is started, the timer for key scanning is started. After that, the key return interrupt is disabled.
(7)Timer interrupt processing
Key scan processing is called as a subroutine from the processing of the periodically generated timer interrupt.
(8)Key scan processing
This part is started by the periodic timer interrupt and keys are actually scanned. This processing is divided into three major parts.
First, a pointer that stores the result of scanning is calculated. So as to decrease the number of input parameters and not to use conditional branching as much as possible, necessary information is obtained through calculation.
Next, scanned data is actually read from a port and countermeasures against chattering and noise are taken. If such strict processing is not necessary and only sampling is used to prevent chattering, it is sufficient to read scanned data from a port and save it to the data area.
Finally, preparation is made for scanning the next key. The scan line is changed to the next line, and data required to scan the new line is output to the port.
The processing of updating the scan line uses the fact that there are four scan lines, 0 to 3, which can be expressed by 2 bits. By adding one and masking bits other than the lower 2 bits, the new scan line can be obtained.
Data for specifying the line that is actually scanned is written to the port register. Data with only 1 bit cleared to 0 is used for it. Because only the higher 4 bits are used, however, simply rotating the data to the right is insufficient. The data of port is 1110XXX when lines up to line 4 have been scanned. Even if the data is rotated to the right as it is, bit 7 cannot be cleared to 0. Therefore, this program clears the carry only when line 1 (scan line) is 0, and sets the carry in cases other than that. The data is rotated to the right with a carry to clear bit 7 to 0 only when line 1 is scanned. The processing is performed in this way without using a conditional branch instruction.