Control de acceso "IN" SIMULABLE

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.

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.
 
Hola,

Si tu programa compila correctamente entonces el problema es del simulador si estas utilizando una version LITE ése es el problema. Prueba con una version Profesional.

Suerte y ánimo.

PD: No maldigas a Murphy si existe algun error es tuyo no de él.
 
Atrás
Arriba