Programación PIC - Obtenga el valor de varios botones en un puerto

1

Estoy aprendiendo PIC (pic18f4550) y bastante nuevo en la programación de microcontroladores. Estoy intentando obtener el valor de tres botones en PORTA y lo envío a una matriz de 8x8 led como coordenadas X a través de un 74LS595 . El problema es que el valor de ir a la matriz de led no cambia cuando presioné los botones para crear un valor diferente. Estoy simulando en Proteus, así que supongo que no necesito la función de rebote. Aquí está mi código y esquema:

#include<p18f4550.h>

#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<<i);
        if(temp)
        {
            DATA = 1;
        }
        else
        {
            DATA = 0;
        }

        SCK = 0;
        SCK = 1;
    }

SCL = 0;
SCL = 1;
}

unsigned char getMatrixX(unsigned char in_X)
{

    switch(in_X)
    {
        case 0:      // the value stuck here
        return 0b01111111;
    case 1:
        return 0b10111111;
    case 2:
        return 0b11011111;
    case 3:
        return 0b11101111;
    case 4:
        return 0b11110111;
    case 5:
        return 0b11111011;
    case 6:
        return 0b11111101;
    case 7:
        return 0b11111110;
    default:
        return 0b11111111;
    }
}

void main()
{

    TRISA = 1;
    TRISC = 1;

    TRISB = 0;
    TRISD = 0;

    PORTD = 0x80;

    while(1){
        Send1byte(getMatrixX(LATA));
    }
}

Este es un enlace a mi esquema: mi esquema

Realmente aprecio cualquier solución y consejo. Lo siento por mi mal inglés.

    
pregunta user3669754

2 respuestas

4

Hay una serie de cosas que deben corregirse en su código antes de que podamos comenzar a ayudarlo con los problemas funcionales. He enumerado algunos a continuación.

Uso de TRIS

Por favor, vea la respuesta de Handoko, que trata esto.

Uso de registros LAT vs. PORT

Llamas a tu función así: Send1byte(getMatrixX(LATA)) . Supongo que su intención es obtener el estado actual de los botones de entrada y enviarlos a esta función.

Esto no funcionará, necesita leer del registro PORTA en su lugar. El código correcto leería Send1byte(getMatrixX(PORTA)) .

¿Por qué es esto? Hay una breve explicación en la hoja de datos:

  

Leyendo el registro PORTA lee el estado de los pines; escribiéndolo   escribirá en el cierre del puerto.

Y una imagen útil:

LalíneadedatosinternaqueseusacuandoleeelbitPORT(parteinferiorizquierda,desdeelbloqueverde)estáconectadaalbúferdeentrada,queprovienedirectamentedelpindeE/S.Encontraste,lalíneadedatosutilizadacuandoleeelbitLAT(arribaalaizquierda,conectadaalbloquerojo)sololeeelestadodelbloqueodedatos.Noestáconectadoalaentrada.

TengaencuentaquelasdefinicionesdeSCK/DATA/SCLdeberíanfuncionar(escribirenelbitdelPUERTOestableceráelLATch)perogeneralmentemantengotodaslasescriturasenelLATchexceptodondeseaimposible(porejemplo,busesbidireccionales).

Configuracióndefuncionesanalógicas

DebedeshabilitarlasfuncionesanalógicasquesemultiplexanenlospinesPORTA.Veaestanotadelahojadedatos:

  

Enunreiniciodeencendido,RA5yRA3:RA0seconfigurancomoentradasanalógicas  yseleecomo"0".   (sección 10, página 113)

Además, la función de comparación también debe estar deshabilitada. Para configurar todos los pines PORTA en entradas digitales, consulte Registro 21-2 (ADCON1) en la hoja de datos. Puedes probar:

ADCON1 = 0x0F; // All digital inputs
CMCON = 0x07;  // Comparators off (note this is the POR default)

Si no hace esto, nunca obtendrá los datos de entrada de sus conmutadores, a menos que el simulador de Proteus haga cosas inusuales.

Simplificando getMatrixX ()

Puede simplificar su función getMatrixX () de varias maneras, dependiendo de si le importa el código o el espacio de datos. Aquí hay uno 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 cambio y cierta 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);
}
    
respondido por el David
4

En primer lugar, necesita configurar su entrada y salida correctamente.

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

Las mismas cuentas para TRISB. Cambie este valor a 0x00000111 o 0x07.

Como Peter ha mencionado, cambie todos sus casos en el cambio a:

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

Además, ¿ni siquiera veo dónde escribiste en el guión qué debe hacer la MCU cuando se presiona un botón?

    
respondido por el Handoko

Lea otras preguntas en las etiquetas