Uso de las interrupciones en PIC C de CCS

Hola a todos.
No tengo mucha practica con programación (CSS) y me gustaría que me ayudarais a enfocar un problema.
Tengo un programa hecho y quisiera que empezara a funcionar cuando se active una interrupción externa. Si tengo el programa en el Main ¿cómo lo hariais? he pensado en hacer una comprobación en el main de una variable que cambiaría durante la interrupción, pero css no me permite hacerlo porque las variables de la interrupción no las veo en el Main y viceversa. también he pensado hacer una llamada a una función con el programa desde la interrupción, pero tampoco me reconoce dicha función.

Muchas gracias de antebrazo.
Aquí os dejo el programa por si os apetece hacer alguna modificación.
Código:
#include <18F2620.h>
#fuses NOMCLR
#fuses HS
#fuses PUT


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


void RUN_PALABRA (int p)

{
   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_B4);
   //output_high(PIN_A5);     // OUTPUT ENABLE ALTO,  SALIDA EN ALTA IMPEDANCIA
        
      int i; 
      for (i=0; i<8; i++)
      {
       //delay_ms(1);
      
      output_low(PIN_A2);  // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3);  // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1);  // 597 `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); // 597 `SHIF Y STORAGE CLOCK INPUT` ALTO     DESPLAZA

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

#INT_EXT
void interrupt_service_rutine_ext0(void)
{
output_toggle(PIN_B3); //

}


void main (void)
{

delay_ms(1000);
enable_interrupts(INT_EXT);
ext_int_edge(l_to_h);
enable_interrupts(global);


set_tris_b(0b00000000);  // 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


  while (true)
  {
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     RUN_PALABRA (0b01010101);
     
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
     RUN_PALABRA (0b00000000);
  
   // output_low(PIN_A5);  // OE VISUALIZAMOS QUE LA SALIDA DE LOS 595
  
  // delay_ms(1000);
  }           
  
   
}
 
Última edición por un moderador:
Hola.
Se puede declarar variables globales... pueden estar en cualquier parte fuera de Main.

Saludos
 
Amigo ahí modifiqué una parte de tu código, adjunto te lo dejo, me cuentas como te va, no tengo el compilador, de manera que asumo que se encuentra bien, lo único que modifiqué fue el estado de una bandera en la cual consultas si la interrupción se ha generado.

Código:
#include <18F2620.h>
#fuses NOMCLR
#fuses HS
#fuses PUT


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

//Declaración de Variablea Globales
unsigned char bandera=0;

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


//Vectores de Interrupción
#INT_EXT
void interrupt_service_rutine_ext0(void)
{
    output_toggle(PIN_B3); //
    bandera = 1;

}


//Programa Principal
void main (void)
{

    delay_ms(1000);
    enable_interrupts(INT_EXT);
    ext_int_edge(l_to_h);
    enable_interrupts(global);


    set_tris_b(0b00000000); // 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


    while (true)
    {

    //Consultas el estado de la bandera
    if(bandera!=0){
        bandera=0
        //Ingresas tu codigo
    }


    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);
    RUN_PALABRA (0b01010101);

    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);
    RUN_PALABRA (0b00000000);

    // output_low(PIN_A5); // OE VISUALIZAMOS QUE LA SALIDA DE LOS 595

    // delay_ms(1000);
    } 

}

void RUN_PALABRA (int p)

{
    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_B4);
    //output_high(PIN_A5); // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA

    int i; 
    for (i=0; i<8; i++)
    {
        //delay_ms(1);

        output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
        output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
        output_low(PIN_A1); // 597 `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); // 597 `SHIF Y STORAGE CLOCK INPUT` ALTO DESPLAZA
    }

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

}
 
Última edición por un moderador:
Como te sugiere el forista, la bandera global estaria perfecta.

Si te queres ahorrar una variable, podes usar la bandera de interrupcion externa del mismo micro. Vas a tener que mirar los registros (tools -> device editor -> registers) para saber cual es
 
Perdonar por no contestar antes, acabo de volver de las vacaciones. Muchas gracias seaarg, edwin ts y ByAxel me habeis ayudado mucho. Lo voy a probar ahora mismo XD
 
Hola amigos. En efecto, como decís, puedo usar la variable bandera, pero aunque en la simulación de ISIS funciona perfectamente, cuando lo paso al hardware me sigue empezando el programa.
Os lo paso para que me digáis si estoy loco.
Nota: La interrupción funciona porque el led se apaga y se enciende.

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 char bandera;

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

   {
   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_B4);
   output_high(PIN_A5); // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA
   output_low(PIN_A3);
      int f;
      for (f=0; f<8; f++)
      {
      //delay_ms(1);
      
      output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1); // 597 `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); // 597 `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
   //output_low(PIN_B4);
   
    int i;
    int e;
    for (e=0; e<16; e++)
    {
      for ( i=0; i<8; i++)
      {
      //delay_ms(1);
      
      output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1); // 597 `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); // 597 `SHIF Y STORAGE CLOCK INPUT` ALTO DESPLAZA
      
      
      }
   
      
      
     }
    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)
   {
   output_toggle(PIN_B3); //
   bandera=2;
   
   
   }

//Programa Principal
void main (void)
   {
   bandera=1;
   delay_ms(1000);
   enable_interrupts(INT_EXT);
   ext_int_edge(l_to_h);
   enable_interrupts(global);
   
   
   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
  
  
  
  while (true)
    {
   //Consultas el estado de la bandera
      switch (bandera)
      {
      case 1:
      CLEAR();
      break;
      case 2: 
   
   
   
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   
   output_low(PIN_A5);delay_ms(300);;
  
      }
   }
   
}
 
Última edición por un moderador:

D@rkbytes

Moderador
Alguien puede indicarme a que se debe estos 2 Warnings que me da el CCS?
se los agradeceria mucho :(
Esas advertencias aparecen cuando el compilador deshabilita algunas interrupciones para evitar un reingreso.
O sea que, algunas veces se tienen que deshabilitar ciertas interrupciones durante la ejecución del programa.

No pasa nada, ya que el compilador lo está haciendo por ti, pero si las quieres evitar, debes deshabilitar las interrupciones que aparecen con advertencia.
Después las tienes que volver a habilitar para que se sigan ejecutando.
 
en mi caso estoy usando Interrupcion por TMR1, TMR2 y Externas. Esto quiere decir que, cuando se habilita una de ellas, se deshabilitan las demas hasta que salga de la interrupcion en la que se encuentra?

Muchas gracias!
 

D@rkbytes

Moderador
en mi caso estoy usando interrupción por TMR1, TMR2 y Externas.
¿Esto quiere decir que, cuando se habilita una de ellas, se deshabilitan las demás hasta que salga de la interrupción en la que se encuentra?
Nop. Si te fijas bien sobre los mensajes de advertencia, solo se deshabilitan algunas, no todas.
Posteriormente el compilador las vuelve a habilitar.
No deberías preocuparte por eso, a menos que quieras evitar esos mensajes y buscar cuando es que se generan.
 
Hola Amigo.

En primer lugar no veo la necesidad de utilizar un Switch para enviar unos datos por un registro de corrimiento y encender un led, por lo que veo lo que necesitas es:

Al presionar un pulsador, se deben enviar datos a un registro de corrimiento y cargar el valor que pasas como parámetro a la función en el Puerto B, en mi opinión, si deseas borrar el registro de corrimiento sencillamente lo podes hacer una vez antes del ciclo infinito, no veo la necesidad de estar borrando todo el tiempo el con clear() el registro de corrimiento, por otra parte, no veo la necesidad de poner tantas veces en el Puerto B el mismo dato, con solo cargarlo una vez es suficiente.

Te escribo el siguiente ejemplo, probablemente lo que sucede es que se te esta quedando bloqueado el Uc, porque todo el tiempo estas recorriendo el Switch.
Por otra parte, la estructura del Switch no está bien, donde dejaste el break del segundo caso y el case por default tampoco está.

Mira la siguiente estructura, amigo:

Código:
switch ( a ) {
case b:
  // Code
  break;
case c:
  // Code
  break;
default:
  // Code
  break;
}

No trabajo con ese compilador, pero te hice la siguiente modificación, prueba y di como te va.

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 char bandera;        

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

   {
   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_B4);
   output_high(PIN_A5); // OUTPUT ENABLE ALTO, SALIDA EN ALTA IMPEDANCIA
   output_low(PIN_A3);
      int f;
      for (f=0; f<8; f++)
      {
      //delay_ms(1);
      
      output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1); // 597 `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); // 597 `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
   //output_low(PIN_B4);
   
    int i;
    int e;
    for (e=0; e<16; e++)
    {
      for ( i=0; i<8; i++)
      {
      //delay_ms(1);
      
      output_low(PIN_A2); // 595 ´STORAGE CLOCK INPUT´ BAJO
      output_low(PIN_A3); // 595 ´SHIFT CLOCK INPUT´ BAJO
      output_low(PIN_A1); // 597 `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); // 597 `SHIF Y STORAGE CLOCK INPUT` ALTO DESPLAZA
      
      
      }
   
      
      
     }
    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)
   {
   output_toggle(PIN_B3); //
   bandera=1;
   
   
   }

//Programa Principal
void main (void)
   {
   bandera=0;
   delay_ms(1000);
   enable_interrupts(INT_EXT);
   ext_int_edge(l_to_h);
   enable_interrupts(global);
   
   
   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();
  
  while (true)
    {
    //Modificado
    if(bandera!=0){
        bandera=0;
        RUN_PALABRA (0b10011001);
        output_low(PIN_A5);delay_ms(300);
    }

/*
    //Consultas el estado de la bandera
      switch (bandera)
      {
      case 1:
      CLEAR();
      break;
      case 2: 
   
   
   
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   RUN_PALABRA (0b10011001);
   
   output_low(PIN_A5);delay_ms(300);;
  
      }
*/
   }
   
}

Saludos.
 
Última edición por un moderador:
Alguien de ustedes sabe por que me marca error en el enable global ?
este es mi codigo, básicamente el programa agrega un bit cada vez que presionas el logictouble.

#include<16f877.h>
#use delay(clock= 4Mhz)
#Fuses XT, NOWDT, NOPROTECT, NOLVP, PUT, NOBROWNOUT
#INT_EXT
int i;
void EXT(void)
{
i= i+1;
void main()
{
enable_interrupts(GLOBAL); // uso inipropiado aqui me dice eso cuando lo compilo
enable_interrupts(INT_EXT);

while(true);
output_b(0);
delay_ms(500);
if (i==0){i=1;} else {i=i<<1;}
}
 

D@rkbytes

Moderador
¿Alguien de ustedes sabe por qué me marca error en el enable global?
Porque estás anidando las rutinas.
Debes crear la rutina de servicio de interrupción en una sola estructura.

Por ejemplo, de esta forma:
Código:
int i;

#INT_EXT
void EXT(void)
{
   ++i;
}
También tendrás código sin funcionamiento en esta parte...
Código:
   while(true);
      output_b(0);
      delay_ms(500);
      if (i==0){i=1;} else {i=i<<1;}
Si cierras el bucle While con punto y coma ; se genera un bucle infinito en esa instrucción y de ahí no se pasará.
Por lo tanto, las instrucciones siguientes nunca se ejecutaran.
 
Última edición:
Hola. Estoy utilizando una interrupción en el puerto RB4 del PIC16F877A.
El main del programa enciende y apaga un led, y al presionar la interrupción se hace un barrido en el puerto D (solo para probar la interrupción).
He colocado ext_int_edge(h_to_l) para que detecte el flanco descendente, pero al iniciar el programa ingresa directo a la interrupción y cuando doy un pulso la interrupción ingresa dos veces.
¿Cuál puede ser la razón de que ocurra esto con la interrupción?
C:
#include <16f877a.h>
#fuses xt, nowdt
#use delay (clock = 4M)

#int_rb
void int_rb0 ()
{
   int aux = 1;
   set_tris_d (0b00000000);

   output_toggle(pin_b0);

   for (int i=0; i<7;i++)
   {
   aux=aux*2;
   output_d(aux);   
   delay_ms(1000);
   }
}

void main()
{
   set_tris_b (0b11110000);

   port_b_pullups(true);

   enable_interrupts(int_rb);
   ext_int_edge(h_to_l);
   enable_interrupts(global);

   while(TRUE)
   {
      output_high(pin_b1);
      delay_ms(500);
      output_low(pin_b1);
      delay_ms(500);
   }
 

Adjuntos

  • interrpcio.png
    interrpcio.png
    37.6 KB · Visitas: 4

D@rkbytes

Moderador
He colocado ext_int_edge(h_to_l) para que detecte el flanco descendente, pero al iniciar el programa ingresa directo a la interrupción y cuando doy un pulso la interrupción ingresa dos veces.
EXT_INT_EDGE es únicamente para la interrupción externa por RB0
¿Cuál puede ser la razón de que ocurra esto con la interrupción?
Lo que sucede es que la interrupción externa por <RB4:RB7> se da cuando cualquiera de estos pines cambian de estado.
Por eso es que desde el principio ocurre la interrupción, ya que en el POR (Power On Reset) los pines de salida toman un estado indefinido.
Para conocer los estados de los registros durante el POR se puede consultar la hoja de datos.

La forma más sencilla de operar con la interrupción <RB4:RB7> es realizando una comparación:
En el caso de RB4, por ejemplo:
C:
#INT_RB
void int_rb4_rb7 (void)
{
    if(!input_state(PIN_B4))
    {
        // Código
    }
}
Ahí se espera que el PIN RB4 se encuentre en 0 para actuar.

Si se requiere comprobar desde RB4 hasta RB7 entonces puede ser así:
C:
#INT_RB
void int_rb4_rb7 (void)
{
    if(!input_state(PIN_B4))
    {
        // Código
    }
    else if(!input_state(PIN_B5))
    {
        // Código
    }
    else if(!input_state(PIN_B6))
    {
        // Código
    }
    else if(!input_state(PIN_B7))
    {
        // Código
    }
}

Otra forma usando una máscara:
C:
#INT_RB
void int_rb4_rb7 (void)
{
    int8 port_mask;
   
    port_mask = input_b() & 0xF0;    // Máscara para <RB4:RB7> por flanco descendente.
   
    switch (port_mask)
    {
        case 0xE0:    // Interrupción externa por RB4
            // Código
            break;
        case 0xD0:    // Interrupción externa por RB5
            // Código
            break;
        case 0xB0:    // Interrupción externa por RB6
            // Código
            break;
        case 0x70:    // Interrupción externa por RB7
            // Código
    }
}
 
Arriba