pic18 interrupts declaration

ptoni2000
2008-04-10
2013-03-12
  • ptoni2000
    ptoni2000
    2008-04-10

    Hi, i have a project on a pic18f4620 with some interrupt functions,
    most of them with declaration and function in main.c, one in a separate c file.

    The problem is: when i declare the interrupt with the macro:

        DEF_HANDLER(SIG_INT0, _int0_handler)

    on the main.c and the function with:

        SIGHANDLER(_int0_handler)

    on the ir_in.c file the compiler give me the message:

        tv_main.asm:234:Error [113] Symbol not previously defined (__int0_handler).

    The only solution i have found is adding to main.c before the DEF_...END_DEF declarations the two lines:

        SIGHANDLER(_int0_handler);
        volatile void (* dummy)()= _int0_handler;

    The first one is the prototipe declaration for the interrupt function present in ir_in.c, the second line is an assignement to a dummy function pointer.
    This is a waste of 3 bytes on the dummy() declaration but make the compiler happy.

    This is the right solution or there is a better one?

    This is a compilable demo code for testing this:

    ====== main.c ======

    #include <pic18fregs.h>
    #include <usart.h>
    #include <stdbool.h>
    #include <signal.h>

    SIGHANDLER(_int0_handler);
    //volatile void (* dummy)()= _int0_handler;

    /* interrupts handlers */
    DEF_INTHIGH(high_int)            /* interrupt dispatch table for high priority interrupts */
    DEF_HANDLER(SIG_TMR2, _tmr2_handler)    /* define a handler for the timer2 */
    DEF_HANDLER(SIG_RC,   _rx_handler)    /* define a handler for serial rx */
    DEF_HANDLER(SIG_INT0, _int0_handler)    /* define a handler for external int 0 */
    DEF_HANDLER(SIG_INT1, _int1_handler)    /* define a handler for external int 1 */
    DEF_HANDLER(SIG_INT2, _int2_handler)    /* define a handler for external int 2 */
    END_DEF                    /* end the declaration of the dispatch table. */

    SIGHANDLER(_tmr2_handler)
    {
        PIR1bits.TMR2IF = 0;    /* Clear timer interrupt flag */
    }

    SIGHANDLER(_rx_handler)
    {
        char c;

        c = usart_getc();
    }

    SIGHANDLER(_int2_handler)
    {
        INTCON3bits.INT2IF = 0;
    }

    SIGHANDLER(_int1_handler)
    {
        INTCON3bits.INT1IF = 0;
    }

    void main (void)
    {
        // Main loop, neverending...
        while (true)
        {

        }
    }

    ====== ir_in.c ======

    #include <pic18fregs.h>
    #include <signal.h>

    SIGHANDLER(_int0_handler)
    {
        INTCONbits.INT0IF = 0;    // clear interrupt flag
    }

    ====== Makefile ======

    # Makefile for compilation w sdcc
    PIC=18f4620
    SDCC=sdcc
    GPASM=gpasm
    GPLINK=gplink

    INCLUDE=-I. -I/usr/share/sdcc/include/pic16
    LDFLAGS=-m -w -I/usr/share/sdcc/lib/pic16 -c -s /usr/share/gputils/lkr/$(PIC).lkr
    #CFLAGS=-V -S
    CFLAGS= -S

    # startup code with initialisation
    LIBS=crt0i.o libsdcc.lib libc18f.lib pic$(PIC).lib libio$(PIC).lib

    PROCESSOR_FLAGS=-mpic16 -p$(PIC)

    SOURCES= ir_in.c tv_main.c
    PROJECT=tv_driver.hex

    OBJS = $(SOURCES:.c=.o)

    all: $(PROJECT)

    %.o: %.c
        $(SDCC) $(INCLUDE) $(PROCESSOR_FLAGS) $(CFLAGS) $<
        $(GPASM) -c $*.asm

    $(PROJECT): $(OBJS)
        $(GPLINK) $(LDFLAGS) -o $(PROJECT) $(OBJS) $(LIBS)

    clean:
        rm -f *.cof *.adb *.asm *.cod *.lst *.hex *.p *.d *.lnk *.map *.o *~