Ayuda por favor, hace días que intento simular este programa en Proteus, luego en MpLab con Proteus y nada NADA NADAAAAAAAAA. Estoy desesperado, programé muchas líneas de código, lo dejé bonito pero la LEY 23423425 DEL MALDITO MURPHY me vino a impedir el debbugeo. Si algún genio anda por aquí muchas gracias.
Es archivo del código lo pongo acá porque es algo largo.
http://www.tecnosoluciones.com.ar/Control_de_Acceso.rar
una parte del main y las declaraciones a continuacion.
Las funciones están en el rar, junto con el circuito en Proteus y el proyect de MpLab.
Agradecido desde ya.
Es archivo del código lo pongo acá porque es algo largo.
http://www.tecnosoluciones.com.ar/Control_de_Acceso.rar
una parte del main y las declaraciones a continuacion.
Código:
////////////////////////////////////////////////////////////////////////////////////
// Aristides E. E. Zago
// 7 Agosto 2007
// [email]zagoaristides@hotmail.com[/email]
// Programa: Control de acceso con LCD, teclado 3x4 y alarma
// Version: 1.0
//
// Dispositivo: PIC 16F648A Compilador: CCS v.4.023
// Simulador: Proteus 7.1 Entorno IDE: MpLab 7.60
//
// ---------------------------------- Explicación ---------------------------------- \\
//
// Notas: se interacciona por un teclado de 3x4 y una pantalla LCD de 1x16
// Tenemos 1 menú principal con 2 opciones
//
// 0 Claves de entrada
// 1 Menu de opciones secundario
//
// 0-Claves de entrada:
// Tiene 2 opciones
// 0-Simple
// 1-Temporal
//
// 0:Se pide una clave válida de 4 dígitos
// se comprueba su validez y si es correcta se abre la puerta
// si es incorrecta se avisa que en X fallos se activará la
// alarma
//
// 1:Se verifica si existe la posibilidad con una bandera.
// Si existe se pide la clave y se da acceso.
// si es incorrecta se avisa que en X fallos se activará la
// alarma.
// Durará una X cantidad de ingresos.
//
//
// 1- Menú de opciones secundario:
// Tiene 2 opciones
// 0-Cambiar Clave
// 1-Ingreso admin
//
// 0-Cambiar Clave: sirve para cambiar las claves de entrada temporal,
// simple o de administrador. Se pide la contraseña del administrador y
// luego si es correctase pide una nueva clave de x dígitos según la clave
// a cambiar.
//
// 1-Ingreso admin: Sirve para ingresar de modo rápido ante cualquier
// inconveniente. Debe usarse solo en ocasiones especiales.
// Con el ingreso de administrador se borra el aviso si se activó la
// alarma en algún momento y se apaga la alarma si se activó por accidente
// u otro motivo.
//
// ERROR de tipo 1 = se pasó del número permitido de dígitos
//
// ---------------------------------- ----------- ---------------------------------- \\
//
// ------------------------------------ PINOUTS ------------------------------------ \\
// Tener en cuenta que hay que poner la directiva
// NOLVP para que el pin B4 sea de salida.
//
// Conexiones: B0 -> D0 LCD/Columna 1 keypad
// B1 -> D1 LCD/Columna 2 keypad
// B2 -> D2 LCD/Columna 3 keypad
// B3 -> D3 LCD
// B4 -> D4 LCD/Fila A keypad
// B5 -> D5 LCD/Fila B keypad
// B6 -> D6 LCD/Fila C keypad
// B7 -> D7 LCD/Fila D keypad
// A0 -> RS LCD
// A1 -> RW LCD
// A2 -> E LCD
// A3 -> Alarma
// A4 -> Led de activación de alarma 1(reseteable)
// A5 -> Apertura de puerta---------------------------1:Abre la puerta
// A6 -> Sensor de apertura de puerta-----------------0uerta Cerrada
// A7 -> Backlight via un transistor NMOS o NPN-------1:Activa el LED
//
// ------------------------------------ ------- ------------------------------------ \\
#include <16f648a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#include<kbd3x4.c> //libreria manejo keypad
#include<lcd2.c> //libreria manejo lcd 8bits
#use fixed_io(a_outputs=PIN_A3,PIN_A4,PIN_A5,PIN_A6,PIN_A7)
#use standard_io(a)
///DEFINICION DE FUNCIONES
void menu_principal (void); //funcion que muestra el menu principal
void menu_ingreso(void); //funcion que muestra el menu de ingreso (Simple - Temporal)
void menu_admin(void); //funcion que muestra el menu administrador (cambio de clave - acceso admin)
void menu_cambiar_claves(void); //funcion que muestra el menu cambio de claves (Admin., temporal, simple)
short ingresar_clave(int); //función a la que se ingresa el tipo de clave (Admin., temporal, simple)
// y guarda la clave y devuelve 1 si es correcto
short comprobar_clave(int); //funcion que comprueba las claves de uno de los tipos (Admin., temporal, simple)
short cambiar_clave(int); //funcion que cambia las claves de uno de los tipos (Admin., temporal, simple)
void leer_clave_en_eeprom(int); //funcion para leer la eeprom y almacenar los datos en las variables (clave_eeprom_x[];-)
void escribir_clave_en_eeprom(int); //funcion para escribir la eeprom los datos de las variables (clave_eeprom_x[];-)
void abrir_puerta(void); //funcion que abre la puerta y ejecuta tareas de chequeo de cerrado
void alarm_check(void); //función que chequea el número de errores acumulados
// y llama a la func. alarma si correspondiera
void alarma (int);
///VARIABLES GLOBALES
int clave_admin[8]={0,1,2,3,4,5,6,7}; //variable usada para guardar temporalmente los datos ingresados
int clave_simple[6]={0,1,2,3,4,5}; //variable usada para guardar temporalmente los datos ingresados
int clave_temp[4]={0,1,2,3}; //variable usada para guardar temporalmente los datos ingresados
int clave_eeprom_admin[8]={0,1,2,3,4,5,6,7}; //variable usada para comparar los datos de la eeprom contra los datos ingresados
int clave_eeprom_simple[6]={0,1,2,3,4,5}; //variable usada para comparar los datos de la eeprom contra los datos ingresados
int clave_eeprom_temp[4]={0,1,2,3}; //variable usada para comparar los datos de la eeprom contra los datos ingresados
int alarm_cont; //variable global que cuenta los fallos
int temp = 4;
int simple = 6;
int admin = 8;
long delay_txt = 100; //delay en ms para textos en pantalla
long delay_anim = 50; //delay en ms para animacion
int delay_r_w = 20; //delay en ms para lectura/escritura
long delay_apertura = 300; //delay en ms para apertura de puerta
int alarma_puerta = 2; //variable que se pasa a la funcion alarma para dar pequeños y cortos sonidos si
//la puerta continúa abierta una x cant. de segs.
int alarma_gral = 3; //variable que se pasa a la funcion alarma para dar la orden de activación contínua
short alarm_flag = 0; //variable de bandera para saber si se activó la alarma durante nuestra ausencia
////////// ----------------------------------------- Inicio del PROGRAMA ----------------------------------------- \\\\\\\\\\
void main(void)
{
char c; //variable donde se almacena tecla pulsada
lcd_init(); //inicializa lcd
output_low(PIN_A7); //Desactivo el BACKLIGHT
for(;;-) //bucle...
{
do{ //espera hasta...
c=kbd_getc();
//mostrar_cecha y hora (implementado con otro chip)
}while(c==0); //...pulsar una tecla
} //...infinito
output_high(PIN_A7); //Activo el BACKLIGHT
menu_principal();
}
void menu_principal (void)
{
char opc;
//short ver_led; //se usa solo para poder llamar a alarm_check
lcd_putc("\fBienvenido:";-) ; //presentacion
delay_ms(delay_txt);
alarm_check(); //verificacion de estado de la cuenta para la alarma
//ver_led = alarm_check(); //verificacion de estado de la cuenta para la alarma
lcd_putc("\f0-Ingreso 1-Adm.";-) ; //fin de presentacion
do
{ //espera hasta...
opc=kbd_getc();
}while(opc==0); //...pulsar una tecla
switch (opc)
{
case '0':
menu_ingreso();
break;
case '1':
menu_admin();
break;
default:
lcd_putc("\fTecla incorrecta";-) ;
break;
}
} //// -------------------------- fin de la funcion menu_principal() -------------------------- \\\\
void menu_ingreso(void)
{
char opc;
short clave_ingreso = 0; //variable que se iguala a las funciones de ingreso / 0: Mal ingresado
short clave_corr = 0; //variable que se iguala a la función de comprobación de clave / 0: Clave incorrecta
//short disparo=0; //la variable de disparo de alarma se inicia reseteada (solo ésta que es local, la global alarm_cont no se toca)
lcd_putc("\f0-Simple 1-Tempo";-) ; //presentacion
do
{ //espera hasta...
opc=kbd_getc();
}while(opc==0); //...pulsar una tecla
//// -------------------- Inicio del switch -------------------- \\\\
switch (opc)
{
//------------------------------CASO 0-----------------------------------//
case '0':
{
clave_ingreso = ingresar_clave(simple); //Si la func ingresar_clave(simple)
if (clave_ingreso == 1) //Si me devuelve 1
{
clave_corr = comprobar_clave(simple); //compruebo la clave
if (clave_corr == 1) //Si me devuelve 1
{
abrir_puerta(); //abro la puerta
//alarm_cont = 0; //reseteo la variable de número de errores antes de la alarma
} //anulé la sentencia anterior porque un usuario simple podría ir intentando descifrar la clave admin
}
else //Si la func ingresar_clave(simple) me devuelve 0
{
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
//------------------------------CASO 1-----------------------------------//
case '1':
{
clave_ingreso = ingresar_clave(temp); //Si la func ingresar_clave(temp)
if (clave_ingreso == 1) //me devuelve 1
{
clave_corr = comprobar_clave(temp); //compruebo la clave
if (clave_corr == 1) //Si me devuelve 1
abrir_puerta(); //abro la puerta
else //Si me devuelve 0
{
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
else //Si me devuelve 0
{
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
default:
lcd_putc("\fTecla incorrecta";-) ;
break;
}
//// --------------------- Fin del switch --------------------- \\\\
} //// -------------------------- fin de la funcion menu_ingreso() -------------------------- \\\\
void menu_admin(void)
{
char opc;
short clave_ingreso = 0; //variable que se iguala a la función de ingresar_clave / 0: Mal ingresada
short clave_corr = 0; //variable que se iguala a la función de comprobación de clave / 0: Clave incorrecta
//short disparo=0; //la variable de disparo de alarma se inicia reseteada (solo ésta que es local, la global alarm_cont no se toca)
for (;;-) //espera hasta...
{
opc=kbd_getc();
lcd_putc("\f0-Cambio de Clave";-) ; //presentacion de dos líneas que van cambiando
delay_ms(delay_txt);
if (opc !=0)
break;
lcd_putc("\f1-Ingreso Admin";-) ;
delay_ms(delay_txt);
opc=kbd_getc();
if (opc !=0)
break;
} //...pulsar una tecla
//// -------------------- Inicio del switch -------------------- \\\\
switch (opc)
{
//------------------------------CASO 0-----------------------------------//
case '0':
{
menu_cambiar_claves(); //Menu de cambio de claves
}
//------------------------------CASO 1-----------------------------------//
case '1':
{
clave_ingreso = ingresar_clave(admin); //Si la func ingresar_clave(admin)
if (clave_ingreso == 1) //me devuelve 1
{
clave_corr = comprobar_clave(admin); //compruebo la clave
if (clave_corr == 1) //Si me devuelve 1
{
alarm_cont = 0; //reseteo la variable de número de errores antes de la alarma
alarm_flag = 0; //reseteo la bandera de alarma activada durante la ausencia
abrir_puerta(); //abro la puerta
}
else //Si me devuelve 0
{
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
else //Si la func ingresar_clave(admin) me devuelve 0
{
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
default:
lcd_putc("\fTecla incorrecta";-) ;
break;
}
//// --------------------- Fin del switch --------------------- \\\\
} //// -------------------------- fin de la funcion menu_admin() -------------------------- \\\\
void menu_cambiar_claves(void) //Menu que pide que tipo de clave a cambiar y verifica
{
char opc;
short clave_cambiada = 0; //variable que se iguala a la función de ingresar_clave / 0: No se cambió
short disparo=0;
do //espera hasta...
{
opc=kbd_getc();
lcd_putc("\f0-Sp 1-Tmp 2-Adm";-) ; //presentacion de dos líneas que van cambiando
}while (opc ==0); //...pulsar una tecla
//// -------------------- Inicio del switch -------------------- \\\\
switch (opc)
{
//------------------------------CASO 0-----------------------------------//
case '0':
{
clave_cambiada = cambiar_clave(simple); //Cambio de clave simple
if (clave_cambiada == 1)
{
lcd_putc("\fClave cambiada";-) ;
delay_ms(delay_txt);
}
else
{
lcd_putc("\fClave no cambiada";-) ;
delay_ms(delay_txt);
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
//------------------------------CASO 1-----------------------------------\\
case '1':
{
clave_cambiada = cambiar_clave(temp); //Cambio de clave simple
if (clave_cambiada == 1)
{
lcd_putc("\fClave cambiada";-) ;
delay_ms(delay_txt);
}
else
{
lcd_putc("\fClave no cambiada";-) ;
delay_ms(delay_txt);
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
alarm_check();
//disparo = alarm_check(); //y llamo a la función de chequeo de alarma
//if (disparo == 1) //Si se debe disparar
// alarma(alarma_gral); //disparo la alarma
}
}
//------------------------------CASO 2-----------------------------------\\
case '2':
{
clave_cambiada = cambiar_clave(admin); //Cambio de clave simple
if (clave_cambiada == 1)
{
lcd_putc("\fClave cambiada";-) ;
delay_ms(delay_txt);
}
else
{
lcd_putc("\fClave no cambiada";-) ;
delay_ms(delay_txt);
alarm_cont += 1; //sumo 1 a la variable de número de errores antes de la alarma
disparo = alarm_check(); //y llamo a la función de chequeo de alarma
if (disparo == 1) //Si se debe disparar
alarma(alarma_gral); //disparo la alarma
break;
}
}
//-------------------------CASO por DEFAULT------------------------------\\
default:
lcd_putc("\fTecla incorrecta";-) ;
delay_ms(delay_txt);
break;
}
//// --------------------- Fin del switch --------------------- \\\\
} //// -------------------------- fin de la funcion menu_cambiar_claves() -------------------------- \\\\
Las funciones están en el rar, junto con el circuito en Proteus y el proyect de MpLab.
Agradecido desde ya.