Ok lo siento! pensaba que lo habia introducido en el .zip que adjunté en el primer post. En el que adjunto ahora he introducido algun cambio sin importancia como el traslado del lcd al puerto B pero ya lo he modificado en su libreria. ¿Podría ser el fallo la librería del teclado o como la gestiono en el programa la causa del problema de que no me detecte las teclas? El otro problema que tengo, el de la interrupción, me detecta la interrupción, entra en ella, pero luego no llega al main para leer el flag=1 de la rutina de la interrupción. Vuelvo a poner el programa con alguna modificacion que he hecho pero sigue sin funcionar.
#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 Registro de direccionamiento Puerto A
#BYTE PORTA = 0b00000101 //PORTA = 0x05 Puerto A
#BYTE TRISB = 0b10000110 //TRISB = 0x86 Registro de direccionamiento Puerto B
#BYTE PORTB = 0b00000110 //PORTB = 0x06 Puerto B
#BYTE TRISC = 0b10000111 //TRISC = 0x87 Registro de direccionamiento Puerto C
#BYTE PORTC = 0b00000111 //PORTC = 0x07 Puerto C
//#bit RB0=0x06.1
#byte kbd_port_b = 6
#include <kbd3x4_2.c> //libreria manejo keypad 3x4
#include <LCD4.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; //variable usada como bandera para las interrupciones
static int flag;
//////////////////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.
output_b(input_b()); // leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar
/*set_tris_c(0b11111110); //pines C0 como salida
output_high(pin_C0); //enciende la sirena durante 2 seg y muestra mensaje
delay_ms(2000);
output_low(pin_C0); //apaga la sirena
output_b(input_b()); // leer/escribir el puerto B al finalizar la interrupción para que no se vuelva a ejecutar
clear_interrupt(int_ext); //ponemos a '0' el flag*/
}
////////////////////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
//port_b_pullups(true); //activo las resistencias de pullup
ext_int_edge(L_TO_H); //activo la interrupcion externa por cambio de bajo a alto
clear_interrupt(int_ext); //pongo a '0' el flag de la interrupcion externa
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);
while(true)
{
if(flag==1)
{
disable_interrupts(int_ext); //deshabilitamos la interrupcion externa
clear_interrupt(int_ext); //ponemos a '0' el flag
delay_ms(20); //antirrebote
alarma_general (); //activamos la alarma
flag=0; //ponemos la variable flag a '0'
enable_interrupts(int_ext); //habilito la interrupcion externa
enable_interrupts(GLOBAL); //habilito las interrupciones
}
else
{
cambia_clave_inicial(); //cambio la contraseña que viene por defecto
menu_principal(); //voy al menu principal
}
}
}
//////////FUNCION CAMBIAR CLAVE INICIAL
void cambia_clave_inicial(void) //funcion que cambia clave administrativa
{
int p;
clave_introducida=0; //pongo la clave tecleada a 0
escribir_clave(clave_introducida); //tecleo la contraseña
p=strcmp(clave_introducida , clave_inicial); //comparo la clave por defecto con la tecleada
if (p==0) //si las dos claves son iguales:
{lcd_putc("\fClave Correcta\n");
delay_ms(2000);
nueva_clave_admin(); //introduzco la nueva clave
}
if (p!=0) //si las dos claves son distintas
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0; //borro la clave introducida
//conteo_intentos();
alarma_general (); //activo la alarma
}
}
//////////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=='#')) // Si no es '*' o '#' en la pantalla aparece un '*'
{
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': //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;
}
}
}
//////////FUNCION CAMBIAR CLAVE
void cambiar_clave(void) //funcion que cambia clave administrativa
{
int p;
escribir_clave(clave_introducida); //escribimos la contraseña
leer_clave_en_eeprom(i); //lee la contraseña que antes hemos cambiado
p=comparar_claves(i); //compara ambas claves
if (p==0) //si son iguales...
{lcd_putc("\fClave Correcta\n");
delay_ms(2000);
nueva_clave_admin(); //vamos a la rutina para introducir la nueva clave
}
if (p!=0) //si son distintas...
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0; //borra la clave ahora introducida
alarma_general (); //activa la alarma
}
}
//////////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!='#') // Si no es '*' o '#' en la pantalla aparece un '*'
{
lcd_putc("*");
clave=k;
}
escribir_clave_en_eeprom(i); //guardamos la nueva clave en la memoria EEPROM
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 compara la clave administrativa y la introducida
{
int i=0;
int s=0;
for (i=0;i<3;i++) //comparo caracter a caracter las claves
{
if (clave_introducida==clave_eeprom_admin) //si el caracter es igual en las dos claves
s++; //paso al siguiente caracter
else //si es distinto la contraseña es incorrecta
{s=0;
lcd_putc("\fClave Incorrecta\n");
break;
}
}
if (s==3) //si todos los tres caracteres son iguales
return 0; //devuelvo un '0'
}
//////////ACTIVAR ALARMA
void activar_alarma(void) //funcion que activa la alarma
{
int i=0;
int p=0;
escribir_clave(clave_introducida); //escribimos la contraseña
leer_clave_en_eeprom(i); //lee la contraseña administrativa grabada anteriormente en la EEPROM
p=comparar_claves(i); //compara ambas claves
if (p==0) //si son iguales...
{lcd_putc("\fAlarma Activada");
delay_ms(2000);
desactivar_alarma(); //vamos a la rutina para desactivar la alarma
}
if (p!=0) //si son distintas...
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0; //borra la clave ahora introducida
alarma_general (); //activo la alarma
}
}
//////////DESACTIVAR ALARMA
void desactivar_alarma(void) //funcion que desactiva la alarma
{
int i=0;
int p=0;
lcd_putc("\fDesactivar alarma\n"); //presentacion
escribir_clave(clave_introducida); //escribimos la contraseña
leer_clave_en_eeprom(i); //lee la contraseña administrativa grabada anteriormente en la EEPROM
p=comparar_claves(i); //compara ambas claves
if (p==0) //si son iguales...
{lcd_putc("\fAlarma\nDesactivada");
delay_ms(2000);
break; //vuelve al menu principal
}
if (p!=0) //si son distintas...
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
clave_introducida=0; //borra la clave ahora introducida
alarma_general (); //activo la alarma
}
}
//////////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(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
alarm_cont = 0; //pongo a cero el contador de errores
//break;
//desactivar_alarma();
}