¿Cómo generar un segundo en un pic?

Hola, para empezar, debes detectar una baja de tensión antes de la etapa estabilizadora, por ejem. en la entrada de un regulador 7805, de ésta manera habrá tiempo anticipado para registrar datos antes del shutdown.
Además puedes añadir filtros de capacidad cómo para asegurar una autonomía de varios cientos de milisegundos.
No utilices retardos entre segmentos de grabación de EEPROM, para ello existe un flag en un registro especifico que indica el finalizado de dicha tarea. Con eso optimizas los tiempos de ejecución de otras tareas antes del apagado.
 
Última edición:
Hola Roberto gracias por responder!!!,te cuento hoy logré dejar el circuito funcionando ya detecto la falta de alimentacion y grabo en memoria ,mi duda es la manera de grabar en la memoria pero con la interrupcion externa, de la manera que explique arriba que con la INT EXT activo un flag y con este flag ya dentro del while grabo en memoria , ya me esta funcionando, pero me parece que no es la manera correcta .De todos modos no entendí bien tu explicacion .
Cual es el registro especifico que indica el finalizado de la grabacion?
Como y donde lo tengo que aclarar?
Si coloco la grabacion de eeprom ,dentro de la funcion de la interrupcion y quito los delays tambien me marca warning cuando compilo.
Tenia entendido que cuando se realizan varias grabaciones seguidas había que dar un delay de 15ms entre cada una
Espero haberme explicado .
Saludos !!!
 
No te preocupes por el flag de escritura completa.
Eso es para lenguaje ensamblador y tu programa está en C.
En lenguajes de alto nivel, el proceso de escritura está controlado por las instrucciones nativas del compilador o realizado por la librería que uses.

Pero si quita esos retardos después de cada escritura, ya que no tienen sentido por lo que expliqué.
 
...
Código:
#int_ext
void corte()
       {
          write_int16_eeprom(100, Hora);
          delay_ms(15);
          write_int16_eeprom(110, HoraParcial);
          delay_ms(15);          
          write_eeprom(120, Minuto);
          delay_ms(15);
          write_eeprom(130, MinutoParcial);
          delay_ms(15);
y estos los errores del compilador :
interrupts disabled call to prevent re-entrancy {@delay_ms1}
interrupts disabled call to prevent re-entrancy { write_int16_eeprom}
[/code]

Re-entrancy en este contexto (sin sistema operativo de por medio, microcontroladores con código normalito o bare-metal como le dicen) se refiere a que una función es llamada a la vez desde código normal y desde una o más rutinas de interrupción.
Toda función que escriba variables globales (mejor dicho recursos globales, por ejemplo en este caso los registros eeprom) es no-reentrante.

Lo que está diciendo el error es que no se permiten llamadas a función desde la rutina de interrupción, pero eso veo que ya lo entendiste por lo que hiciste más abajo.

Como debería hacer la funcion para que cuando entre la interrupcion me grabe estos datos en la memoria lo mas rapido posible es decir antes que se quede sin alimentacion el pic
Tambien probé hacerlo asi :

Código:
#int_ext
void corte()
 {
    a=1;         
 }
Código:
while(1)
    { 
 
         if (a==1)
       {
          write_int16_eeprom(100, Hora);
          delay_ms(15);
          write_int16_eeprom(110, HoraParcial);
          delay_ms(15);          
          write_eeprom(120, Minuto);
          delay_ms(15);
          write_eeprom(130, MinutoParcial);
          delay_ms(15);
          a=0;          
       }

pero logicamente aparte de esto tengo mucho mas codigo ,en el cual estaria perdiendo demasiado tiempo dependiendo de en que punto estaba el programa cuando entró la interrupcion y hasta que vuelva a llegar a aquí, tal vez no me alcance el tiempo para grabar antes que se termine la alimentacion .

La respuesta más sencilla es chequear varias si a==1, es decir, en vez de:

Código:
while(1)
{
    if(a==1)
    {
        ;//salvar todo
    }
    funcion1();
    funcion2();
    funcion3();
    funcion4();
    funcion5();
    funcion6();
    funcion7();
...
}

hacer algo como:

Código:
void salvarTodo(void)
{
    if(a==1)
    {
        ;//salvar todo
    }
}

while(1)
{

    funcion1();
    salvarTodo();
    funcion2();
    salvarTodo();
    funcion3();
    salvarTodo();
    funcion4();
    salvarTodo();
    funcion5();
    salvarTodo();
    funcion6();
    salvarTodo();
    funcion7();
...
}

No es para nada bonito, pero puede funcionar.
Un enfoque más sofisticado sería modificar la dirección de retorno (el contador de programa PC guardado en la pila) en la rutina de interrupción corte() (si mal no recuerdo es lo que hace por ejemplo el freeRTOS para controlar la ejecución de tareas).
Pero ahí ya vas a tener que averiguar como se guarda el PC en la pila al producirse una interrupción.

Y un ultima pregunta, de que manera desactivo todos los perifericos cuando entre esta interrupcion ,me refiero si con una instruccion dentro de la interrupcion o como debería hacerlo ? ya que desactivando los perifericos estaría ahorrando energia y ganando tiempo para grabar.
Desde ya les agradezco cualquier ayudita .Saludos!!!!

Con más código... deshabilitando uno por uno.

Ups... recién me dí cuenta que ya habían contestado, pero ya escribí todo el choclo así que ahí queda.
 
Hola Ardogan muchas gracias por tu respuesta disculpa no conteste antes pero ando sin internet en casa,te agradezco mucho la explicacion, estoy teniendo poco tiempo para dedicarme al codigo pero ni bien tenga algo les comento, nuevamente muchas gracias
Saludos!!!
 
Hola quería contarles que al final decidí cambiar un poco el programa basandome en varios ciclos while con condiciones y asi lograr salir de cualquier parte del programa al momento de la interrupcion y entrar al while donde se activan las grabaciones ya lo tengo probado y funciona.Quedó algo asi :
Código:
#int_ext
void corte()
 {  
    x=0;
    grabar=1;         
 }

Resto del programa:

Código:
 while(x==0)
    {   
      if(grabar==1)
       {
          write_int16_eeprom(100, Hora);
          write_int16_eeprom(110, HoraParcial);         
          write_eeprom(120, Minuto);
          write_eeprom(130, MinutoParcial);
          grabar=0;
          lcd_putc("\f");           
          lcd_putc("    APAGANDO     ");           
          delay_ms(500);
       } 
          lcd_gotoxy(1,1);           
          printf(lcd_putc," MENU PRINCIPAL   ");     
   }
while (x==1)
{
codigo
}
while (x==2)
{
codigo
}
Muchas gracias por sus respuestas ,Si alguien quiere el codigo completo con gusto lo subiré.
Saludos!!!!
 
Última edición:
Atrás
Arriba