checa,compilando con las modificaciones que te menciono no hay mas problema
#include<16f876.h>
#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
#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 captura(void); //funcion que captura la clave tecleada
void cambia_clave_inicial(void); //funcion que cambia la clave inicial
void escribir_clave(void); //funcion que escibre la clave tecleada
void nueva_clave_admin(void); //funcion que añade la nueva clave administrativa
void limpiar_clave(void); //funcion que pone a '0' la variable clave
void escribir_clave_en_eeprom(int d); //función que escribe las claves en la memoria eeprom
void menu_principal(void); //funcion que muestra el menu principal
void cambiar_clave(void); //funcion que cambia clave admin
void leer_clave_en_eeprom(int); //función que lee las claves y las guarda en su correspondiente variable
int comparar_claves(int); //función que compara las claves
void alarma_general(void); //funcion que enciende la sirena
////////////////VARIABLES GLOBALES///////////////////////////
int flag_teclado=0; //flag que señala que una tecla ha sido pulsada
char bandera=0,bandera_rb=0; //flag que señala que se ha producido una interrupcion externa
int tecla; //variable que recoge la tecla pulsada
int fila,columna; //variables que recogen la fila y columna de la tecla pulsada
char clave[3]={}; //variable usada para recoger la clave tecleada
char clave_inicial[3]= {'1','2','3'}; //variable usada como clave de inicio
int d=0; //variable usada para movernos por las posiciones de la memoria
char clave_eeprom_admin[3]; //variable usada para comparar los datos de la eeprom contra los datos ingresados
int lectura_1,lectura_2; //variables locales para detectar la tecla pulsada
/***************************************
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()
{
bandera_rb=1;
}
//////////////INTERRUPCION EXTERNA//////////////////
#INT_EXT
void externa(void)
{
bandera=1; //marcamos que se ha producido una interrupcion externa
}
//////////////PROGRAMA PRINCIPAL///////////////////////
void main()
{
set_tris_b(0b11110001); //configuro el puerto b
set_tris_c(0b11111111); //configuro el puerto c
enable_interrupts(INT_RB); //habilito la interrupcion por cambio de nibble alto
ext_int_edge(H_TO_L); //habilito la interrupcion externa por cambio de flanco
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL); //habilito las interrupciones
lcd_init(); //inicializa lcd
delay_ms(1000);
lcd_putc (" Bienvenido ");
delay_ms(1000);
lcd_putc("\fEscribir clave:\n");
while(TRUE)
{
menu_principal();
if(flag_teclado==1) //Si se ha pulsado una tecla
{
flag_teclado=0;
cambia_clave_inicial(); //cambio la contraseña que viene por defecto
}
if(bandera_rb==1)
{
bandera_rb=0;
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.
{
flag_teclado=1; //marcamos que se ha pulsado una tecla
captura(); //capturamos dicha tecla
}
set_tris_b(0b11110000);
output_b(0b00001111);
clear_interrupt(INT_RB);
set_tris_b(0b11110001);
}
if(bandera==1) //Si se ha producido una interrupcion externa
{
bandera=0;
alarma_general(); //activo la sirena
}
}
}
/********************************
Esta Rutina permite rastrear el teclado
y devuelve el valor de la tecla que se
ha presionado
************************************/
void captura(void) //funcion que captura la clave tecleada
{
int const teclado[4][4] = {{0,'1','2','3'},
{0,'4','5','6'},
{0,'7','8','9'},
{0,'*','0','#'}};
int 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];
}
//////////FUNCION CAMBIAR CLAVE INICIAL
void cambia_clave_inicial(void) //funcion que cambia la clave inicial
{
int p;
escribir_clave(); //tecleo la contraseña
if (d==3) //Si ya se han introducido todos los valores de la clave
{
p=strncmp(clave , clave_inicial,3); //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);
limpiar_clave(); //pongo a '0' la variable clave
nueva_clave_admin(); //introduzco la nueva clave
}
if (p!=0) //si las dos claves son distintas
{lcd_putc("\fClave Incorrecta\n");
delay_ms(2000);
limpiar_clave(); //pongo a '0' la variable clave
alarma_general (); //activo la alarma
}
}
}
//////////FUNCION ESCRIBIR CLAVE
void escribir_clave() //funcion que escibre la clave tecleada
{
lcd_putc("*");
clave[d]=tecla;
if(d<3) //Si no se han introducido todos los valores...
{
d++; //... incremento una posicion de memoria
}
else //Si se han introducido todos los valores...
{
d=0; //... salgo
}
}
//////////LIMPIAR CLAVE
void limpiar_clave() //función que pone a '0' la variable clave
{
int k;
for(k=0;k<3;k++) //limpiamos uno a uno cada valor de la variable
{
clave[k]=0x00;
}
}
/////FUNCION MENU PRINCIPAL
void menu_principal (void) //funcion que muestra el menu principal
{
tecla=0;
d=0;
lcd_putc("\f0-Activa Alarma\n1-Cambia Clave");
delay_ms(2000);
while(tecla==0 && bandera==0);
{
switch (tecla)
{
case '0': //si '0' va a activar la alarma
//activar_alarma();
alarma_general();
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(); //escribimos la contraseña
if (d==3) //Si ya se han introducido todos los valores de la clave
{
leer_clave_en_eeprom(d); //lee la contraseña que antes hemos cambiado
p=comparar_claves(d); //compara ambas claves
if (p==0) //si son iguales...
{lcd_putc("\fClave Correcta\n");
delay_ms(2000);
limpiar_clave(); //pongo a '0' la variable clave
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);
limpiar_clave(); //pongo a '0' la variable clave
alarma_general (); //activa la alarma
}
}
}
//////////FUNCION NUEVA CLAVE
void nueva_clave_admin(void) //funcion que añade la nueva clave administrativa
{
tecla=0; //limpio las variables
int aux=0;
d=0;
lcd_putc("\fNueva clave:\n"); //presentacion
delay_ms(500);
for(aux=0;aux<3;aux++)
{
while(tecla==0 && bandera==0);
{
flag_teclado=0;
lcd_putc("*");
clave[d]=tecla;
if(d<3)
{
escribir_clave_en_eeprom(d); //guardamos la nueva clave en la memoria EEPROM
tecla=0;
d++;
}
else
{
d=0;
break;
}
}
}
//menu_principal(); //voy al menu principal
}
//////////FUNCION COMPARAR CLAVES
int comparar_claves(int) //funcion que compara la clave administrativa y la introducida
{
d=0;
int s=0;
for (d=0;d<3;d++) //comparo caracter a caracter las claves
{
if (clave[d]==clave_eeprom_admin[d]) //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'
}
//////////ESCRIBIR_CLAVE_EN_EEPROM
void escribir_clave_en_eeprom(int d) //función que escribe las claves en la memoria eeprom
{
write_eeprom (d,tecla); //guardamos cada valor de la variable global correspondiente
delay_ms(20); //en la direccion d + 0 (para no pisar datos) de la eeprom
d++; //en una palabra escribe de la posicion 0 a la 2 (3 lugares)
}
//////////LEER_CLAVE_EN_EEPROM
void leer_clave_en_eeprom(int d) //función que lee las claves y las guarda en su correspondiente variable
{
for (d=0;d<3;d++)
{
clave_eeprom_admin[d] = read_eeprom(d); //guardamos cada valor de la direccion i + 0 (para no pisar datos)
delay_ms(20); //de la eeprom en la variable global correspondiente
}
}
//////////FUNCION ALARMA GENERAL
void alarma_general (void) //funcion que enciende la sirena
{
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;
}
solo comente la linea de la llamada a menu_principal() que es la que causa el error y la coloque al inicio del while,pero como mencione puedes cambiarla segun tus necesidades
saludos