Autor Tema: interrupcion externa, teclado matricial, 16f877a  (Leído 7811 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado cedruiz

  • PIC10
  • *
  • Mensajes: 8
interrupcion externa, teclado matricial, 16f877a
« en: 17 de Enero de 2011, 12:58:21 »
hola a todo el mundo siento mucho q mi primer post sea para pedir ayuda pero estoy seguro q solo ustedes me pueden sacar de este predicamento.

estoy trabajando en un sistema de seguridad que me pida una contraseña y me este monitoreando unos sensores, estoy trabajando con un 16f877a configurado de la siguiente manera el puerto A y el puerto D se encargan de un lcdX2, el puerto B barre un teclado matricial de 4x3.

El problema consiste con la interrupción externa de flanco que ingresa por el puerto B la cual quiero utilizar para detectar el cambio de estado en los sensores, si bien el teclado matricial esta en el mismo puerto desabilito las resistencias de pull up y cargo la configuracion del teclado y hasta este punto la interrupcion se activa el problema aparece cuando utlizo la instruccion kbd_getc() en este momento la interrupcion pues ya no interrumpe =D.

ahora pues si alguien a tenido este mismo problema podria decirme como puedo solucionarlo =D, si nadie se a topado con esto podrian hecharle un vistaso, solo lo he simulado en proteus puede ser solo problema de simulador?

en fin les agradesco cualquier ayuda que puedan darme =D.

Desconectado cedruiz

  • PIC10
  • *
  • Mensajes: 8
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #1 en: 19 de Enero de 2011, 20:08:01 »
vamos gente ideas, preguntas, sugerencias algo jejejeje =)

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #2 en: 19 de Enero de 2011, 22:10:03 »
vamos gente ideas, preguntas, sugerencias algo jejejeje =)

por que no mejor pones tambien un esquema del circuito?
asi mejor que mejor comprenderemos lo que haces y como lo haces
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado cedruiz

  • PIC10
  • *
  • Mensajes: 8
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #3 en: 19 de Enero de 2011, 22:33:25 »
en hora buena man gracias adjunto en el zip todos los archivos q estoy utilizando incluso el archivo que utilizo para la simulacion en proteus UNTITLED.dsn =D

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #4 en: 20 de Enero de 2011, 07:26:23 »
fijate, para poder tener una interrupcion el el pin RB0 lo primero que debes hacer es configurarlo como entrada... mira en el modo debug del proteus el estado del potrb... te pongo una imagen,este esta en 0b11111110 osea que lo tienes como salida no como entrada, tambien te recomendaria poner una resistencia pullup en simulacion ya que a veces falla...

esta imagen es al principio de entrar en el void main
Imagen 1
y esta otra cuando ya se ha pulsado el keypad
Imagen 2

el registro de trisb sige igual, no te detectara ninguna interrupcion por cambio de flanco por que ahora mismo tienes habilitado el pin b0 como salida
un saludo
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado cedruiz

  • PIC10
  • *
  • Mensajes: 8
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #5 en: 21 de Enero de 2011, 14:36:17 »
gracias man voy hacer las correcciones cualquier adelanto lo comunico =)

Desconectado cedruiz

  • PIC10
  • *
  • Mensajes: 8
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #6 en: 22 de Enero de 2011, 11:12:45 »
muchas gracias solucionado el problema con la interrucion, configuro el trisc como me dijiste y se ha solucionado todo =D nuevamente muchas gracias.

Desconectado ppyote

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 929
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #7 en: 22 de Enero de 2011, 14:55:25 »
muchas gracias solucionado el problema con la interrucion, configuro el trisc como me dijiste y se ha solucionado todo =D nuevamente muchas gracias.
de nada me alegro que te funcione un saludo
PPyote... siempre estareis en mi corazon.... Te quiero Hermano...

Desconectado cedruiz

  • PIC10
  • *
  • Mensajes: 8
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #8 en: 23 de Enero de 2011, 13:38:30 »
listo como todo esta solucionado y ahora si tengo tiempo aca dejo como solucione este problema por si alguien tiene este inconveniente.

ya q el inconveniente se presentaba con la rutina de manejo del teclado matricial 4x3 (KBD.c) hice una pequeña modificación un poco trivial pero funciona para el caso donde se tenga el teclado matricial en el puerto b y se necesite la interrupcion ext por rb0 adjunto la rutina (KBD1.c)

espero pueda servile a alguien saludos =D

Desconectado aprendiendoles

  • PIC10
  • *
  • Mensajes: 1
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #9 en: 12 de Junio de 2012, 13:43:57 »
muy  buen aporte ... facil solucion .. gracias creia que yo era el unico al que le pasaba esto

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #10 en: 04 de Diciembre de 2012, 15:48:00 »
Hola buenas tardes!

Llevo un tiempo siguiendo este foro para aprender lenguaje C pero pocas veces me he animado a escribir en el. Tengo un problema parecido al del creador de este tema pero mi sistema sigue sin funcionar aun utilizando las soluciones que se dijeron en el.
Estoy creando un sistema de alarma tambien. El programa funcionaba perfectamente, pero al añadirle la interrupcion externa no me funciona y la parte de la interrupcion por separado si. Es una cosa un poco rara porque si elimino el cable que une el pin del micro de la interrupcion del interruptor que la crea, el programa funciona correctamente excepto lo que es la interrupcion.
Aquí les dejo el programa para ver si me podeis ayudar. Tambien adjunto los diferentes archivos del programa con la libreria del teclado y el esquema del circuito electrico

#include "C:\Users\acer\Documents\Ruben\UNIVERSIDAD\PFC\Pruebas en C\Pruebas\prueba.h"

#fuses XT            //Crystal osc <= 4mhz               
#fuses NOWDT         //deshabilita el Watch Dog Timer
#fuses NOPROTECT     //deshabilita la proteccion del codigo del pic
#fuses PUT           //habilita el reseteo de power up timer
#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 = 4000000)

#use fast_io(A)       //con esta instruccion evitamos que
#use fast_io(B)       //se este configurando cada vez que usamos
#use fast_io(C)       //alguna instruccion de entrada o salida
#BYTE TRISA = 0b10000101   //TRISA = 0x85
#BYTE PORTA = 0b00000101   //PORTA = 0x05
#BYTE TRISB = 0b10000110   //TRISB = 0x86
#BYTE PORTB = 0b00000110   //PORTB = 0x06
#BYTE TRISC = 0b10000111   //TRISC = 0x87
#BYTE PORTC = 0b00000111   //PORTC = 0x07

#include <kbd3x4_2.c>         //libreria manejo keypad 3x4
#include <lcd3.c>             //libreria manejo lcd 8 bits
#include <string.h>           //libreria manejo cadenas

#rom 0x2100={0,0,0,0,0,0,0}   //la EEPROM se carga con los valores 00h desde la direccion 00h hasta 06h



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

void menu_principal(void);             //funcion que muestra el menu principal
void escribir_clave(char clave[]);     //funcion que escibre la clave tecleada
void cambia_clave_inicial(void);       //funcion que cambia clave
void cambiar_clave(void);              //funcion que cambia clave
int comparar_claves(int);              //función que compara las claves
void nueva_clave_admin(void);          //funcion que añade la nueva clave administrativa
void activar_alarma(void);             //funcion que activa la alarma
void desactivar_alarma(void);          //funcion que desactiva la alarma
void escribir_clave_en_eeprom(int);    //función que escribe las claves en la memoria eeprom
void leer_clave_en_eeprom(int);        //función que lee las claves y las guarda en su correspondiente variable
void alarma_general(void);             //funcion que enciende la sirena
void conteo_intentos(void);            //funcion que cuenta el numero de intentos de ingreso de contraseña



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

char clave_inicial[3]= {'1','2','3'};  //variable usada como clave de inicio
char clave_eeprom_admin[3];            //variable usada para comparar los datos de la eeprom contra los datos ingresados             
char clave[3];                         //variable usada para recoger la clave tecleada
char k;                                //variable usada para recoger las teclas pulsadas del teclado
signed char i;                         //variable usada para movernos por las posiciones de la memoria
char clave_introducida[3]={};          //variable usada para los datos ingresados
int alarm_cont=0;                      //variable global que cuenta los fallos
int flag;


//////////////////LLAMADA FUNCION INTERRUPCION//////////////
#INT_EXT
void intrb0(void)

{
    flag=1;
}



////////////////////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;
   set_tris_b(0b11100001);
   set_tris_c(0b11100000);
   enable_interrupts(int_ext);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   
   lcd_init();            //inicializa lcd
   delay_ms(1000);
   lcd_putc ("   Bienvenido   ");
   delay_ms(1000);
   
   for( ; ; )
   {
      cambia_clave_inicial();
      menu_principal();
      if(flag==1)
      {
         delay_ms(20);           //antirrebote
         flag=0;
         alarma_general ();
      }
      do
      {
         cambia_clave_inicial();
         menu_principal();
      }while(flag==0);
   
   }
   
}


//////////FUNCION CAMBIAR CLAVE INICIAL
void cambia_clave_inicial(void)             //funcion que cambia clave administrativa

{
int p;
   clave_introducida=0;
   escribir_clave(clave_introducida);
   p=strcmp(clave_introducida , clave_inicial);
   if (p==0)     
         {lcd_putc("\fClave Correcta\n");
          delay_ms(2000);
          nueva_clave_admin();
         }
   if (p!=0)
         {lcd_putc("\fClave Incorrecta\n");
          delay_ms(2000);
          clave_introducida=0;
          //conteo_intentos();
          alarma_general ();
         }
}

//////////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{
         do{               //espera hasta...
            k=kbd_getc();   
           }while(k==0);   //...pulsar una tecla
         
            if(!(k=='*' || k=='#'))
            {     
            lcd_putc("*");
            clave=k;
            }       
     i++;
     
     }while( !(k=='*' || k=='#') );        //Si '*' o '#' señalamos que hemos terminado de introducir la contraseña
}

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

{
     for( ; ; )
    {
      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':         //va a activar la alarma
         activar_alarma();
      break;
      case '1':         //va a comprobar clave para despues cambiar la clave
         cambiar_clave();
      break;
     }
    }   
}




//////////FUNCION CAMBIAR CLAVE
void cambiar_clave(void)             //funcion que cambia clave administrativa

{
int p;
   escribir_clave(clave_introducida);
   leer_clave_en_eeprom(i);
   p=comparar_claves(i);
   if (p==0)     
         {lcd_putc("\fClave Correcta\n");
          delay_ms(2000);
          nueva_clave_admin();
         }
   if (p!=0)
         {lcd_putc("\fClave Incorrecta\n");
          delay_ms(2000);
          clave_introducida=0;
          alarma_general ();
         }
}


//////////FUNCION NUEVA CLAVE
void nueva_clave_admin(void)                 //funcion que añade la nueva clave administrativa

{
int i=0;
   lcd_putc("\fNueva clave:\n");   //presentacion
   do{
         do{               //espera hasta...
            k=kbd_getc();   
           }while(k==0);   //...pulsar una tecla
         
            if(k!='*' || k!='#')   
            {     
            lcd_putc("*");
            clave=k;
            }
     escribir_clave_en_eeprom(i);
     i++;
     
     }while( !(k=='*' || k=='#') );       //Si '*' o '#' señalamos que hemos terminado de introducir la contraseña
}


//////////FUNCION COMPARAR CLAVES
int comparar_claves(int)                  //funcion que cambia clave administrativa

{
int i=0;
int s=0;
   for (i=0;i<3;i++)
   {
      if (clave_introducida==clave_eeprom_admin)
        s++;
      else
        {s=0;
         lcd_putc("\fClave Incorrecta\n");
         break;
        }
   }
   if (s==3)
      return 0;
}


//////////ACTIVAR ALARMA
void activar_alarma(void)

{
int i=0;
int p=0;
   escribir_clave(clave_introducida);
   leer_clave_en_eeprom(i);
   p=comparar_claves(i);
   if (p==0)     
         {lcd_putc("\fAlarma Activada");
          delay_ms(2000);
          desactivar_alarma();
         }
   if (p!=0)
         {lcd_putc("\fClave Incorrecta\n");
          delay_ms(2000);
          clave_introducida=0;
          alarma_general ();
         }
}


//////////DESACTIVAR ALARMA
void desactivar_alarma(void)

{
int i=0;
int p=0;
   lcd_putc("\fDesactivar alarma\n");   //presentacion
   escribir_clave(clave_introducida);
   leer_clave_en_eeprom(i);
   p=comparar_claves(i);
   if (p==0)     
         {lcd_putc("\fAlarma\nDesactivada");
          delay_ms(2000);
          break;
         }
   if (p!=0)
         {lcd_putc("\fClave Incorrecta\n");
          delay_ms(2000);
          clave_introducida=0;
          alarma_general ();
         }
}


//////////ESCRIBIR_CLAVE_EN_EEPROM
void escribir_clave_en_eeprom(int i)     //función que escribe las claves en la memoria eeprom

{
   write_eeprom (i,k);             //guardamos cada valor de la variable global correspondiente
   delay_ms(20);                   //en la direccion i + 0 (para no pisar datos) de la eeprom
   i++;                            //en una palabra escribe de la posicion 0 a la 4 (5 lugares)
}


//////////LEER_CLAVE_EN_EEPROM
void leer_clave_en_eeprom(int i)       //función que lee las claves y las guarda en su correspondiente variable

{
    for (i=0;i<3;i++)
    {
      clave_eeprom_admin = read_eeprom(i);      //guardamos cada valor de la direccion i + 0 (para no pisar datos)
      delay_ms(20);                                //de la eeprom en la variable global correspondiente
    }
}



////////////FUNCION CONTEO INTENTOS
/*void conteo_intentos(void)             //funcion que cuenta el numero de intentos de ingreso de contraseña

{
   if (alarm_cont==3)
      alarma_general();
   else
      alarm_cont++;
}*/



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

{
    set_tris_c(0b11100000);      //pines C0 hasta C4 como salida                             
    output_high(pin_C0);         //enciende la sirena durante 10 seg y muestra mensaje
    //lcd_putc("\fALARMA\n");         
    delay_ms(2000);
    output_low(pin_C0);          //apaga la sirena
    alarm_cont = 0;              //pongo a cero el contador de errores
    break;
}


Muchas gracias por todo



« Última modificación: 12 de Diciembre de 2012, 08:42:23 por escarrillense »

Desconectado escarrillense

  • PIC10
  • *
  • Mensajes: 41
Re: interrupcion externa, teclado matricial, 16f877a
« Respuesta #11 en: 11 de Diciembre de 2012, 07:23:58 »
Buenos dias!

Se me olvido comentar en el anterior post que estoy utilizando un PIC16F876 en lugar del micro citado en el título del tema, que la versión de Proteus que empleo es la 7.7 y que el compilador es CCS