Timer0 no se interrumpe en PIC18f4321

0

Estoy intentando ejecutar un código básico de mi libro de texto en un PIC18F4321, usando el último compilador XC8. Se supone que enciende un LED después de 10 segundos, pero el LED nunca se enciende. He comprobado mi cableado y he probado el puerto y debería funcionar bien. Intento la depuración a través de Pickit 3 y la ejecuto como una versión simulada y la interrupción nunca se dispara, lo que me lleva a pensar que algo está mal con el temporizador. ¿Alguna idea sobre qué podría estar causando que la interrupción falle?

#include <pic18f4321.h> //include necessary header
#pragma config OSC = INTIO2 
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config BOR = OFF

unsigned char count;
void LEDON();

#pragma code T0ISR = 0x08;
void T0ISR() {
    asm("GOTO LEDON");
}

#pragma code
void main(void) {
    OSCCON = 0x60;
    TRISC = 0x00;
    PORTCbits.RC0 = 0; //start LED off
    INTCONbits.PEIE = 1; //turn on peripheral interrupt
    INTCONbits.GIE = 1; //enable global interrupt
    T0CON = 0x07; //16 bit mode, normal prescale, internal clock
    TMR0H = 0x67;
    TMR0L = 0x69;
    INTCONbits.TMR0IE = 1; //enable timer 1 interrupt
    INTCONbits.TMR0IF = 0; //clear the timer interrupt flag
    T0CONbits.TMR0ON = 1;

    while(1);

    return;
}

 #pragma interrupt LEDON
 void LEDON() {
    PORTCbits.RC0 = 1;
    INTCONbits.TMR0IF = 0;
}
    
pregunta nerdsley

1 respuesta

1

Le convendría leer el manual de XC8 y ver un mejor código de ejemplo para la familia de piezas PIC18F.

Tenga en cuenta que las versiones XC8 2.0 y posteriores tienen una sintaxis diferente para declarar rutinas de servicio de interrupción.

Esta es la sintaxis que me funciona con el compilador Microchip XC8 versión 1.45:

/* 
 * File: main.c
 * Target: PIC18F4321
 * Compiler: XC8 v1.45
 * MPLABX IDX v4.05
 * 
 * Description:
 * 
 *  Use TIMER0 interrupt to turn on LED attached 
 *  to PORTC bit RC0 ten seconds after power on reset.
 */

#pragma config OSC = INTIO2     // Oscillator (Internal oscillator block, port function on RA6 and RA7)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = OFF        // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum Setting)
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)
#pragma config CCP2MX = RC1     // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = ANA     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
#pragma config STVREN = ON      // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config BBSIZ = BB256    // Boot Block Size Select bits ( 256 Word)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
#pragma config CP0 = OFF        // Code Protection bit (Block 0 not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 not code-protected)
#pragma config CPB = OFF        // Boot Block Code Protection bitProtect Boot (Boot block not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 not write-protected)
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 not protected from table reads executed in other blocks)
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block not protected from table reads executed in other blocks)

#include <xc.h>

unsigned char count;

// Wrong way to catch interrupts with XC8
// void LEDON();

// #pragma code T0ISR = 0x08;
// void T0ISR() {
//     asm("GOTO LEDON");
// }

// #pragma code
void main(void) {
    OSCCON = 0x60;
    TRISCbits.RC0 = 0;  // make PORTC bit RC0 and output
    LATCbits.LATC0 = 0; // turn LED off PORTC bit RC0
    T0CON = 0x07; //16 bit mode, prescale 1:256, internal clock
    TMR0H = 0x67; // TIMER0 interrupt asserts 10000128 instruction clocks 
    TMR0L = 0x69; // after the timer is turned on.
    INTCONbits.TMR0IF = 0; //clear the timer interrupt flag
    INTCON2bits.TMR0IP = 1; // select timer interrupt priority
    INTCONbits.TMR0IE = 1; //enable timer interrupt
    RCONbits.IPEN = 0; // select legacy interrupt model
    INTCONbits.PEIE = 1; //turn on peripheral interrupt
    INTCONbits.GIE = 1; //enable global interrupt
    T0CONbits.TMR0ON = 1; // turn on TIMER0

    while(1); // embedded applications in a PIC never return from main()

}

// Wrong way to catch interrupts with XC8
// #pragma interrupt LEDON
// void LEDON() {
//     PORTCbits.RC0 = 1;
//     INTCONbits.TMR0IF = 0;
// }

void interrupt ISR( void )
{
    if (INTCONbits.TMR0IE) // check if TIMER0 interrupt is enabled
    {
        if (INTCONbits.TMR0IF) // check if TIMER0 interrupt has asserted
        {
            INTCONbits.TMR0IF = 0; // clear TIMER0 interrupt assert
            LATCbits.LATC0 = 1; // turn LED on PORTC bit RC0
        }
    }
}
    
respondido por el Dan1138

Lea otras preguntas en las etiquetas