Saltos incondicionales en una interrupción

#1
Hola.
Tengo la necesidad de que cuando se produzca una interrupción, el programa continúe en otro punto (utilizo css)
He probado con goto pero el compilador no me lo permite.
¿Cómo lo haríais?

Os dejo el programa y ¡Muchísimas Gracias!
Código:
#include <18F2620.h>

#fuses NOMCLR
#fuses HS
#fuses PUT
#fuses NOWDT



#use delay(CLOCK=25M)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)

//Declaración de Variablea Globales
//unsigned int bandera;
unsigned long r;

//Declaración de Funciones
   void RUN_PALABRA (int p)

   {
   output_high(PIN_A5); // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA
   output_low(PIN_A0); // `PARALEL LOAD` BAJO NECESARIO PARA QUE EL DATO PASE DEL LATCH AL REGISTRO
   output_low(PIN_A1); // ´SHIF Y STORAGE CLOCK INPUT´ BAJO PREPARANDO EL FLANCO DE SUBIDA PARA LLEVAR EL DATO A LA AL REGISTRO
   

   output_c(p); // SE PONE EL DATO EN EL PUERTO B
   
   output_high(PIN_A1); // ´SHIF Y STORAGE CLOCK INPUT´ FLANCO DE SUBIDA PARA LLEVAR EL DATO AL REGISTRO
   output_high(PIN_A0); // `PARALEL LOAD` ALTO NECESARIO PARA QUE EL REGISTRO PUEDA AVANZAR, PONE EL EL PRIMER BIT A LA SALIDA
   output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
   output_low(PIN_A3);
     
      int f;
      for (f=0; f<8; f++)
      {
   
      
      output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1); // 165 `SHIF Y STORAGE CLOCK INPUT` BAJO
      output_high(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ ALTO PASA EL DATO AL REGISTRO Y LO DESPLAZA
      output_high(PIN_A1); // 165 `SHIF Y STORAGE CLOCK INPUT` ALTO DESPLAZA
      
      
      }
   
      output_high(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ ALTO PASA EL REGISTRO A LA SALIDA
      
      }

   void CLEAR (void)
    {
   output_high(PIN_A5); // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA 
   output_low(PIN_A0); // `PARALEL LOAD` BAJO NECESARIO PARA QUE EL DATO PASE DEL LATCH AL REGISTRO
   output_low(PIN_A1); // ´SHIF Y STORAGE CLOCK INPUT´ BAJO PREPARANDO EL FLANCO DE SUBIDA PARA LLEVAR EL DATO A LA AL REGISTRO
   

   output_c(0b00000000); // SE PONE EL DATO EN EL PUERTO B
   
   output_high(PIN_A1); // ´SHIF Y STORAGE CLOCK INPUT´ FLANCO DE SUBIDA PARA LLEVAR EL DATO AL REGISTRO
   output_high(PIN_A0); // `PARALEL LOAD` ALTO NECESARIO PARA QUE EL REGISTRO PUEDA AVANZAR, PONE EL EL PRIMER BIT A LA SALIDA
   output_low(PIN_A2); //    595 ´STORAGE CLOCK INPUT´ BAJO
  
   
    int i;
    int e;
    for (e=0; e<16; e++)
    {
      for ( i=0; i<8; i++)
      {
    
      
      output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1); // 165 `SHIF Y STORAGE CLOCK INPUT` BAJO
             output_a(0b00100011);
      output_high(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ ALTO PASA EL DATO AL REGISTRO Y LO DESPLAZA
      output_high(PIN_A1); // 165 `SHIF Y STORAGE CLOCK INPUT` ALTO DESPLAZA
            output_a(0b00100011); 
      
      }
   
      
      
     }
    output_high(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ ALTO PASA EL REGISTRO A LA SALIDA
    
  }


//Vectores de Interrupción

#INT_EXT
   void interrupt_service_rutine_ext0(void)
   {
      r=get_timer1();
      r=r/128;
      set_timer1(0);
      goto principio;
   }

//Programa Principal
void main (void)
   {
   
   delay_ms(1000);
   enable_interrupts(INT_EXT);
   ext_int_edge(l_to_h);
   enable_interrupts(global);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );
   
   set_tris_b(0b00000001); // PUERTO B SALIDA CON B1, B2 Y B3 COMO ENTRADA PARA INTERRUPCIONES
   set_tris_c(0b00000000); // PUERTO C SALIDA
   set_tris_a(0b11000000); // PUERTO A SALIDA
    
   CLEAR();
   delay_ms(2000);
   
//escenas
principio:
   while (true)
   {
RUN_PALABRA (0b11111011); //1
RUN_PALABRA (0b11111111); //2
RUN_PALABRA (0b11110111); //3
RUN_PALABRA (0b11111111); //4
RUN_PALABRA (0b01111111); //5
RUN_PALABRA (0b11111111); //6
RUN_PALABRA (0b11111111); //7
RUN_PALABRA (0b11110010); //8
RUN_PALABRA (0b00111111); //9
RUN_PALABRA (0b11111111); //10
RUN_PALABRA (0b11111111); //11
RUN_PALABRA (0b00111111); //12
RUN_PALABRA (0b11111001); //13
RUN_PALABRA (0b11111111); //14
RUN_PALABRA (0b11110001); //15
RUN_PALABRA (0b11111110); //16
output_low(PIN_A5); delay_us(r);
RUN_PALABRA (0b11111011); //1
RUN_PALABRA (0b11111111); //2
RUN_PALABRA (0b11110111); //3
RUN_PALABRA (0b11111111); //4
RUN_PALABRA (0b01111111); //5
RUN_PALABRA (0b11111111); //6
RUN_PALABRA (0b11111111); //7
RUN_PALABRA (0b11110011); //8
RUN_PALABRA (0b00111111); //9
RUN_PALABRA (0b11111111); //10
RUN_PALABRA (0b11111111); //11
RUN_PALABRA (0b00111111); //12
RUN_PALABRA (0b11111001); //13
RUN_PALABRA (0b11111111); //14
RUN_PALABRA (0b11110001); //15
RUN_PALABRA (0b11111111); //16
output_low(PIN_A5); delay_us(r);

   
   }
 }
 
Última edición por un moderador:

Dr. Zoidberg

Well-known-Papá Pitufo
#2
Hola tengo la necesidad de que cuando se produzca un interrpción, el programa continue en otro punto (utilizo css) he probado con goto pero el compilador no me lo permite.
¿como lo hariais?
Y para que querés hacer eso???? Es una verdera barbaridad hacer esas cosas cuando no hay control del punto de ejecución :( como en la invocación de una ISR.
Mejor repensá el algoritmo, por que lo que pensás hacer es cualquier cosa...
 
#3
lo que necesitaria es que se reinicie el "while" sin que termine cuando se active la interrupción. No se como hacer eso. ¿Alguna sugerencia?

ha, y muchas gracias doctor ;)
 
#4
En un PIC, al no ser multitarea no podrás hacer eso, cuando se cumpla la interrupción y se salga de ella, se retomará el control justo en el lugar cuando se produjo la interrupción.
Entonces el valor de r podrá ser usado en toda la rutina hasta que se complete todo el ciclo.

Tal vez lo puedas hacer usando RTOS o de plano quitar el GoTo y esperar hasta que se cumpla el ciclo.

Suerte.
 

Dr. Zoidberg

Well-known-Papá Pitufo
#5
En un PIC, al no ser multitarea no podrás hacer eso, cuando se cumpla la interrupción y se salga de ella, se retomará el control justo en el lugar cuando se produjo la interrupción.
Seeee.... pero "puedo" sobreescribir el stack en la ISR con la nueva dirección de retorno de manera que siempre vuelva a ese punto... pero eso es aumentar la cochinada a niveles épicos :oops: y correr serios riesgos de stack-overflow si la interrupción me pilla dentro de una función y yo no descarto las direcciones de retorno de ellas que estén presentes en el stack :eek:

La unica solución que yo veo sin analizar demasiado es poner un flag global en falso cada vez que se reinicie el lazo y en verdadero cada vez que pase por la ISR. Luego ya es fácil: Un rediseño de la función RUN_PALABRA y una parva de if para reinicir el while con un continue si el flag está en verdadero.

Sinceramente... yo pensaría la solución nuevamente sin hacer enrriedos con técnicas de assembler por que el C permite manejar mucho mas simplemente la ejecución del código.
 
#6
Tienes que utilizar una variable que haga de bandera.

Es decir: en el resto del programa -en los bucles, en las esperas- debes comprobar, de forma regular, si la bandera ha cambiado de valor. Si es así, debe terminar inmediatamente -en caso de ser una subrutina, como CLEAR- para volver al bucle principal. Y ahí volver a comprobar la bandera -debe enterarse que CLEAR o la otra subrutina ha vuelto enseguida debido a ese evento-. Si la bandera está puesta, hace un 'continue' para que reinicie el bucle while(). Y la primera instrucción del while() es bajar la bandera.

Viendo el código con más detalle... tanto CLEAR como RUN_PALABRA apenas ocupan unas decenas de ciclos, no tienen esperas largas, así que no necesitas comprobar que la bandera cambia dentro de ellas (a no ser que quieras una precisión extrema).

Entonces, el código quedaría algo así (no probado):
PHP:
#include <18F2620.h>

#fuses NOMCLR
#fuses HS
#fuses PUT
#fuses NOWDT

#use delay(CLOCK=25M)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)

// Declaración de variables globales
unsigned int bandera = 0;
unsigned long r;

unsigned int escenas1[16] = {
    0b11111011,     // 1
    0b11111111,     // 2
    0b11110111,     // 3
    0b11111111,     // 4
    0b01111111,     // 5
    0b11111111,     // 6
    0b11111111,     // 7
    0b11110010,     // 8
    0b00111111,     // 9
    0b11111111,     //10
    0b11111111,     //11
    0b00111111,     //12
    0b11111001,     //13
    0b11111111,     //14
    0b11110001,     //15
    0b11111110      //16
};

// por alguna extraña razón, las escenas son distintas en el número 8
unsigned int escenas2[16] = {
    0b11111011,     // 1
    0b11111111,     // 2
    0b11110111,     // 3
    0b11111111,     // 4
    0b01111111,     // 5
    0b11111111,     // 6
    0b11111111,     // 7
    0b11110011,     // 8
    0b00111111,     // 9
    0b11111111,     //10
    0b11111111,     //11
    0b00111111,     //12
    0b11111001,     //13
    0b11111111,     //14
    0b11110001,     //15
    0b11111110      //16
};


// Declaración de funciones
void RUN_PALABRA (int p) {

    output_high(PIN_A5);        // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA
    output_low(PIN_A0);         // 'PARALLEL LOAD' BAJO NECESARIO PARA QUE EL DATO PASE DEL LATCH AL REGISTRO
    output_low(PIN_A1);         // 'SHIF Y STORAGE CLOCK INPUT' BAJO PREPARANDO EL FLANCO DE SUBIDA PARA LLEVAR EL DATO A AL REGISTRO

    output_c(p);                // SE PONE EL DATO EN EL PUERTO B

    output_high(PIN_A1);        // 'SHIF Y STORAGE CLOCK INPUT' FLANCO DE SUBIDA PARA LLEVAR EL DATO AL REGISTRO
    output_high(PIN_A0);        // 'PARALLEL LOAD' ALTO NECESARIO PARA QUE EL REGISTRO PUEDA AVANZAR, PONE EL PRIMER BIT A LA SALIDA
    output_low(PIN_A2);         // 595 'STORAGE CLOCK INPUT' BAJO
    output_low(PIN_A3);

    int f;
    for (f = 0; f < 8; f++) {

        output_low(PIN_A2);        // 595 'STORAGE CLOCK INPUT' BAJO
        output_low(PIN_A3);        // 595 'SHIFT CLOCK INPUT' BAJO
        output_low(PIN_A1);        // 165 'SHIFT Y STORAGE CLOCK INPUT' BAJO

        output_high(PIN_A2);       // 595 'STORAGE CLOCK INPUT' ALTO PASA EL DATO AL REGISTRO Y LO DESPLAZA
        output_high(PIN_A1);       // 165 'SHIFT Y STORAGE CLOCK INPUT' ALTO DESPLAZA
    }

    output_high(PIN_A3);        // 595 'SHIFT CLOCK INPUT' ALTO PASA EL REGISTRO A LA SALIDA
}

void CLEAR (void) {

    output_high(PIN_A5);        // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA
    output_low(PIN_A0);         // 'PARALLEL LOAD' BAJO NECESARIO PARA QUE EL DATO PASE DEL LATCH AL REGISTRO
    output_low(PIN_A1);         // 'SHIF Y STORAGE CLOCK INPUT' BAJO PREPARANDO EL FLANCO DE SUBIDA PARA LLEVAR EL DATO A AL REGISTRO

    output_c(0b00000000);       // SE PONE EL DATO EN EL PUERTO B

    output_high(PIN_A1);        // 'SHIF Y STORAGE CLOCK INPUT' FLANCO DE SUBIDA PARA LLEVAR EL DATO AL REGISTRO
    output_high(PIN_A0);        // 'PARALEL LOAD' ALTO NECESARIO PARA QUE EL REGISTRO PUEDA AVANZAR, PONE EL PRIMER BIT A LA SALIDA
    output_low(PIN_A2);         // 595 'STORAGE CLOCK INPUT' BAJO

    int i, e;
    for (e = 0; e < 16; e++) {
        for (i = 0; i < 8; i++) {

            output_low(PIN_A2);         // 595 'STORAGE CLOCK INPUT' BAJO
            output_low(PIN_A3);         // 595 'SHIFT CLOCK INPUT' BAJO
            output_low(PIN_A1);         // 165 'SHIF Y STORAGE CLOCK INPUT' BAJO

            output_a(0b00100011);

            output_high(PIN_A2);        // 595 'STORAGE CLOCK INPUT' ALTO PASA EL DATO AL REGISTRO Y LO DESPLAZA
            output_high(PIN_A1);        // 165 'SHIF Y STORAGE CLOCK INPUT' ALTO DESPLAZA

            output_a(0b00100011);
        }
    }

    output_high(PIN_A3);        // 595 'SHIFT CLOCK INPUT' ALTO PASA EL REGISTRO A LA SALIDA
}


// Vectores de Interrupción

#INT_EXT
void interrupt_service_rutine_ext0(void) {
    r = get_timer1() / 128;
    set_timer1(0);

    bandera = 1;
}

// Programa Principal
void main (void) {
    int e;

    delay_ms(1000);

    enable_interrupts(INT_EXT);
    ext_int_edge(l_to_h);
    enable_interrupts(global);
    setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 );

    set_tris_b(0b00000001);        // PUERTO B SALIDA CON B1, B2 Y B3 COMO ENTRADA PARA INTERRUPCIONES
    set_tris_c(0b00000000);        // PUERTO C SALIDA
    set_tris_a(0b11000000);        // PUERTO A SALIDA

    CLEAR();

    delay_ms(2000);

    // escenas
    principio:

    while (true) {

        bandera = 0;

        for (e = 0; e < 16; e++) {

            RUN_PALABRA (escenas1[e]);

            if (bandera) e = 16;                // obligar a terminar
        }

        if (bandera) continue;                  // recomenzar el bucle

        output_low(PIN_A5); delay_us(r);

        for (e = 0; e < 16; e++) {

            RUN_PALABRA (escenas2[e]);

            if (bandera) e = 16;                // obligar a terminar
        }

        if (bandera) continue;                  // recomenzar el bucle

        output_low(PIN_A5); delay_us(r);
    }
}
 
Última edición:
#7
Buenas noches estimados colegas:

Estoy teniendo un problema "similar" en una interrupción externa por RB0. Resulta que estoy manejando unos displays multiplexados con un registro de desplazamiento 74LS164. No se si está prohibido, pero es posible usar una subfunción dentro de la interrupción? El programa no me copila y para complicar más la situación ocurren dos cosas en la práctica:

**Al encender el sistema, el micro entra directamente en la interrupción por RB0

**Una interrupción por timer0 tampoco funciona.

Parte del programa de la interrupción, el resto es el mismo solo que evaluando otras entradas.

Código:
#INT_EXT
void ext_interm( ){   
      disable_interrupts(INT_TIMER1);
      disable_interrupts(INT_RTCC);
      while(input(BTN4)==1){
void escribirDIAUX(int8 aux)
{
int i;
for(i=0;i<8;i++){
 if (bit_test(aux, i)==0)
  {
    output_low (DATAN);
    output_low (CLOCKAN);
   output_high(CLOCKAN);
   }
    if (bit_test(aux,i)==1)
    {
   output_high (DATAN);
   output_low (CLOCKAN);
   output_high(CLOCKAN);

   }
 }
}
      if (input(BTN3)==0){
         while(input(BTN3)==0){
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
Saludos :D
 
#8
Estoy teniendo un problema "similar" en una interrupción externa por RB0.
Resulta que estoy manejando unos displays multiplexados con un registro de desplazamiento 74LS164.
No sé si está prohibido, pero, ¿es posible usar una subfunción dentro de la interrupción?
El problema es que no puedes anidar una o más sub rutinas dentro de otra.
Tampoco se debe llamar a otra sub rutina cuando estás dentro del servicio de interrupción.
El programa no me copila y para complicar más la situación ocurren dos cosas en la práctica:

**Al encender el sistema, el micro entra directamente en la interrupción por RB0
Esto puede ser debido a que no has configurado por que flanco debe ocurrir la interrupción.
Usa ext_int_edge(); con las opciones L_TO_H o H_TO_L para definir el flanco.

**Una interrupción por timer0 tampoco funciona.
No se ve la configuración ni la rutina de servicio en la parte de código que pusiste.
Únicamente se ve que la deshabilitas durante el servicio de interrupción por RB0, pero no se ve que la vuelvas a habilitar.
 
#9
Adjunto el código completo, es un RTC con el 18F2520. Otra falla que me da es que cuando llega a las 12, no pasa a 1 :confused: . Fijate que esas directivas de inicio de la interrupción si estan.

Código:
#include <18F2520.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
//#BYTE TRISA=0x85
//#BYTE PORTA=0x05
//#BYTE TRISB=0x86
//#BYTE PORTB=0x06
//#BYTE TRISC=0x87
//#BYTE PORTC=0x07
//#BYTE TRISD=0x88
//#BYTE PORTD=0x08
//#BYTE TRISE=0x89
//#BYTE PORTE=0x09
//#use fast_io(d)
#BYTE OPTION_REG=0x81
#use standard_io(c)
#include <math.h>             
#include <ds1307877.c>
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)//modificacion1904133:20pm
byte const num[10]={252,96,218,242,102,182,190,224,254,246};
byte sec=0;
byte secuni=0;
byte secdec=0;
byte min=59;
byte minuni=0;
byte mindec=0;
byte hr=23;//64+8
byte hruni=0;
byte hrdec=0;
byte day=31;
byte dayanterior=31;
byte contaseg=0;
byte dayuni=1;
byte daydec=0;
byte mth=12;
byte year=13;
byte dow=1;
byte copia=0;
byte qdia=1;
byte previo=0;
byte prehr=0;
//int16 N=0;
int16 contarc0=0;
int i;
int8 aux;
#define DATAN  PIN_A3
#define CLOCKAN  PIN_A2
#define SEGUNDERO PIN_A0
#define HAB1 PIN_C2
#define HAB2 PIN_C5
#define HAB3 PIN_C6
#define HAB4 PIN_C7
#define BTN2 PIN_B1
#define BTN3 PIN_B2
#define BTN4 PIN_B3

#INT_EXT
void ext_interm( ){   
      disable_interrupts(INT_TIMER1);
      disable_interrupts(INT_RTCC);
      while(input(BTN4)==1){
void escribirDIAUX(int8 aux)
{
int i;
for(i=0;i<8;i++){
 if (bit_test(aux, i)==0)
  {
    output_low (DATAN);
    output_low (CLOCKAN);
   output_high(CLOCKAN);
   }
    if (bit_test(aux,i)==1)
    {
   output_high (DATAN);
   output_low (CLOCKAN);
   output_high(CLOCKAN);

   }
 }
}
      if (input(BTN3)==0){
         while(input(BTN3)==0){
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
}   
            if (hr==23){
               hr=0;
            }
            else{
               hr++;
            }
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
   
      }
      if (input(BTN2)==0){
         while(input(BTN2)==0){
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
       output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
         }
         if (min==59){
               min=0;
            }
            else{
               min++;
            }
     
      }
     

      dayuni=0;
      daydec=0;
      copia=day;
      daydec= copia/10;
      copia= copia%10;
      dayuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
            if (hr==0){
            prehr=12;
                        }
            else if (hr==12){
            prehr=hr;
          
            }
            else if (hr>12){
            prehr=hr-12;
            
            }
            else{
            prehr=hr;
            }
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
    output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
}
      delay_ms(100);
      ds1307_set_date_time(day,mth,year,qdia,hr,min,sec);
      delay_ms(100);

      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
      dayuni=0;
      daydec=0;
      copia=day;
      daydec= copia/10;
      copia= copia%10;
      dayuni=copia;
      dayanterior=day;
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_RTCC);
}
#INT_TIMER1
temp1_isr(void){
      disable_interrupts(INT_TIMER1);
      if (contaseg==23){
      contaseg=0;
      ds1307_get_date(day,mth,year,dow);
      ds1307_get_time(hr,min,sec);

      secuni=0;
      secdec=0;
      copia=sec;
      secdec= copia/10;
      copia= copia%10;
      secuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
      }
      else{
      contaseg++;
      }

      set_timer1(3025);
      enable_interrupts(INT_TIMER1);

}
#INT_RTCC
RTCC_isr(){
   set_timer0(198);
   if (contarc0>=333){
      output_toggle(SEGUNDERO);
      contarc0=0;
   }
   else{
   contarc0++;
   }
}

void bin_bcd(){
      dayuni=0;
      daydec=0;
      copia=day;
      daydec= copia/10;
      copia= copia%10;
      dayuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
            if (hr==0){
            prehr=12;
       
            }
            else if (hr==12){
            prehr=hr;
          
            }
            else if (hr>12){
            prehr=hr-12;
                      }
            else{
            prehr=hr;
                      }
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
}   

void escribirDI(int8 aux)
{
int i;
for(i=0;i<8;i++){
 if (bit_test(aux, i)==0)
  {
    output_low (DATAN);
    output_low (CLOCKAN);
    output_high(CLOCKAN);
    }
    if (bit_test(aux,i)==1)
    {
    output_high (DATAN);
    output_low (CLOCKAN);
    output_high(CLOCKAN);
    }
  }
}


void mostrar(){
   bin_bcd();
  output_low(HAB4);
escribirDI(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDI(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDI(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDI(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3); 
}   

    
void main() {
     // set_tris_D(0x00);
     // PORTD=0b00000000;
      delay_ms(1000);
      disable_interrupts(global);
      //set_tris_A(0b00100000);
      //set_tris_E(0x00);
      //set_tris_C(0b10000000);
      // set_tris_B(0XFF);
     // output_low(PIN_C0);
     // output_low(PIN_C1);
     // output_low(PIN_C2);
     ds1307_init();
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
      set_timer1(3036);
      setup_timer_0(RTCC_DIV_8);
      set_timer0(198);
      disable_interrupts(INT_RTCC);
      disable_interrupts(INT_TIMER1);
      enable_interrupts(int_ext);
      ext_int_edge(H_to_L);
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_TIMER1);
      enable_interrupts(INT_RTCC);

         ds1307_get_date(day,mth,year,dow);
         ds1307_get_time(hr,min,sec);
      dayanterior=day;
      mostrar();

while (1){
      mostrar();
             }
}   
}
 
#11
Es feo usar goto en C, más feo hacerlo en una interrupción. :LOL:

Otras alternativas a las que te mencionaron es hacer una máquina de estados, es un método muy ordenado, pero dependiendo de la aplicación, puede ser lento.
 
#12
Anexo simulación en proteus (no conseguí cómo conectar bien el display, a la salida Q0 del 74LS164 le corresponde el segmento A, Q1 el B y así sucesivamente;no empleo mucho las simulaciones).

También subo foto del equipo armado :D

Saludos
 

Adjuntos

#13
El problema está en la subrutina anidada dentro del servicio de interrupción por RB0.
Tienes muchas llamadas a escribirDIAUX(int8 aux) y la verdad yo si optaría por incluir esa rutina al final del servicio de interrupción, pero con etiqueta y llamarla con un goto, previamente cargando el valor para la variable aux
Si es feo usar goto como menciona cosmefulanito04, pero sería más feo repetir el código para sustituir la rutina.

No sé cómo sería eso de hacer una máquina de estado, pero así con goto se puede hacer fácil, pues son muchas las veces que se llama a esa subrutina.

PD:
Olvidaste incluir la librería ds1307877.c
 
#14
El problema está en la subrutina anidada dentro del servicio de interrupción por RB0.
Tienes muchas llamadas a escribirDIAUX(int8 aux) y la verdad yo si optaría por incluir esa rutina al final del servicio de interrupción, pero con etiqueta y llamarla con un goto, previamente cargando el valor para la variable aux
Si es feo usar goto como menciona cosmefulanito04, pero sería más feo repetir el código para sustituir la rutina.
Hay múltiples llamadas porque cada vez que voy a sacar un número, la subrutina me escribe el registro de desplazamiento. Trate de asignarle el valor de los minutos y horas a la variable aux y luego colocar el código para sustituir la rutina (como dices, quedo un mostro) pero no funcionó. Cómo se hacen las etiquetas usando C?

PD: Olvidaste incluir la librería ds1307877.c
Listo.
 

Adjuntos

#15
No se en los pic y dependerá de cada caso, se puede meter en la pila la dirección de retorno y cuando haga falta usar la instrucción de retorno de subrutina para saltar allí
 
#17
Hola Anthony123 ahora es mas facil ayudarte ya que subiste el la simulación, el código mas la librería que etas usando... viendo el esquema te comento que seria mas fácil hacer la mutiplexacion de los displays sin unas el registro de desplazamientos ya que viendo la disposición de los pines quizá se pueda llegar a un mejor arreglo... "pero eso sera en otra ocasión".

Compilando el programa que subiste salen "un kilo de errores"...

codigo complilado

Código:
#include <18F2520.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
//#BYTE TRISA=0x85
//#BYTE PORTA=0x05
//#BYTE TRISB=0x86
//#BYTE PORTB=0x06
//#BYTE TRISC=0x87
//#BYTE PORTC=0x07
//#BYTE TRISD=0x88
//#BYTE PORTD=0x08
//#BYTE TRISE=0x89
//#BYTE PORTE=0x09
//#use fast_io(d)
#BYTE OPTION_REG=0x81
#use standard_io(c)
#include <math.h>             
#include <ds1307877.c>
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)//modificacion1904133:20pm
byte const num[10]={252,96,218,242,102,182,190,224,254,246};
byte sec=0;
byte secuni=0;
byte secdec=0;
byte min=59;
byte minuni=0;
byte mindec=0;
byte hr=23;//64+8
byte hruni=0;
byte hrdec=0;
byte day=31;
byte dayanterior=31;
byte contaseg=0;
byte dayuni=1;
byte daydec=0;
byte mth=12;
byte year=13;
byte dow=1;
byte copia=0;
byte qdia=1;
byte previo=0;
byte prehr=0;
//int16 N=0;
int16 contarc0=0;
int i;
int8 aux;
#define DATAN  PIN_A3
#define CLOCKAN  PIN_A2
#define SEGUNDERO PIN_A0
#define HAB1 PIN_C2
#define HAB2 PIN_C5
#define HAB3 PIN_C6
#define HAB4 PIN_C7
#define BTN2 PIN_B1
#define BTN3 PIN_B2
#define BTN4 PIN_B3

#INT_EXT
void ext_interm( ){   
      disable_interrupts(INT_TIMER1);
      disable_interrupts(INT_RTCC);
      while(input(BTN4)==1){
void escribirDIAUX(int8 aux)
{
int i;
for(i=0;i<8;i++){
 if (bit_test(aux, i)==0)
  {
    output_low (DATAN);
    output_low (CLOCKAN);
   output_high(CLOCKAN);
   }
    if (bit_test(aux,i)==1)
    {
   output_high (DATAN);
   output_low (CLOCKAN);
   output_high(CLOCKAN);

   }
 }
}
      if (input(BTN3)==0){
         while(input(BTN3)==0){
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
}   
            if (hr==23){
               hr=0;
            }
            else{
               hr++;
            }
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
   
      }
      if (input(BTN2)==0){
         while(input(BTN2)==0){
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
            if (hr==0){
            prehr=12;
            }
            else if (hr==12){
            prehr=hr;
            }
            else if (hr>12){
            prehr=hr-12;
            }
            else{
            prehr=hr;
            }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
       output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
         }
         if (min==59){
               min=0;
            }
            else{
               min++;
            }
     
      }
     

      dayuni=0;
      daydec=0;
      copia=day;
      daydec= copia/10;
      copia= copia%10;
      dayuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
            if (hr==0){
            prehr=12;
                        }
            else if (hr==12){
            prehr=hr;
          
            }
            else if (hr>12){
            prehr=hr-12;
            
            }
            else{
            prehr=hr;
            }
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
    output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDIAUX(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3);
}
      delay_ms(100);
      ds1307_set_date_time(day,mth,year,qdia,hr,min,sec);
      delay_ms(100);

      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
      dayuni=0;
      daydec=0;
      copia=day;
      daydec= copia/10;
      copia= copia%10;
      dayuni=copia;
      dayanterior=day;
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_RTCC);
}
#INT_TIMER1
temp1_isr(void){
      disable_interrupts(INT_TIMER1);
      if (contaseg==23){
      contaseg=0;
      ds1307_get_date(day,mth,year,dow);
      ds1307_get_time(hr,min,sec);

      secuni=0;
      secdec=0;
      copia=sec;
      secdec= copia/10;
      copia= copia%10;
      secuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
      }
      else{
      contaseg++;
      }

      set_timer1(3025);
      enable_interrupts(INT_TIMER1);

}
#INT_RTCC
RTCC_isr(){
   set_timer0(198);
   if (contarc0>=333){
      output_toggle(SEGUNDERO);
      contarc0=0;
   }
   else{
   contarc0++;
   }
}

void bin_bcd(){
      dayuni=0;
      daydec=0;
      copia=day;
      daydec= copia/10;
      copia= copia%10;
      dayuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
            if (hr==0){
            prehr=12;
       
            }
            else if (hr==12){
            prehr=hr;
          
            }
            else if (hr>12){
            prehr=hr-12;
                      }
            else{
            prehr=hr;
                      }
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
}   

void escribirDI(int8 aux)
{
int i;
for(i=0;i<8;i++){
 if (bit_test(aux, i)==0)
  {
    output_low (DATAN);
    output_low (CLOCKAN);
    output_high(CLOCKAN);
    }
    if (bit_test(aux,i)==1)
    {
    output_high (DATAN);
    output_low (CLOCKAN);
    output_high(CLOCKAN);
    }
  }
}


void mostrar(){
   bin_bcd();
  output_low(HAB4);
escribirDI(num[minuni]);
delay_us(10);
output_high(HAB1);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDI(num[mindec]);
delay_us(10);
output_high(HAB3);
delay_ms(4);
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDI(num[hruni]);
delay_us(10);
output_high(HAB2);
delay_ms(4);
if (hrdec==1)
{
output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);
escribirDI(num[hrdec]);
delay_us(10);
output_high(HAB4);
delay_ms(4);
}
else {output_low(HAB1);
output_low(HAB2);
output_low(HAB3);
output_low(HAB4);}
delay_ms(3); 
}   

    
void main() {
     // set_tris_D(0x00);
     // PORTD=0b00000000;
      delay_ms(1000);
      disable_interrupts(global);
      //set_tris_A(0b00100000);
      //set_tris_E(0x00);
      //set_tris_C(0b10000000);
      // set_tris_B(0XFF);
     // output_low(PIN_C0);
     // output_low(PIN_C1);
     // output_low(PIN_C2);
     ds1307_init();
      setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
      set_timer1(3036);
      setup_timer_0(RTCC_DIV_8);
      set_timer0(198);
      disable_interrupts(INT_RTCC);
      disable_interrupts(INT_TIMER1);
      enable_interrupts(int_ext);
      ext_int_edge(H_to_L);
      enable_interrupts(GLOBAL);
      enable_interrupts(INT_TIMER1);
      enable_interrupts(INT_RTCC);

         ds1307_get_date(day,mth,year,dow);
         ds1307_get_time(hr,min,sec);
      dayanterior=day;
      mostrar();

while (1){
      mostrar();
             }
}   
}
79 errores detectados por el compilador.
Dibujo.PNG

ahora bien hay algunos erroes que saltan a la visa como este por ejemplo.

#INT_EXT
void ext_interm( ){
disable_interrupts(INT_TIMER1);
disable_interrupts(INT_RTCC);
while(input(BTN4)==1){ <------ la llave esta abierta, deberia estar cerrada }
void escribirDIAUX(int8 aux)
{
int i;
.
.
.


bien ahora le daré una revisada al código y a ver que sale...
 
#18
El uso del registro de desplazamiento es por la libertad que ofrecen de "dibujar" los numeros como quiera, ademas de ahorrar pines (estoy usando el 18f2520 para el debug pero usare uno de mas baja gama). Con respecto al while de BTN4, es un cerrojo para mantener el programa en la rutina de interrupcion (en donde se programa el ds1307) hasta que pise tal boton.

Saludos y gracias por la ayuda.
 
#19
Si es feo usar goto como menciona cosmefulanito04, pero sería más feo repetir el código para sustituir la rutina.
Yo me refería al 1er post, después me dí cuenta que lo revivieron. :oops:

De todas formas, del código que publicó anthony123, más allá de su pregunta, no me gusta que la rutina de interrupción sea tan larga.

Ese código se resuelve en main (o en otra rutina) usando flags (banderas) o con máquinas de estado. Con flag ya se mencionó arriba, con máquinas de estados, es una forma de flags, pero con más valores posibles que los típicos booleanos de un flag, eso te permite luego con un switch saber que evento se produjo y dirigir el flujo del programa como si fuera una máquina de estados típicas de los sistemas lógicos digitales.

La ventaja de una máquina de estado, es que una vez que la dibujas, resulta muy sencillo pasarla a código y a su vez te queda algo super ordenado y muy sencillo de modificar a futuro, simplemente se agregan más estados en la máquina.

Ejemplo muy básico:

 
Última edición:
#20
Hola anthony123, te comento que viendo el programa que subiste y corrigiendo lo que parecia estar mal "solamente cambie la llaves {}" encontre que ambas interruciones temporizadas se disparan cada medio segundo pero para el caso del timer1 la variable contaseg ocasiona que la actualizacion de la fecha y hora sea cada 12 segundos.
Para el timer0 la variable contarc0 ocasiona que "el segundero cambie" cada 174 segundos.
Por otro lado la tabla num[10] es para displays catodo comun.
Este el codigo resultante.
Código:
#include <18F2520.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
//#BYTE TRISA=0x85
//#BYTE PORTA=0x05
//#BYTE TRISB=0x86
//#BYTE PORTB=0x06
//#BYTE TRISC=0x87
//#BYTE PORTC=0x07
//#BYTE TRISD=0x88
//#BYTE PORTD=0x08
//#BYTE TRISE=0x89
//#BYTE PORTE=0x09
//#use fast_io(d)
#BYTE OPTION_REG=0x81
#use standard_io(c)
#include <math.h>             
#include <ds1307877.c>
#use i2c(Master,Slow,sda=PIN_C4,scl=PIN_C3)//modificacion1904133:20pm
byte const num[10]={252,96,218,242,102,182,190,224,254,246};
byte sec=0;
byte secuni=0;
byte secdec=0;
byte min=59;
byte minuni=0;
byte mindec=0;
byte hr=23;//64+8
byte hruni=0;
byte hrdec=0;
byte day=31;
byte dayanterior=31;
byte contaseg=0;
byte dayuni=1;
byte daydec=0;
byte mth=12;
byte year=13;
byte dow=1;
byte copia=0;
byte qdia=1;
byte previo=0;
byte prehr=0;
//int16 N=0;
int16 contarc0=0;
int i;
int8 aux;
#define DATAN  PIN_A3
#define CLOCKAN  PIN_A2
#define SEGUNDERO PIN_A0
#define HAB1 PIN_C2
#define HAB2 PIN_C5
#define HAB3 PIN_C6
#define HAB4 PIN_C7
#define BTN2 PIN_B1
#define BTN3 PIN_B2
#define BTN4 PIN_B3

#INT_EXT
void ext_interm( )
{
      disable_interrupts(INT_TIMER1);
      disable_interrupts(INT_RTCC);
      while(input(BTN4)==1);
}
void escribirDIAUX(int8 aux)
{
   int i;
   for(i=0;i<8;i++)
   {
      if(bit_test(aux, i)==0)
      {
         output_low (DATAN);
         output_low (CLOCKAN);
         output_high(CLOCKAN);
      }
      if(bit_test(aux,i)==1)
      {
         output_high (DATAN);
         output_low (CLOCKAN);
         output_high(CLOCKAN);
      }
   }
   if (input(BTN3)==0)
   {
      while(input(BTN3)==0)
      {
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
         if(hr==0)
         {
            prehr=12;
         }
         else if(hr==12)
         {
            prehr=hr;
         }
         else if (hr>12)
         {
            prehr=hr-12;
         }
         else
         {
            prehr=hr;
         }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
         output_low(HAB1);
         output_low(HAB2);
         output_low(HAB3);
         output_low(HAB4);
         escribirDIAUX(num[minuni]);
         delay_us(10);
         output_high(HAB1);
         delay_ms(4);
         output_low(HAB1);
         output_low(HAB2);
         output_low(HAB3);
         output_low(HAB4);
         escribirDIAUX(num[mindec]);
         delay_us(10);
         output_high(HAB3);
         delay_ms(4);
         output_low(HAB1);
         output_low(HAB2);
         output_low(HAB3);
         output_low(HAB4);
         escribirDIAUX(num[hruni]);
         delay_us(10);
         output_high(HAB2);
         delay_ms(4);
         if(hrdec==1)
         {
            output_low(HAB1);
            output_low(HAB2);
            output_low(HAB3);
            output_low(HAB4);
            escribirDIAUX(num[hrdec]);
            delay_us(10);
            output_high(HAB4);
            delay_ms(4);
         }
         else
         {
            output_low(HAB1);
            output_low(HAB2);
            output_low(HAB3);
            output_low(HAB4);
         }
         delay_ms(3);
      }   
      if(hr==23)
      {
         hr=0;
      }
      else
      {
         hr++;
      }
      if(hr==0)
      {
         prehr=12;
      }
      else if(hr==12)
      {
         prehr=hr;
      }
      else if(hr>12)
      {
         prehr=hr-12;
      }
      else
      {
         prehr=hr;
      }
   }
   if(input(BTN2)==0)
   {
      while(input(BTN2)==0)
      {
         dayuni=0;
         daydec=0;
         copia=day;
         daydec= copia/10;
         copia= copia%10;
         dayuni=copia;
         minuni=0;
         mindec=0;
         copia=min;
         mindec= copia/10;
         copia= copia%10;
         minuni=copia;
         hruni=0;
         hrdec=0;
         if (hr==0)
         {
            prehr=12;
         }
         else if(hr==12)
         {
            prehr=hr;
         }
         else if(hr>12)
         {
            prehr=hr-12;
         }
         else
         {
            prehr=hr;
         }
         copia=prehr;
         hrdec= copia/10;
         copia= copia%10;
         hruni=copia;
         output_low(HAB1);
         output_low(HAB2);
         output_low(HAB3);
         output_low(HAB4);
         escribirDIAUX(num[minuni]);
         delay_us(10);
         output_high(HAB1);
         delay_ms(4);
         output_low(HAB1);
         output_low(HAB2);
         output_low(HAB3);
         output_low(HAB4);
         escribirDIAUX(num[mindec]);
         delay_us(10);
         output_high(HAB3);
         delay_ms(4);
         output_low(HAB1);
         output_low(HAB2);
         output_low(HAB3);
         output_low(HAB4);
         escribirDIAUX(num[hruni]);
         delay_us(10);
         output_high(HAB2);
         delay_ms(4);
         if(hrdec==1)
         {
            output_low(HAB1);
            output_low(HAB2);
            output_low(HAB3);
            output_low(HAB4);
            escribirDIAUX(num[hrdec]);
            delay_us(10);
            output_high(HAB4);
            delay_ms(4);
         }
         else
         {
            output_low(HAB1);
            output_low(HAB2);
            output_low(HAB3);
            output_low(HAB4);
         }
         delay_ms(3);
      }
      if(min==59)
      {
         min=0;
      }
      else
      {
         min++;
      }
   }
   dayuni=0;
   daydec=0;
   copia=day;
   daydec= copia/10;
   copia= copia%10;
   dayuni=copia;
   minuni=0;
   mindec=0;
   copia=min;
   mindec= copia/10;
   copia= copia%10;
   minuni=copia;
   hruni=0;
   hrdec=0;
   if(hr==0)
   {
      prehr=12;
   }
   else if(hr==12)
   {
      prehr=hr; 
   }
   else if(hr>12)
   {
      prehr=hr-12;    
   }
   else
   {
      prehr=hr;
   }
   copia=prehr;
   hrdec= copia/10;
   copia= copia%10;
   hruni=copia;
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribirDIAUX(num[minuni]);
   delay_us(10);
   output_high(HAB1);
   delay_ms(4);
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribirDIAUX(num[mindec]);
   delay_us(10);
   output_high(HAB3);
   delay_ms(4);
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribirDIAUX(num[hruni]);
   delay_us(10);
   output_high(HAB2);
   delay_ms(4);
   if (hrdec==1)
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      escribirDIAUX(num[hrdec]);
      delay_us(10);
      output_high(HAB4);
      delay_ms(4);
   }
   else
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
   }
   delay_ms(3);
   delay_ms(100);
   ds1307_set_date_time(day,mth,year,qdia,hr,min,sec);
   delay_ms(100);

   minuni=0;
   mindec=0;
   copia=min;
   mindec= copia/10;
   copia= copia%10;
   minuni=copia;
   hruni=0;
   hrdec=0;
   copia=prehr;
   hrdec= copia/10;
   copia= copia%10;
   hruni=copia;
   dayuni=0;
   daydec=0;
   copia=day;
   daydec= copia/10;
   copia= copia%10;
   dayuni=copia;
   dayanterior=day;
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_RTCC);
}
#INT_TIMER1
void temp1_isr()        //se dispara cada 500ms
{
   disable_interrupts(INT_TIMER1);
   if(contaseg==23)
   {
      contaseg=0;
      ds1307_get_date(day,mth,year,dow);
      ds1307_get_time(hr,min,sec);

      secuni=0;
      secdec=0;
      copia=sec;
      secdec= copia/10;
      copia= copia%10;
      secuni=copia;
      minuni=0;
      mindec=0;
      copia=min;
      mindec= copia/10;
      copia= copia%10;
      minuni=copia;
      hruni=0;
      hrdec=0;
      copia=prehr;
      hrdec= copia/10;
      copia= copia%10;
      hruni=copia;
   }
   else
   {
      contaseg++;
   }

   set_timer1(3025);
   enable_interrupts(INT_TIMER1);
}
#INT_RTCC
void RTCC_isr()            //se dispara dada 522ms
{
   set_timer0(198);
   if (contarc0>=333)
   {
      output_toggle(SEGUNDERO);
      contarc0=0;
   }
   else
   {
      contarc0++;
   }
}
void bin_bcd()
{
   dayuni=0;
   daydec=0;
   copia=day;
   daydec= copia/10;
   copia= copia%10;
   dayuni=copia;
   minuni=0;
   mindec=0;
   copia=min;
   mindec= copia/10;
   copia= copia%10;
   minuni=copia;
   hruni=0;
   hrdec=0;
   if(hr==0)
   {
      prehr=12;    
   }
   else if(hr==12)
   {
      prehr=hr;
   }
   else if(hr>12)
   {
      prehr=hr-12;
   }
   else
   {
      prehr=hr;
   }
   copia=prehr;
   hrdec= copia/10;
   copia= copia%10;
   hruni=copia;
}   
void escribirDI(int8 aux)
{
   int i;
   for(i=0;i<8;i++)
   {
      if(bit_test(aux, i)==0)
      {
         output_low (DATAN);
         output_low (CLOCKAN);
         output_high(CLOCKAN);
      }
      if(bit_test(aux,i)==1)
      {
         output_high (DATAN);
         output_low (CLOCKAN);
         output_high(CLOCKAN);
      }
   }
}

void mostrar()
{
   bin_bcd();
   output_low(HAB4);
   escribirDI(num[minuni]);
   delay_us(10);
   output_high(HAB1);
   delay_ms(4);
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribirDI(num[mindec]);
   delay_us(10);
   output_high(HAB3);
   delay_ms(4);
   output_low(HAB1);
   output_low(HAB2);
   output_low(HAB3);
   output_low(HAB4);
   escribirDI(num[hruni]);
   delay_us(10);
   output_high(HAB2);
   delay_ms(4);
   if(hrdec==1)
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
      escribirDI(num[hrdec]);
      delay_us(10);
      output_high(HAB4);
      delay_ms(4);
   }
   else
   {
      output_low(HAB1);
      output_low(HAB2);
      output_low(HAB3);
      output_low(HAB4);
   }
   delay_ms(3); 
} 
void main()
{     
     // set_tris_D(0x00);
     // PORTD=0b00000000;
     delay_ms(1000);
     disable_interrupts(global);
     //set_tris_A(0b00100000);
     //set_tris_E(0x00);
     //set_tris_C(0b10000000);
     // set_tris_B(0XFF);
     // output_low(PIN_C0);
     // output_low(PIN_C1);
     // output_low(PIN_C2);
     ds1307_init();
     setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
     set_timer1(3036);
     setup_timer_0(RTCC_DIV_8);
     set_timer0(198);
     disable_interrupts(INT_RTCC);
     disable_interrupts(INT_TIMER1);
     enable_interrupts(int_ext);
     ext_int_edge(H_to_L);
     enable_interrupts(GLOBAL);
     enable_interrupts(INT_TIMER1);
     enable_interrupts(INT_RTCC);

     ds1307_get_date(day,mth,year,dow);
     ds1307_get_time(hr,min,sec);
     dayanterior=day;
     mostrar();
     while (true)
     {
         mostrar();
     }
}
Seria mejor que le des otro enfoque a tu programa por ejemplo: que una interrupcion temporizada se ocupe de la visualizacion de los displays, otra interrupcion se ocupe de actualizar la fecha y hora mediante la salida SOUT del DS1307...
 

Adjuntos

Última edición:

Temas similares

Arriba