1 votos

Programación PIC - Obtener el valor de múltiples botones en un puerto

Estoy aprendiendo PIC (pic18f4550) y soy bastante nuevo en la programación de microcontroladores. Estoy tratando de obtener el valor de tres botones en PORTA y enviarlo a una matriz led 8x8 como coordenadas X a través de un 74LS595. El problema es que el valor que va a la matriz led no cambia cuando presiono los botones para crear un valor diferente. Estoy simulando en Proteus así que supongo que no necesito una función de debounce. Aquí está mi código y esquemático:

#include

#define SCK LATBbits.LATB0
#define DATA PORTBbits.RB1
#define SCL PORTBbits.RB2

void Data_in(unsigned char k){
    DATA=k;
    SCK=0;
    SCK=1;
}

void LatchData(){
    SCL=0;
    SCL=1;
}

void Send1byte(unsigned char data)
{
    unsigned char i,temp;
    for(i=0;i<8;i++)
    {
        temp = data & (1<

`

Este es el enlace a mi esquemático: mi Esquemático

Aprecio mucho cualquier solución y consejo. Disculpen mi mal inglés.

`

4voto

Handoko Puntos 370

Primero que nada, necesitas configurar correctamente tus entradas y salidas.

Usaste TRISA = 1; lo que significa que solo RA0 es una ENTRADA. Por favor cambia esto a TRISA = 0b00000111; o TRISA = 0x07; para configurar los 3 botones como ENTRADA.

Lo mismo aplica para TRISB. Cambia este valor a 0x00000111 o 0x07.

Como mencionó Peter, cambia todos tus casos en el switch a:

case1:
 // TODO
 return;
case2:
 // TODO
 return;

Además, ni siquiera veo dónde programaste qué debe hacer el MCU cuando se presiona un botón?

4voto

Salem Koja Puntos 21

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:

Figura 10-1 PORT vs. LAT

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);
}

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X