Autor Tema: Teclado matricial con PIC16F84  (Leído 3179 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado bormanp

  • PIC10
  • *
  • Mensajes: 3
Teclado matricial con PIC16F84
« en: 16 de Mayo de 2011, 12:05:27 »
¡¡Hola, señores!!

No sé si acierto posteando esto aqui, si no fuese así, ruego a algún moderador que lo cambie...

Este es mi segundo proyecto, y ya me está trayendo quebraderos de cabeza... Posteo aquí mi problema a ver si algún alma caritativa puede echarme un cable (nunca mejor dicho).

Lo que siempre he pretendido es empezar de 0, y consultar la menor cantidad de código y soluciones "ya hechas" en Internet, porque creo que es la mejor forma de aprender.

Buscando proyectos para empezar en este mundillo, encontré el teclado matricial. Leí el desarrollo y la metodología básicos, y me puse a diseñar.

Os pego código y esquema, y luego os cuento lo que me pasa:

Código: [Seleccionar]
// Programa para el manejo de un teclado matricial

// Librerías que utilizo
#include <16F84A.h>

// Fusibles
#fuses HS,NOWDT,NOPUT,NOPROTECT

// Frecuencia del cristal
#use delay(clock=8000000)

#use fast_io(A)
#use fast_io(B)

///  asignamos a variable port_b el espacio memoria 0x06 que es la dir de port_b
#byte PuertoA=0x05
#byte PuertoB=0x06

int Fila; //Definimos los valores globales de fila y columna
int Columna;
int Rebote;

void Reseteo()
{
   Fila=0; //Inicializamos los valores de fila y columna a 0
   Columna=0;
   Rebote=0; //No hay rebotes de momento
}

int Decodifica(int VarFil, int VarCol)
{
   int VarTemp; //Definimos una variable temporal donde guardar el resultado
   
   switch(VarFil)
   {
      case 4:
         switch(VarCol)
         {
            case 1: VarTemp=0b1111; break;
            case 2: VarTemp=0b0000; break;
            case 3: VarTemp=0b1110; break;
            case 4: VarTemp=0b1101; break;
         }
         break;
      case 3:
         switch(VarCol)
         {
            case 1: VarTemp=0b0001; break;
            case 2: VarTemp=0b0010; break;
            case 3: VarTemp=0b0011; break;
            case 4: VarTemp=0b1100; break;
         }
         break;
      case 2:
         switch(VarCol)
         {
            case 1: VarTemp=0b0100; break;
            case 2: VarTemp=0b0101; break;
            case 3: VarTemp=0b0110; break;
            case 4: VarTemp=0b1011; break;
         }
         break;
      case 1:
         switch(VarCol)
         {
            case 1: VarTemp=0b0111; break;
            case 2: VarTemp=0b1000; break;
            case 3: VarTemp=0b1001; break;
            case 4: VarTemp=0b1010; break;
         }
         break;
   }
   
   return VarTemp;
}
   
void main() // Rutina principal
{
   set_tris_a(0b00000);     //El puerto A son todo salidas
   set_tris_b(0b11110000);  //El puerto B: pin 0-1-2-3 salidas 4-5-6-7 entradas
   ext_int_edge(0,H_TO_L);  //Establecemos el flanco de las interrupciones
   enable_interrupts(INT_RB); //Habilitamos las interrupciones
   enable_interrupts(GLOBAL);
   
   PuertoB=0b00000000;
   PuertoA=0b00000;
   
   Reseteo();
   
   while(true)
   {
      if ((Fila!=0) && (Columna!=0))
      {
         PuertoA=Decodifica(Fila, Columna);
         delay_ms(1000);
         Fila=0;
         Columna=0;
         PuertoA=0;
         Rebote=0;
      }
   }
}

#int_rb //Vamos a vigilar la interrupción correspondiente al cambio de estado de RB4-RB7
   void manejador_rb()
   {
   
      //Empezamos el barrido
     
      if (Rebote==0)
      {
         //Rebote=1; //Este lo tengo comentado para no tratar los rebotes de momento
         output_b(0b0001); //Encendemos el pin 0 (correspondiente a columna 1)
         
         //delay_ms(10);
         
         if (!input(PIN_B4) || !input(PIN_B5) || !input (PIN_B6) || !input (PIN_B7)) //Si hemos activado una fila...
         {
            Columna=1; //Sabemos que la columna es 1
            if (!input(PIN_B4)) Fila=1; //Y la fila... depende del pin activado
            if (!input(PIN_B5)) Fila=2;
            if (!input(PIN_B6)) Fila=3;
            if (!input(PIN_B7)) Fila=4;
         }
         
         output_b(0b0010); //Encendemos el pin 1 (correspondiente a columna 2)
         //delay_ms(10);
         
         if (!input(PIN_B4) || !input(PIN_B5) || !input (PIN_B6) || !input (PIN_B7)) //Si hemos activado una fila...
         {
            Columna=2; //Sabemos que la columna es 2
            if (!input(PIN_B4)) Fila=1; //Y la fila... depende del pin activado
            if (!input(PIN_B5)) Fila=2;
            if (!input(PIN_B6)) Fila=3;
            if (!input(PIN_B7)) Fila=4;
         }
         
         output_b(0b0100); //Encendemos el pin 2 (correspondiente a columna 3)
         //delay_ms(10);
         
         if (!input(PIN_B4) || !input(PIN_B5) || !input (PIN_B6) || !input (PIN_B7)) //Si hemos activado una fila...
         {
            Columna=3; //Sabemos que la columna es 3
            if (!input(PIN_B4)) Fila=1; //Y la fila... depende del pin activado
            if (!input(PIN_B5)) Fila=2;
            if (!input(PIN_B6)) Fila=3;
            if (!input(PIN_B7)) Fila=4;
         }
         
         output_b(0b1000); //Encendemos el pin 3 (correspondiente a columna 4)
         //delay_ms(10);
         
         if (!input(PIN_B4) || !input(PIN_B5) || !input (PIN_B6) || !input (PIN_B7)) //Si hemos activado una fila...
         {
            Columna=4; //Sabemos que la columna es 4
            if (!input(PIN_B4)) Fila=1; //Y la fila... depende del pin activado
            if (!input(PIN_B5)) Fila=2;
            if (!input(PIN_B6)) Fila=3;
            if (!input(PIN_B7)) Fila=4;
         }
         
         PuertoB=0b00000000;
      }
   }

El esquema:



¿Mi problema?

Cuando desactivo la detección de interrupciones en el código fuente, la lógica del circuito funciona perfectamente: cuando acciono un pulsador,el pin correspondiente del rango RB4 a RB7 pasa de nivel alto se pone a nivel bajo (pasa de rojo a azul). Todo perfecto. Pero cuando activo las interrupciones... me encuentro con que, al comenzar el barrido que se realiza en el tratamiento de la interrupción, se pone en estado lógico desconocido (los pines RB0 a RB3 se ponen en gris, y el pin correspondiente en el rango RB4 a RB7 también se pone en gris). Es posible que en el código que acabo de poner esté tratando de forma incorrecta el barrido (que deba tratarlo partiendo de los pines RB0 a RB3 con nivel alto, e ir desactivandolos uno a uno), pero llevo varios días dándole vueltas, ya he probado de mil maneras distintas, y siempre consigo el mismo resultado.

Es posible que el código no esté muy optimizado, pero primero quiero hacerlo con grandes pinceladas, y luego irlo optimizando a medida que lo vaya entendiendo.

Muchas gracias de antemano a quien me ayude, y ¡perdón por la parrafada!  ;)

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: Teclado matricial con PIC16F84
« Respuesta #1 en: 26 de Mayo de 2011, 01:06:55 »
hola, no se si ya resolviste tu problema, pero te comento que tu conexion esta mal, en la parte de arriba de tus botones 7 8 9 A, tienes tus conexiones en corto, entonces cuando presiones un boton, todos se van al mismo estado, pero como los que no presionaste estaban en 1, y les pones un 0 por eso te da el estado gris.

tambien puedes probar usando el teclado que tiene el proteus, buscalod como keypad
"Nada es imposible, no si puedes imaginarlo"


 

anything