During initialization, all rows (output port) are forced low (see Figure 3.2). When no key is pressed, all columns (input port) read high. Any key closure will cause one of the columns to go low. To see if a key has been pressed, the microprocessor only needs to see if any of the input lines are low. Once the microprocessor has detected that a key has been pressed, it needs to find out which key it was. This process is quite simple. The microprocessor outputs a low on only one of the rows. If it finds a 0 on the input port, the microprocessor knows that the key closure occurred on the selected row. Conversely, if the input port had all highs, the key pressed was not on that row and the microprocessor selects the next row, repeating the process until it finds the row. Once the row has been identified, the specific column of the pressed key can be established by locating the position of the single low bit on the input port. The time required for the microprocessor to perform these steps is very short compared to the minimum switch closure time and it is thus assumed that the key will remain pressed during that interval.
To filter through the bouncing problem, the microprocessor samples the keyboard at regular intervals, typically between 20 mS and 100 mS (called the debounce period) depending on the bounce characteristics of the switches being used.
The scan code of the key pressed is typically placed in a buffer until the application is ready to process a keystroke. Buffering is a handy feature because it prevents losing keystrokes when the application cannot process them as they occur. The size of the buffer depends on your application requirements. A buffer size of 10 keystrokes is a good starting point. The buffer is generally implemented as a circular queue. When a key is pressed, the scan code is placed at the next empty location in the queue. When your application obtains a scan code from the keyboard module, the scan code is extracted from the oldest location in the queue. If the queue is full, any further keystrokes are lost.
Another nice feature is what is called auto-repeat or typematic. Auto-repeat allows the scan code of a key pressed to be repeatedly inserted into the buffer for as long as you press the key or until the buffer fills up. Auto-repeat capability is nice to have if you plan on incrementing or decrementing the value of a parameter (i.e., a variable) without having to continuously press and release the key. The timing diagram of Figure 3.3 shows how auto-repeat works. The scan code of the key pressed is inserted in the buffer as soon as the closure is detected. If the key is held down longer than the auto-repeat start delay, the scan code is again inserted in the buffer. From then on, if the key remains pressed, the scan code will be inserted in the buffer every auto-repeat delay.
Was this article helpful?