Interrumpe con 16f887 y MPLAB

1

Necesito ayuda con las interrupciones y el 16f887.

Estoy usando MPLAB y escribiendo mi código en C. Estoy usando la placa de demostración de 44 pines de Microchip. Hay un botón pulsador conectado a RBO / INTO que normalmente es alto y se baja cuando se presiona el botón.

Ya verifiqué que la entrada y el botón pulsador están funcionando, pero no creo que esté configurando la interrupción correctamente. Cuando se presiona el botón, intento activar PORTD, y cuando vuelve la interrupción, PORTD se desactiva.

Sin embargo, cuando ejecuto el código, PORTD se enciende de inmediato. ¿Alguna idea?

#include <pic16f887.h>
#include <htc.h>

__CONFIG (DEBUG_ON, LVP_OFF, FCMEN_OFF, IESO_OFF, BOREN_OFF,
    CPD_OFF, CP_OFF, MCLRE_ON, WDTE_ON, FOSC_INTRC_NOCLKOUT, BOR4V_BOR21V);


void intMain() {
PORTD=0xff;
INTF=0;
GIE=1;
}


void main(void){

 TRISB = 0xff;        //set PORTB as inputs
 TRISD = 0x00;        // Set PORTD as an Output
 ANSEL = 0x00;
 ANSELH = 0x00;
 GIE=1;
 INTE=1;
 PORTD=0x00;
 while(1)
 {
     PORTD=0x00;

 }
}

EDIT

He actualizado mi código basado en algunas sugerencias a continuación. Aquí está el código actual. Lo escribí para que, cuando se llame el ISR, el puerto D cuente de 0 a 256, luego borre y salga del ISR. He escrito en una trampa para evitar que el ISR salga y mantenerlo en un bucle sin fin. Cuando inicio el controlador, el puerto cuenta hasta 256, se borra y se reinicia repetidamente.

#include <pic16f887.h>
#include <htc.h>

__CONFIG (DEBUG_ON, LVP_OFF, FCMEN_OFF, IESO_OFF, BOREN_OFF,
    CPD_OFF, CP_OFF, MCLRE_ON, WDTE_ON, FOSC_INTRC_NOCLKOUT, BOR4V_BOR21V);

void interrupt intMain() {
int i,k;
i=0;
k=0;
while(i<256)
{
    while(k<3000) //delay
        k++;
    i++;
    k=0;
    PORTD=i;
}
while(1){} //trap
//INTF=0;
}

void main(void){

 TRISB = 0xff;        //set PORTB as inputs
 TRISD = 0x00;        // Set PORTD as an Output
 ANSEL = 0x00;
 ANSELH = 0x00;
 INTE=1;
 GIE=1;
 INTEDG=0;
 nRBPU=0;
 WPUB0=1;
 PORTD=0x00;
 while(1)
 {
     PORTD=0x00;

 }
}
    
pregunta Michael

4 respuestas

3

Intente borrar el bit INTEDG del registro OPTION_REG. De la hoja de datos página 30 (32):

INTEDG: Interrupt Edge Select bit
        1 = Interrupt on rising edge of INT pin
        0 = Interrupt on falling edge of INT pin

Cuando PORTD está alto, ¿el LED se enciende o apaga?

También puedes ver cambiar contacto rebotar . Aquí hay un enlace y cómo rebotar . Para verificar si el rebote de contacto está causando lo que se ve como un "problema", agregue un retraso de 500 ms o 1 segundo después de PORTD=0xff; en la rutina de interrupción. Si el puerto es alto, su problema es el rebote de contacto si la solución sugerida anteriormente no resuelve su problema, es decir, eliminar el bit INTEDG.

No necesitas ese GIE=1; en la última línea del bloque de interrupción.

No tengo experiencia con el compilador Hi-Tech C. Las posibilidades son bajas, pero intente hacer INTE=1; antes de GIE=1; en la función principal.

Editar

Intente cambiar void intMain() a void interrupt intMain() . Según

  

HI-TECH C® para PIC10 / 12/16 Guía del usuario 3.8 MANEJO DE INTERRUPCIÓN EN C (Página 86) Enlace

Editar después de la segunda pregunta

Según el mismo manual mencionado anteriormente (299):

  

Para producir un bucle infinito, use para (;;).

Está intentando asignar un valor de "entero" a una variable de "carácter" como cito a continuación. Defina la variable i como unsigned char . El compilador debería encargarse de esto, pero vale la pena intentarlo.

...
int i,k;
...
PORTD=i;
...
    
respondido por el abdullah kahraman
0

No sé acerca de Hi-tec C, pero ciertamente en otros hay que hacer cosas especiales para que funcionen las interrupciones:

Cree una función de interrupción en una ubicación de memoria específica. Esta es la dirección de "vector" de la interrupción, generalmente 0x80 o 0x88, dependiendo del microcontrolador, verifique la hoja de datos. Esta función debe tener un comando, que es un comando "GOTO" de ASM para su rutina de interrupción real. Esto debe marcarse como una función de interrupción (no sé cómo en HTC) para que use la instrucción RETFIE en lugar de la instrucción RETURN normal, y también maneje la conservación de registros en la pila.

Exactamente cómo organiza todo esto en HTC, no puedo decirle. Le sugiero que lea el Manual de Hi-Tec C: debería estar instalado en su sistema en algún lugar.

    
respondido por el Majenko
0

Parece que se olvidó de activar el pullup débil para RB0. Sin eso, el pin simplemente flotará cuando no se presione el botón.

No conozco tu compilador, pero el restablecimiento manual de GIE en la rutina de interrupción no tiene sentido. Eso debe hacerse con una instrucción RETFIE. No sé cómo explicarle eso a tu compilador. Tendrás que cavar a través del manual tú mismo. O más fácil, simplemente escríbalo en el ensamblador para saber exactamente qué instrucciones está ejecutando la máquina.

Añadido:

Su segundo código intenta comparar las variables INT con valores mayores a 255. Eso implica que INT es más que un byte. ¿Es eso realmente cierto en tu compilador? Recuerde, esta es una máquina de 8 bits, por lo que podría no serlo.

    
respondido por el Olin Lathrop
-1

Se debe a que tienes habilitado el temporizador de vigilancia (WDTEN_ON) porque tu controlador se reinicia.

    
respondido por el user133993

Lea otras preguntas en las etiquetas