Interrupcion Externa y MCLR. ¿Cómo funcionan? PIC18F4550

#1
Hola, chicos y chicas.
Bueno, como el título lo menciona, tengo una duda de cómo manejar un interrupción externa, en concreto #INT EXT (RB0) en el PIC18F4550.

La verdad soy novato manejando un microcontrolador.
Les posteo mi programa para que puedan visualizar mi duda.
Mi intención es utilizar la interrupción externa (RB0) y consecuentemente a este proceso asigné un valor entero a una variable previamente definida con el nombre de Inicio.

El formato de esta variable es de tipo int1 y dependiendo de su valor se ejecutará una de las dos opciones:
Si es uno, se enciende el Led 1 ubicado en el puerto E en el pin RE1 y se apaga el pin RE0, si el valor de la variable inicio es igual a cero sucede el efecto inverso.

El problema de este programa es qué cuando oprimo el MCLR (Master Clear) el proceso inicial no se vuelve a repetir.
Entonces la pregunta es. ¿Cómo le hago para trabajar el MCLR y las interrupciones externas?
PHP:
//Librerias para el microcontrolador 
#include <18F4550.h>
#fuses   XT, NOWDT, PBADEN, MCLR, PUT, NOWRT
#use delay (clock = 4000000)
//Asiganación de variables a la RAM
#byte TRISE=0xF96
#byte PORTe=0xF84 
#byte TRISB=0xF93
#byte PORTB=0xF81
#byte INTCONT2=0xFF1

int1 Inicio;

#INT_EXT
 int1 EXT_ISR()
{
   Inicio=1;
   clear_interrupt(int_ext);
   return Inicio;
}


void main()
{
TRISB=0xFF;
TRISE=0x08;
Inicio=0; 
bit_clear(INTCONT2, 7);
bit_clear(PORTE, 0);
bit_clear(PORTE, 1);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
   while(TRUE)
   {
      if(Inicio==1)
      {
        bit_set(PORTE, 1);
        bit_clear(PORTE, 0);
      }
        else
        {
        bit_set(PORTE, 0);
        bit_clear(PORTE, 1);
        }
   }
}
 
Última edición por un moderador:
#2
No realices el servicio de interrupción como una función que retorne un valor.
Eso sería como querer invocar por código a la interrupción externa.

Prueba así:
PHP:
#include <18f4550.h>
#fuses   nofcmen
#use     delay(crystal = 4MHz)

int1 Inicio = 0;

#int_ext
void sdi_int_ext (void)
{
   Inicio = 1;
}

void main (void)
{
   enable_interrupts(int_ext);
   ext_int_edge(l_to_h);
   enable_interrupts(global);
   
   while (true)
   {
      if(Inicio)
      {
         output_high(pin_e1);
         output_low(pin_e0);
      }
      else
      {
         output_high(pin_e0);
         output_low(pin_e1);
      }
   }
}
Pero no simules el programa porque no funcionará, debes hacerlo físicamente.
En la simulación no se ejecutará el código desde el principio (Vector de Reset) y eso te causará confusión.

Lo que verás físicamente, es que al iniciar el programa, RE0 estará en nivel 1 y RE1 en nivel 0.
Cuando ocurra la interrupción externa por RB0, se invertirán los estados de los pines RE0 y RE1 y al presionar el botón de reset, el programa se ejecutará con los valores iniciales.
 
Arriba