Hay varias cosas que necesitan corregirse en tu código antes de que podamos comenzar a ayudar con los problemas funcionales. He enumerado algunas a continuación.
Uso de TRIS
Por favor, consulta la respuesta de Handoko, que trata sobre esto.
Uso de los registros LAT vs. PORT
Llamas a tu función de esta manera: Send1byte(getMatrixX(LATA))
. Supongo que tu intención es obtener el estado actual de los botones de entrada y enviarlos a esta función.
Esto no funcionará, necesitas leer desde el registro PORTA en su lugar. El código correcto sería Send1byte(getMatrixX(PORTA))
.
¿Por qué es esto? Hay una breve explicación en la hoja de datos:
Al leer el registro PORTA, se lee el estado de los pines; al escribir en él, se escribirá en el latch del puerto.
Y una imagen útil:
La línea de datos interna que se utiliza al leer el bit PORT (abajo a la izquierda, desde el bloque verde) está conectada al buffer de entrada, que proviene directamente del pin de E/S. En contraste, la línea de datos utilizada al leer el bit LAT (arriba a la izquierda, conectada al bloque rojo) solo lee el estado del latch de datos. No está conectada a la entrada.
Nota que las definiciones de SCK/DATA/SCL deberían funcionar (escribir en el bit PORT establecerá el LATch) pero generalmente mantengo todas las escrituras en el LATch excepto donde sea imposible (por ejemplo, en buses bidireccionales).
Configuración de funciones analógicas
Necesitas deshabilitar las funciones analógicas que están multiplexadas en los pines de PORTA. Consulta esta nota de la hoja de datos:
En un reinicio por hardware, RA5 y RA3:RA0 se configuran como entradas analógicas y se leen como '0'. (sección 10, página 113)
Además, la función del comparador también debe desactivarse. Para configurar todos los pines de PORTA como entradas digitales, consulta el Registro 21-2 (ADCON1) en la hoja de datos. Podrías intentar lo siguiente:
ADCON1 = 0x0F; // Todas las entradas digitales
CMCON = 0x07; // Comparadores desactivados (nota que este es el valor predeterminado POR)
Si no haces esto, nunca obtendrás los datos de entrada de tus interruptores, a menos que el simulador Proteus haga cosas inusuales.
Simplificando getMatrixX()
Puedes simplificar tu función getMatrixX() de varias maneras, dependiendo de si te preocupa el espacio de código o de datos. Aquí hay una que utiliza una búsqueda de tabla (sin probar):
unsigned char data[8] = { 0b01111111, 0b10111111, 0b11011111, 0b11101111, 0b11110111, 0b11111011, 0b11111101, 0b01111110 };
unsigned char getMatrixX(unsigned char in_X) {
if (in_X > 7) {
return 0xFF;
}
return data[in_X];
}
Sería sencillo hacer lo mismo con un desplazamiento y algo de lógica, evitando la tabla de búsqueda:
unsigned char getMatrixX(unsigned char in_X) {
if (in_X > 7) {
return 0xFF;
}
return 0xFF ^ (0x80 >> in_X);
}