Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

25/07/2014 #1


Saltos incondicionales en una interrupción
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);

   
   }
 }
25/07/2014 #2

Avatar de Dr. Zoidberg

Guille101 dijo: Ver Mensaje
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...
25/07/2014 #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
25/07/2014 #4
Moderador

Avatar de D@rkbytes

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.
25/07/2014 #5

Avatar de Dr. Zoidberg

D@rkbytes dijo: Ver Mensaje
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 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

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.
26/07/2014 #6

Avatar de JoaquinFerrero

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):
Código 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 (
08f++) {

        
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 ie;
    for (
016e++) {
        for (
08i++) {

            
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) {
    
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 (
016e++) {

            
RUN_PALABRA (escenas1[e]);

            if (
bandera16;                // obligar a terminar
        
}

        if (
bandera) continue;                  // recomenzar el bucle

        
output_low(PIN_A5); delay_us(r);

        for (
016e++) {

            
RUN_PALABRA (escenas2[e]);

            if (
bandera16;                // obligar a terminar
        
}

        if (
bandera) continue;                  // recomenzar el bucle

        
output_low(PIN_A5); delay_us(r);
    }

03/11/2014 #7

Avatar de anthony123

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
04/11/2014 #8
Moderador

Avatar de D@rkbytes

anthony123 dijo: Ver Mensaje
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.
anthony123 dijo: Ver Mensaje
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.

anthony123 dijo: Ver Mensaje
**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.
04/11/2014 #9

Avatar de anthony123

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 . 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();
             }
}   
}
04/11/2014 #10
Moderador

Avatar de D@rkbytes

anthony123 dijo: Ver Mensaje
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
Adjunta también el diagrama y/o la simulación, por favor.
04/11/2014 #11

Avatar de cosmefulanito04

Es feo usar goto en C, más feo hacerlo en una interrupción.

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.
05/11/2014 #12

Avatar de anthony123

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

Saludos
Imágenes Adjuntas
Tipo de Archivo: jpg IMG_0592.jpg (34,0 KB (Kilobytes), 9 visitas)
Archivos Adjuntos
Tipo de Archivo: rar RTC.rar (28,0 KB (Kilobytes), 5 visitas)
06/11/2014 #13
Moderador

Avatar de D@rkbytes

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
06/11/2014 #14

Avatar de anthony123

D@rkbytes dijo: Ver Mensaje
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?

D@rkbytes dijo: Ver Mensaje
PD: Olvidaste incluir la librería ds1307877.c
Listo.
Archivos Adjuntos
Tipo de Archivo: rar ds1307877.rar (1,3 KB (Kilobytes), 2 visitas)
06/11/2014 #15

Avatar de Scooter

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í
06/11/2014 #16
Moderador

Avatar de D@rkbytes

anthony123 dijo: Ver Mensaje
¿Cómo se hacen las etiquetas usando C?
Igual que en otros lenguajes.

goto label;

label:
// Código
06/11/2014 #17

Avatar de Saint_

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.


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...
Imágenes Adjuntas
Tipo de Archivo: png Dibujo.PNG (82,3 KB (Kilobytes), 57 visitas)
06/11/2014 #18

Avatar de anthony123

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.
07/11/2014 #19

Avatar de cosmefulanito04

D@rkbytes dijo: Ver Mensaje
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.

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:

09/11/2014 #20

Avatar de Saint_

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...
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.