Autor Tema: Problema con interrupcion externa y teclado  (Leído 10982 veces)

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

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #15 en: 12 de Marzo de 2013, 15:47:33 »
Hola! muchas gracias por las molestias que os estais tomando.

He efectuado los cambios que me explicasteis y sigue sin detectar la interrupción. He pasado el lcd al puerto c (concretamente a los pines C1, C2, C3 y C4) y eliminado la instrucción output_b(input_b(). Tambien hice caso a AngelGris y pase la lectura del flag de la interrupción a la rutina menu principal.

Escribo la parte del codigo que afecta a las partes criticas y adjunto los archivos empleados:

//////////////////LLAMADA FUNCION INTERRUPCION//////////////
#INT_EXT
void int_ext_isr(void)  //funcion que detecta la interrupcion

{  
    flag=1;    //Se habilita la bandera cuando ocurre una interrupcion.
  
}



////////////////////PROGRAMA PRINCIPAL//////////////////////
void main()

{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
  
   flag=0;                       //pongo la variable de la bandera a '0'
   set_tris_b(0b00001111);       //configuro el puerto b
   set_tris_c(0b11111111);       //configuro el puerto c
   ext_int_edge(H_TO_L);         //activo la interrupcion externa por cambio de bajo a alto
  
   //bit_clear(INTCON,1); //Borra bandera de la interrupcion
   enable_interrupts(int_ext);   //habilito la interrupcion externa
   enable_interrupts(GLOBAL);    //habilito las interrupciones
  
   lcd_init();            //inicializa lcd
   delay_ms(1000);
   lcd_putc ("   Bienvenido   ");
   delay_ms(1000);
   cambia_clave_inicial();    //cambio la contraseña que viene por defecto
   menu_principal();          //voy al menu principal
    
}

/////FUNCION MENU PRINCIPAL  
void menu_principal (void)             //funcion que muestra el menu principal

{
     for( ; ; )
    {
      if(flag==1)
      {
         disable_interrupts(int_ext);  //deshabilitamos la interrupcion externa
         //disable_interrupts(GLOBAL);
         delay_ms(20);                 //antirrebote
         alarma_general ();            //activamos la alarma
         flag=0;                       //ponemos la variable flag a '0'
         clear_interrupt(int_ext);     //ponemos a '0' el flag
         enable_interrupts(int_ext);   //habilito la interrupcion externa
         //enable_interrupts(GLOBAL);    //habilito las interrupciones
      }
      else
      {
         lcd_putc("\f0-Activa Alarma\n1-Cambia Clave");
         do{               //espera hasta...
            k=kbd_getc();  
            }while(k==0 || k==1);   //...pulsar una tecla
      
         switch (k)
         {
         case '0':         //si '0' va a activar la alarma
            activar_alarma();
         break;
         case '1':         //si '1' va a comprobar clave para despues cambiar la clave
          cambiar_clave();
         break;
         }
      }
    }  
}


He estado investigando por el foro lo de gestionar el teclado por interrupciones pero no termino de entender su funcionamiento ni como adaptarlo a mi programa. Si me lo pudierais explicar me hariais un gran favor.

Muchas gracias por todo a todos
« Última modificación: 12 de Marzo de 2013, 15:55:32 por escarrillense »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Problema con interrupcion externa y teclado
« Respuesta #16 en: 12 de Marzo de 2013, 19:29:14 »
  Perdón, pero observando mejor la estructura de la función "menu principal" sigue existiendo un inconveniente y es que sigues quedando a la espera de pulsar o bien la tecla 0 o bien la tecla 1.

  No sé como funcione la librería de teclado que estás utilizando. Obviamente, lo ideal sería utilizarla por medio de interrupciones.
  De todas maneras, si existe una función que te permita chequear con aterioridad si se presionó alguna tecla, se podría hacer uso  de ella. Algo así...


Código: C
  1. for(;;)
  2. {
  3.   if (flag == 1)
  4.   {
  5.     todo lo que tengas que hacer
  6.   }
  7.   if (kbd_hit)
  8.   {
  9.     k = kbd_getc();
  10.     switch (k)
  11.     {
  12.     }
  13.   }
  14. }

  de esa manera sólo leerías el teclado si es que se presionó alguna tecla. De no ser así se repite constantemente el ciclo y por lo tanto si podrías leer el flag.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #17 en: 13 de Marzo de 2013, 09:17:06 »
Muchas gracias AngelGris! Creo que estas en lo cierto, que el problema que tengo es como gestiono el teclado. Estoy constantemente en un bucle esperando a pulsar una tecla y no llego a detectar la interrupción. He probado el codigo que me pusiste y no me funciona, creo que es porque esa instrucción solo es válida para comunicación rs-232 y en mi caso no la estoy utilizando en este pryecto.
Estoy intentando gestionar el teclado por medio de interrupciones pero no consigo lograrlo. Seguire probando y tambien estudiare lo de la comunicación serie por si es una posible solución.

Muchas gracias y a ver si consigo avanzar

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #18 en: 13 de Marzo de 2013, 13:42:18 »
ok escarrillense,porque no como sugerencia vamos armando poco a poco el código y haciendo funcionar una a una las cosas porque me parece que de lo liado que estas ya no se puede trabajar con ese código jeje solo es una sugerencia,en unos momentos subo un código donde trabaje la interrupción externa que es la que no quiere la bendita  :? aunque es raro,y de ahí vamos metiendole cosas una por una te parece.

ahora,pregunta,que pic usas?? el 16F876?? que es el que veo en la simulación del proteus,porque no se como le estas haciendo que no veo el include correspondiente al pic en tu codigo,es decir,#include<pic16f876.h>,pero bueno si te compila y hace algo es porque va bien.

dame chancecita que ahorita subo el codigo para que pruebes y me dices que chow
Nunca se deja de aprender

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #19 en: 13 de Marzo de 2013, 14:14:59 »
Ok ahi va,utilizando el mismo PIC que veo en tu simulacion,he creado este codigo que configura la interrupcion externa y cuando esta se activa,un led en RB1 togglea (osea que,de estar apagado va a encendido y de encendido va a apagado),he creado tambien la simulacion sencilla en Proteus 7.9,espero te sirva,cualquier duda por aqui andamos.

Código: [Seleccionar]
#include<16f876.h>
#fuses XT,PUT,NOWDT,NODEBUG
#use delay(clock=4MHZ)

#byte TRISB=0x086

char bandera=0;

#INT_EXT
void externa(void)
{
bandera=1;
}

void configura_int_ext(void)
{
bit_set(TRISB,0);
clear_interrupt(INT_EXT);
ext_int_edge(L_TO_H);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
}

void main(void)
{
configura_int_ext();
while(true)
{
if(bandera==1)
{
bandera=0;
output_toggle(PIN_B1);
}
}
}
Nunca se deja de aprender

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #20 en: 14 de Marzo de 2013, 15:15:14 »
Muchas gracias thegame por el codigo! Lo he probado y funciona perfectamente pero al añadirle el teclado volvemos al problema de siempre aunque no ponga bucles como los que me estaban dado problemas hasta ahora. La interrupción ahora funciona pero no la captura de teclas. Estoy utilizando un PIC16F876. El include con el modelo de PIC no me es necesario ponerlo (no me pregunten por qué ya que no lo se, es muy raro ya lo se). De forma paralela sigo trabajando con la gestión del teclado por interrupciones, por si fuera la solución. Les pongo el código que he probado (las librerías son las anteriormente utilizadas, las saque del foro y hasta ahora funcionaban perfectamente):

#include<16f876.h>
#fuses XT,PUT,NOWDT,NODEBUG
#fuses NOPROTECT     //deshabilita la proteccion del codigo del pic
#fuses NOLVP         //No Low Voltage Programming on B3(PIC16) or B5(PIC18,no habilita la programacion en bajo voltaje)
#fuses NOBROWNOUT    //No Reset when brownout detected
#use delay(clock=4MHZ)

#use fast_io(A)       //alguna instruccion de entrada o salida
//#use fast_io(C)       //alguna instruccion de entrada o salida
#BYTE TRISA = 0b10000101   //TRISA = 0x85 Registro de direccionamiento Puerto A
#BYTE PORTA = 0b00000101   //PORTA = 0x05 Puerto A
#byte TRISB=0x086
#BYTE TRISC = 0b10000111
#BYTE PORTC = 0b00000111   //PORTC = 0x07 Puerto C

#include <LCD4.c>             //libreria manejo lcd 8 bits
#include <kbd3x4_2.c>         //libreria manejo keypad 3x4
#byte kbd_port_b = 6

////////////////DEFINICION DE FUNCIONES////////////////////////////

void menu_principal(void);             //funcion que muestra el menu principal
void escribir_clave(char clave[]);            //funcion que escibre la clave tecleada


char bandera=0;
int k;
char clave_introducida[3]={};          //variable usada para los datos ingresados

#INT_EXT
void externa(void)
{
   bandera=1;
}

void configura_int_ext(void)
{
   bit_set(TRISB,0);
   clear_interrupt(INT_EXT);
   ext_int_edge(L_TO_H);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
}

void main(void)
{
   set_tris_b(0b00001111);       //configuro el puerto b
   //port_b_pullups(true);         //activo las resistencias de pullup
   lcd_init();            //inicializa lcd
   delay_ms(1000);
   lcd_putc ("   Bienvenido   ");
   delay_ms(1000);
  
   configura_int_ext();
  
   while(true)
   {
      if(bandera==1)
      {
         bandera=0;
         output_toggle(PIN_C0);
      }
      else
      {
      
      escribir_clave(clave_introducida);
      }
   }
}

//////////FUNCION ESCRIBIR NUEVA CLAVE
void escribir_clave(char clave[])            //funcion que escibre la clave tecleada

{
int i=0;
   lcd_putc("\fEscribir clave:\n");   //presentacion
   do{
           if(k!=0)
           {
        
               if(!(k=='*' || k=='#')) // Si no es '*' o '#' en la pantalla aparece un '*'
               {      
               lcd_putc("*");
               clave=k;
               }      
            i++;
           }
            else
            {
               break;
            }
    
     }while( !(k=='*' || k=='#') );        //Si '*' o '#' señalamos que hemos terminado de introducir la contraseña
}

« Última modificación: 14 de Marzo de 2013, 15:43:21 por escarrillense »

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #21 en: 14 de Marzo de 2013, 19:27:20 »
Que tal escarillense,bueno por ahi veo unas cosas que no cuadran para mi,me explico:

1.- Porque colocas las declaraciones individuales de los registros si no veo que los uses con instrucciones como bit_clear() o bit_set(),es decir para que poner:

Código: [Seleccionar]
#BYTE TRISA = 0b10000101   //TRISA = 0x85 Registro de direccionamiento Puerto A
#BYTE PORTA = 0b00000101   //PORTA = 0x05 Puerto A

y

Código: [Seleccionar]
#BYTE TRISC = 0b10000111
#BYTE PORTC = 0b00000111   //PORTC = 0x07 Puerto C

si no se estan usando,ahora,no que alla problema con que las coloques pero se revuelve mas el codigo.
yo si la coloque en el codigo que te envie porque si la uso para configurar el direccionamiento del pin.

2.- Dentro de configura_int_ext(),ya no es necesaria la instruccion bit_set(TRISB,0); ya que previamente utilizas:

Código: [Seleccionar]
set_tris_b(0b00001111);       //configuro el puerto b
por lo que tambien puedes quitar de tu codigo esta parte:

Código: [Seleccionar]
#byte TRISB=0x086
que fue de lo que yo te mande si no me equivoco.

Ok,veamos que cambios podemos hacer y echar a andar esto,estamos en contacto. Suerte no desesperes,igual un usuario con mayor experiencia nos echa la mano jeje
Nunca se deja de aprender

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #22 en: 14 de Marzo de 2013, 20:45:56 »
Estuve revisando la libreria para el teclado,creo que por ahi el barrido que hace de las columnas ya no seria el mismo,dado que tu utilizas RB0 como interrupcion externa y no para el teclado.... :? lo estoy checando jeje
Nunca se deja de aprender

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #23 en: 15 de Marzo de 2013, 05:24:54 »
Muchas gracias thegame!  He quitado lo que me dijiste del #byte tirs y port. Tenías razón con lo de la librería del teclado y las columnas, como he hecho tantos cambios en este tiempo debí de postear la librería que no era. El cambio realizado en la librería del teclado es el siguiente: en la línea 46 hay que sustituir
for(c=0x01, j=0; j<3; c<<=1, j++) por lo sigiente for(c=0x02, j=0; j<3; c<<=1, j++).

He modificado la rutina escribir_clave y me detecta las teclas (machacandolas, eso si) pero ahora la interrupción no. En resumen, o me funciona una cosa o la otra, pero las dos a la vez no. Copio la parte de codigo que he modificado de esta rutina, ya que el resto sigue como anteriormente:

//////////FUNCION ESCRIBIR NUEVA CLAVE
void escribir_clave(char clave[])            //funcion que escibre la clave tecleada

{
int i=0;
   lcd_putc("\fEscribir clave:\n");   //presentacion
   delay_ms(1000);
   k=kbd_getc();
           
    if(!(k=='*' || k=='#')) // Si no es '*' o '#' en la pantalla aparece un '*'
    {     
       lcd_putc("*");
       clave=k;         
    }       
       //i++;
    if((k=='*' || k=='#'))
    {
       break;
    }
    i++;
}

« Última modificación: 15 de Marzo de 2013, 07:21:15 por escarrillense »

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #24 en: 15 de Marzo de 2013, 13:20:47 »
si asi es amigo,ya habia modificado esa parte de la libreria,te comento mis avances.

La interrupcion externa me funciona junto con el teclado,solo que modifique la función que tu utilizas para la captura de la clave,me funciona a medias porque siempre me marca acceso denegado jajaja (eso se lo puse yo jojo),entonces haciendo debug con el proteus he checado que no me esta guardando las teclas de entrada (clave_introducida) igual yo no lo estoy haciendo bien pero creo que tarde o temprano saldra esto jeje seguire intentando,te dejo lo que yo he echo or si le ves algun detalle y yo metere esta nueva funcion que has puesto hoy.

Código: [Seleccionar]
#include<16f876.h>
#fuses XT,PUT,NOWDT,NODEBUG
#fuses NOPROTECT     //deshabilita la proteccion del codigo del pic
#fuses NOLVP         //No Low Voltage Programming on B3(PIC16) or B5(PIC18,no habilita la programacion en bajo voltaje)
#fuses NOBROWNOUT    //No Reset when brownout detected
#use delay(clock=4MHZ,crystal=4MHZ)

#include<LCD4.c>             //libreria manejo lcd 8 bits
#include<kbd3x4_2.c>         //libreria manejo keypad 3x4

////////////////DEFINICION DE FUNCIONES////////////////////////////

char bandera=0,i=0;
char clave_introducida[4]={};
char clave_correcta[4]={'1','2','3'};

#INT_EXT
void externa(void)
{
   bandera=1;
}

void configura_int_ext(void)
{
clear_interrupt(INT_EXT);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
       
lcd_init();           
delay_ms(500);
lcd_putc ("   Bienvenido   ");
delay_ms(500);
}

void main(void)
{
configura_int_ext();
lcd_putc("\fEscribir clave:\n");   //presentacion

while(true)
{
if(bandera==1)
{
                            bandera=0;
                            output_toggle(PIN_C0);
}
     
if(kbd_getc()!=0)
{
if((kbd_getc()!='*' || kbd_getc()!='#'))
{     
clave_introducida[i]==kbd_getc();
                                lcd_putc(kbd_getc());
i++;
}

if(i==4 && (kbd_getc()=='*' || kbd_getc()=='#'))
{
if(clave_correcta==clave_introducida)
{
lcd_putc("\fAcceso concedido\n");
}
else
{
lcd_putc("\fAcceso denegado\n");
}
}

        }
}
}

pero me hace cosas raras,dejame decirte que me he estado divirtiendo con tu problema jeje,he aprendido mucho,asi que como decimos en mi tierra...o sales o sales k....jajaja
no desesperes que si queda,probare lo que tu modificaste
Nunca se deja de aprender

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #25 en: 15 de Marzo de 2013, 13:40:41 »
Muchas gracias thegame! He probado tu código y siento decirte que no me funciona. No se si sera mi versión de proteus o el que, seguiré investigando.

En la parte donde comparas la clave introducida y la correcta, yo lo hago de esta manera y hasta ahora funcionaba:

int p;
clave_introducida=0;                //pongo la clave tecleada a 0
   escribir_clave(clave_introducida);  //tecleo la contraseña
   p=strcmp(clave_introducida , clave_correcta);    //comparo la clave por defecto con la tecleada
   if (p==0)                           //si las dos claves son iguales:
         {
              lcd_putc("\fClave Correcta\n");
         
         }
   if (p!=0)                        //si las dos claves son distintas
         {
           lcd_putc("\fClave Incorrecta\n");
          delay_ms(2000);
          clave_introducida=0;      //borro la clave introducida
         
         }
« Última modificación: 15 de Marzo de 2013, 13:51:07 por escarrillense »

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #26 en: 15 de Marzo de 2013, 15:52:22 »
mmm que mal,bueno a seguir buscando
Nunca se deja de aprender

Desconectado thegame

  • PIC18
  • ****
  • Mensajes: 439
    • Mcu Tronics
Re: Problema con interrupcion externa y teclado
« Respuesta #27 en: 17 de Marzo de 2013, 01:47:52 »
Algun avance amigo escarrillense??
Nunca se deja de aprender

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #28 en: 18 de Marzo de 2013, 05:44:30 »
Hola! Pues este fin de semana no he podido probar nada del programa ya que no he tenido tiempo y casi me ha venido bien para cargar pilas. Estuve hablando con un amigo y me dijo que lo mejor es gestionar el teclado por interrupciones. Me dijo que de esta manera te ahorras muchos problemas como los que me estan pasando. Despues de una mañana luchando he conseguido que el teclado funcione por interrupciones. Lo que me pasa que el * y # no me los detecta y me sale el valor ASCII creo que es. El esquema es el anteriormente utilizado. Si descubris alguna manera de mejorar este código recibiré vuestras opiniones gratamente. El siguiente paso es añadir la dichosa interrupción externa que tantos quebraderos de cabeza me esta provocando. Aqui os lo dejo:

#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#use delay (CLOCK=4000000)
#use fast_io(A)
#use fast_io(B)
#byte port_b = 0x06
#byte tris_b = 0xff

#include <LCD4.c>             //libreria manejo lcd 8 bits
#include <string.h>           //libreria manejo cadenas
int flag_teclado;
int tecla,fila,columna;
 
/********************************
Esta Rutina permite rastrear el teclado
y devuelve el valor de la tecla que se
ha presionado
************************************/
int captura(void)
{
int const teclado[4][4] = {{0,1,2,3},
                           {0,4,5,6},
                           {0,7,8,9},
                           {0,'*',0,'#'}};
int tecla,lectura,i;
for(i=0;i<4;i++)
{
output_b(0);
bit_set(port_b,i);
lectura = port_b & 0b11110000;
switch(lectura)
{
case 0b00010000: fila=0;
 columna=i;
 break;
case 0b00100000: fila=1;
 columna=i;
 break;
case 0b01000000: fila=2;
 columna=i;
 break;
case 0b10000000: fila=3;
 columna=i;
 break;
}
}
tecla = teclado[fila][columna];
return(tecla);
}
 
/***************************************
Rutina de Interrupcion.
- Antirebote.
- Llama a rutina "captura" para saber
  la tecla presionada.
- Activa la bandera "flag_teclado"
  a usar en el main o en otra parte
  del programa.
***************************************/
#INT_RB
void tecla_presionada()
{
   int lectura_1,lectura_2;
   lectura_1 = port_b & 0b11110000; //lee portb4:7 y lo guarda en lectura_1
   delay_ms(10); //Funcion AntiRebotes: Espero 10ms.
   lectura_2 = port_b & 0b11110000; //Vuelvo a leer el puerto.
   if(lectura_1==lectura_2 && lectura_1!=0) //Si el valor es igual y distinto de 0 es porque en realidad se presiono una tecla.
   {                                   
      tecla = captura();
      flag_teclado=1;
   }
   set_tris_b(0b11110000);
   output_b(0b00001111);
   clear_interrupt(INT_RB);
   input_b();
}


//////////////PROGRAMA PRINCIPAL///////////////////////
void main()
{
   set_tris_b(0b11110000);
   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);
   
   lcd_init();            //inicializa lcd
   delay_ms(1000);
   lcd_putc ("   Bienvenido   ");
   delay_ms(1000);
   
   while(TRUE)
   {
   if(flag_teclado==1)
      {
      printf(lcd_putc "Tecla: %i\n\r",tecla);
      flag_teclado=0;
      }
   }
}   
 
« Última modificación: 18 de Marzo de 2013, 08:47:27 por escarrillense »

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: Problema con interrupcion externa y teclado
« Respuesta #29 en: 19 de Marzo de 2013, 09:23:40 »
Hola a todos! Continuo con los avances. He conseguido meter la interrupcion externa y que funcionen ambas cosas. Lo que no consigo es que me guarde las teclas pulsadas como una cadena para que aparezcan en el display una detras de otra. En el display las teclas las oculto mediante asteriscos. Seguiré intentando lo de la cadena y mas avances. Por cierto, os pediría un favor, ¿como se hace para poner el código en una pequeña ventanita mas pegueña? Lo veo en muchos post y no se como se hace y así lograría que los mios no ocupasen tanto jajajaj. Pongo el código:

#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NOBROWNOUT
#use delay (CLOCK=4000000)
#use fast_io(A)
#use fast_io(B)
#byte port_b = 0x06
#byte tris_b = 0xff

#include <LCD4.c>             //libreria manejo lcd 8 bits
#include <string.h>           //libreria manejo cadenas


////////////////DEFINICION DE FUNCIONES////////////////////////////

void escribir_clave(char clave[]);     //funcion que escibre la clave tecleada
void alarma_general(void);             //funcion que enciende la sirena


////////////////VARIABLES GLOBALES///////////////////////////

int flag_teclado;
int tecla,fila,columna;
char bandera=0;
char clave[3];                         //variable usada para recoger la clave tecleada
char clave_introducida[3]={};          //variable usada para los datos ingresados
signed char i;                         //variable usada para movernos por las posiciones de la memoria

 
/********************************
Esta Rutina permite rastrear el teclado
y devuelve el valor de la tecla que se
ha presionado
************************************/
int captura(void)
{
int const teclado[4][4] = {{0,'1','2','3'},
                           {0,'4','5','6'},
                           {0,'7','8','9'},
                           {0,'*','0','#'}};
int tecla,lectura,i;
for(i=0;i<4;i++)
{
output_b(0);
bit_set(port_b,i);
lectura = port_b & 0b11110000;
switch(lectura)
{
case 0b00010000: fila=0;
 columna=i;
 break;
case 0b00100000: fila=1;
 columna=i;
 break;
case 0b01000000: fila=2;
 columna=i;
 break;
case 0b10000000: fila=3;
 columna=i;
 break;
}
}
tecla = teclado[fila][columna];
return(tecla);
}
 
/***************************************
Rutina de Interrupcion.
- Antirebote.
- Llama a rutina "captura" para saber
  la tecla presionada.
- Activa la bandera "flag_teclado"
  a usar en el main o en otra parte
  del programa.
***************************************/
#INT_RB
void tecla_presionada()
{
   int lectura_1,lectura_2;
   lectura_1 = port_b & 0b11110000;          //lee portb4:7 y lo guarda en lectura_1
   delay_ms(10);                             //Funcion AntiRebotes: Espero 10ms.
   lectura_2 = port_b & 0b11110000;          //Vuelvo a leer el puerto.
   if(lectura_1==lectura_2 && lectura_1!=0)  //Si el valor es igual y distinto de 0 es porque en realidad se presiono una tecla.
   {                                   
      tecla = captura();
      flag_teclado=1;
   }
   set_tris_b(0b11110000);
   output_b(0b00001111);
   clear_interrupt(INT_RB);
   set_tris_b(0b11110001);
   //input_b();
}


//////////////INTERRUPCION EXTERNA//////////////////
#INT_EXT
void externa(void)
{
   bandera=1;
}


//////////////PROGRAMA PRINCIPAL///////////////////////
void main()
{
   set_tris_b(0b11110001);
   set_tris_c(0b11111111);       //configuro el puerto c
   enable_interrupts(INT_RB);
   ext_int_edge(H_TO_L);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   
   lcd_init();            //inicializa lcd
   delay_ms(1000);
   lcd_putc ("   Bienvenido   ");
   delay_ms(1000);
 
   while(TRUE)
   {
   if(flag_teclado==1)
      {
      escribir_clave(clave_introducida);  //tecleo la contraseña
      flag_teclado=0;
      //break;
      }
    if(bandera==1)
      {
         bandera=0;
         alarma_general();
         //break;
      }
   }
}   


//////////FUNCION ESCRIBIR NUEVA CLAVE
void escribir_clave(char clave[])            //funcion que escibre la clave tecleada

{
int i=0;
     
         lcd_putc("\fEscribir clave:\n");   //presentacion
         
            if(!(tecla=='*' || tecla=='#')) // Si no es '*' o '#' en la pantalla aparece un '*'
            {     
            lcd_putc("*");
            clave=tecla;
            }
            i++;     
}



//////////FUNCION ALARMA GENERAL
void alarma_general (void)

{
    set_tris_c(0b11111110);      //pin C0 como salida                             
    output_high(pin_C0);         //enciende la sirena durante 2 seg y muestra mensaje
    //lcd_putc("\fALARMA\n");         
    delay_ms(2000);
    output_low(pin_C0);          //apaga la sirena
}
« Última modificación: 19 de Marzo de 2013, 09:26:07 por escarrillense »


 

anything