Hello Mauricio,
You do not describe the manner in which the suggested code failed, or what you observed when you tested the code.
Your new function Escanear_Teclado() differs from the previous keyscan() function in two key areas -
- You have eliminated the test to determined whether any key is pressed, and hence the determination that all keys are released.
- You do not control the Salir variable to prevent multiple entry to the scanning process, once a keypress has been decoded.
However, to a more important issue . . .
I have just realized that all the code posted so far has the potential to damage the MCU and/or the keypad. This is because the columns that are not being scanned, during each cycle of the scanning process, are driven to a high output state. The single column that is being scanned is driven to a low output state. If two (or more) keys, within the same row, are pressed, this will result in a short circuit between two differing output states, with excessive current flow. This may damage the MCU, and if a membrane keypad type is used, might also damage the keypad.
Two solutions to this problem are possible, a harware solution and a firmware solution -
The hardware solution is to place a series schottky diode between each MCU output and its associated keypad column connection.
The preferred solution is the firmware solution. This requires that the non-scanned columns are never driven high. This is achieved by the following code changes -
- All bits of the keypad port are set low, and remain so at all times, i.e. PTA = 0;
- Pullups are enabled on all bits of the port, i.e. PTAPUE = 0xFF;
- When a column is to be scanned, its corresponding DDR bit is set for output. However, when not scanned the DDR bit must be cleared. This will require change to the Muestreo_Filas array, and the way it is used.
Changes to the previously suggested code are shown below.
/* Global variables */
byte Salir = 0;
byte Tecla_Presionada;
const byte Muestreo_Columnas[4] = {0x08, 0x04, 0x02, 0x01};
const byte RowDecode[16] = {
...
};
byte keyscan(void)
{
byte temp, i;
PTA = 0;
PTAPUE = 0xFF; /* Enable all pullups */
/* Check for any key pressed */
DDRA = 0x0F;
if (((PTA >> 4) != 0x0F) {
/* Check if keypress previously decoded */
if (Salir == 0)) {
Debounce(); /* Key debounce delay */
/* Commence scan for actual keypress */
for (i = 0; i < 4; i++) {
DDRA = Muestreo_Columnas[i];
Delayus(500); // Settling delay 500 us
temp = PTA;
if ((temp >> 4) != 0x0F) {
DDRA = 0x0F;
Salir = 1; /* Flag successful decode */
temp = RowDecode[temp >> 4] + i;
return temp; /* Return keypress value 0-15 */
}
}
}
}
else
Salir = 0; /* All keys released */
DDRA = 0x0F;
return 0xFF;
}
Regards,
Mac