3
\$\begingroup\$

I'm trying to compile this code to blink led with button interrupt, using xc8 compiler and PIC18F4550. I got those warning, so the code lines are ignored and the program doesn't work properly (by clinking on button nothing happens)

newmain.c:45: warning: (335) unknown pragma "code"
newmain.c:46: warning: (335) unknown pragma "interrupt"
newmain.c:65: warning: (335) unknown pragma "code"

program code

#define _XTAL_FREQ 4000000
#include <pic18f4550.h>

// BEGIN CONFIG
#pragma config OSC = HS

static int cpt = 1;

void IntExternal_INT(void) {
    TRISB0 = 1; // PORT B0 as input
    INT0E = 1;
    INTCONbits.PEIE = 1; //enable periphyrical interrupts 
    INTCONbits.GIE = 1;
    INTEDG0 = 0; //: Interrupt Edge Select bit : 1 = Interrupt on rising edge of RB0/INT pin
    //  0 = interrupt on falling edge
    INT0F = 0;
}

void delay() {
    volatile int i, j;
    for (i = 0; i < 2000; i++)
        for (j = 0; j < 10; j++);
}

#pragma code isr = 0x08 // Store the below code at address 0x08
#pragma interrupt isr  // let the compiler know that the function isr() is an interrupt handler

void iscr(void) {
    cpt++;

    if (INT0IF) //If External Edge INT Interrupt
    {
        LATDbits.LATD0 = 1; // RD-0 to High
        LATDbits.LATD1 = 1; // RD-1 to High
        delay();
        LATDbits.LATD0 = 0; // RD-0 to LOW
        LATDbits.LATD1 = 0; // RD-1 to LOW
        delay();
        INT0IF = 0; // clear the interrupt
    }
}    
#pragma code // Return to the default code section

void main(void) {
    IntExternal_INT();
    TRISD = 0xF0; // PORT B Setting: Set all the pins in port D to Output.
    while (1) {
        if (cpt % 2 == 0) {
            delay();
            LATDbits.LATD0 = 1; // RD-0 to High
            LATDbits.LATD1 = 1; // RD-1 to High
            delay();
            LATDbits.LATD0 = 0; // RD-0 to LOW
            LATDbits.LATD1 = 0; // RD-1 to LOW
        }
    }
}
\$\endgroup\$
2
  • \$\begingroup\$ I think you need to call your iscr isr, and you need to declare it above the #pragma interrupt isr \$\endgroup\$ Commented Aug 30, 2014 at 9:24
  • \$\begingroup\$ aaaand that won't work too because you don't have that much room up there in memory, you will need a goto to an appropriate handler. \$\endgroup\$ Commented Aug 30, 2014 at 9:25

2 Answers 2

7
\$\begingroup\$

Have you read the XC8 user's guide? Section 5.9 deals with interrupts.

In there it states:

The function qualifier interrupt (or __interrupt) can be applied to a C function definition so that it will be executed once the interrupt occurs. The compiler will process the interrupt function differently to any other functions, generating code to save and restore any registers used and return using a special instruction.

and:

An interrupt function must be declared as type void interrupt and cannot have parameters. This is the only function prototype that makes sense for an interrupt function since they are never directly called in the source code.

It then goes on to give an example:

int tick_count;

void interrupt tc_int(void)
{
    if (TMR0IE && TMR0IF) {
        TMR0IF=0;
        ++tick_count;
        return;
    }
    // process other interrupt sources here, if required
}

The compiler itself handles inserting the code into the right location in the vector table to call the ISR.

By default it uses the high priority interrupt vector. To specify the low priority vector instead, insert the attribute low_priority:

void interrupt low_priority tc_int()
\$\endgroup\$
6
  • \$\begingroup\$ I did exactly as you said beore, but not working stackoverflow.com/questions/25553762/… . so I tried this method that I found in a tutorial \$\endgroup\$ Commented Aug 30, 2014 at 10:19
  • \$\begingroup\$ I think the #pragma method was from C18 which is now obsolete. \$\endgroup\$
    – Majenko
    Commented Aug 30, 2014 at 10:30
  • \$\begingroup\$ so you mean that the interrupt method of this code is obsolete and I should follow the first method ( question on stackoverflow) . I'm using xc8 compiler \$\endgroup\$ Commented Aug 30, 2014 at 10:33
  • 1
    \$\begingroup\$ Yes, since XC8 uses the method I detail (and you have in your other question), not the #pragma method. That's why it tells you, quite plainly when you compile, that you're doing it wrong. \$\endgroup\$
    – Majenko
    Commented Aug 30, 2014 at 10:34
  • \$\begingroup\$ Majenco is perfectly right, my comments to the questions are there because I though this was about C18 (misread) \$\endgroup\$ Commented Aug 30, 2014 at 10:35
2
\$\begingroup\$

In addition to Majenko's correct answer, you have other issues with your code. It looks like you lifted a configuration setting from an example you found somewhere. Unfortunately, the configuration settings on every PIC are different. The only exception to that is PICs within the same family. You cannot simply copy configuration settings from source code for a different PIC and hope it will work. As it is, your code will not work due to a lack of proper configuration settings.

Luckily, getting the correct configuration settings is very easy. Assuming you're using MPLAB X, go to Windows->PIC Memory Views->Configuration Bits. A new tab called "Configuration Bits" should open at the bottom of the screen. Adjust the settings as you need under the Options column (hint: you will want to turn the WDT off and the FOSC to HS, everything else can probably stay the same). Then click the "Generate Source Code to Output" button. It will produce a long list of "#pragma config" lines. Copy everything and paste it at the top of your code.

\$\endgroup\$
4
  • \$\begingroup\$ the configuration is not been written in the code by clinking generate source code to output \$\endgroup\$ Commented Aug 30, 2014 at 10:45
  • \$\begingroup\$ Also other things to consider / learn about are how to use the volatile keyword, atomic blocks when accessing shared variables, and why you shouldn't be using int for counting a number less than 256. \$\endgroup\$
    – Majenko
    Commented Aug 30, 2014 at 10:50
  • \$\begingroup\$ @Makouda, the last line of my answer says you have to copy and paste the text manually. It doesn't insert it into your code for you. \$\endgroup\$
    – Dan Laks
    Commented Aug 30, 2014 at 10:58
  • \$\begingroup\$ @DanLaks ok understand, I can see the output configuration ,thanks \$\endgroup\$ Commented Aug 30, 2014 at 10:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.