Estoy usando un PIC16F877A, corriendo a 20 MHz.
Tengo dos teclas en paralelo, 3 columnas y 4 filas. Mi configuración es la siguiente:
KR1 a KR4 son filas, KC1 a KC3 son columnas, y todas van al microcontrolador.
En el programa, las filas se configuran como salidas digitales y las columnas se configuran como entradas digitales. Otros periféricos de los pines están deshabilitados. La forma en que escaneo las teclas es la siguiente:
Hago que la primera fila sea ALTA, luego verifico la columna 1, la columna 2 y la columna 3. Si alguna de ellas es ALTA, entonces espero un poco y verifico nuevamente para deshacer el rebote. Si aún está en ALTO, el programa decide que se presiona una tecla. Esta rutina sigue para las otras 3 filas.
Verifico el teclado cada 100 ms, y para cada fila, toma aproximadamente 2.4uS como medí con el osciloscopio. Eso, supongo, significa, para un dígito específico; póngalo en alto y luego intente medir aproximadamente 800 nS, si no sucede nada, continúe.
Así que el problema era extraño. Cada dígito trabajado, excepto de '0'. Funcionó al azar y ese azar significa raramente al mismo tiempo. Además, cuando intenté medir su voltaje al suelo con un multímetro en modo de voltios de CC, y luego presioné el botón al mismo tiempo, funcionó con cada pulsación.
Luego agregué un retraso de 5 uS después de hacer la fila específica ALTO y luego revisé las columnas. ¡Funcionó!
Ahora, ¿cuál es el problema aquí? Los cables del teclado tienen una longitud de unos 30 cm (~ 12 pulgadas). ¿Es algún tipo de problema en la línea de transmisión, como si estuviera agregando un retraso? O si el problema proviene del microcontrolador; ¿El microcontrolador no es lo suficientemente rápido?
Aquí hay una parte del código que es relevante para el problema:
...
KEY_R4 = 1;
delay_us(5);
if (KEY_C1)
{
scan_keys.waitstate = 10;
goto c4r1;
}
else if (KEY_C2)
{
scan_keys.waitstate = 11;
goto c4r2;
}
else if (KEY_C3)
{
scan_keys.waitstate = 12;
goto c4r3;
}
else
{
KEY_R4 = 0;
presstime = 0;
}
...
c4r2:
if (++presstime >= PRESSTIMEVALUE && !KEY_C2)
{
scan_keys.waitstate = 0;
KEY_R4 = 0;
return '0';
}
return 'n';
...