PIC 18F Interrupts

Help
2008-09-06
2013-03-12
  • William Gebers
    William Gebers
    2008-09-06

    Hi. 

    I am a newbie to SDCC so apologize if this is a foolish question.

    I am trying to create a script that, using interrupts, flashes a few LED's.  The point of this script is to ultimately have interrupt driven routines for another project. 

    I have watched the registers using an ICD2, and I notice that the TMR0 register overflows, but does not trigger an interrupt.  Any suggestions as to where I went wrong?

    Thanks in advance for your assistance.

    #include "pic18fregs.h"
    // For PIC18F2550

    // Configuration Bits
    code char at __CONFIG1H conf1 = 0x22; // Select HS OSC
    code char at __CONFIG4L conf2 = 0x81; // Disable LVP
    code char at __CONFIG2H conf3 = 0x0E; // Disable WDT

    // flip flops
    volatile int x = 0;
    volatile int x1 = 0;

    void isr_high() interrupt 1
        {
        x = 1-x;
        INTCONbits.TMR0IF = 0;
        T0CONbits.TMR0ON = 1;
        }
    void isr_low() interrupt 2
        {
        x1 = 1-x1;
        INTCONbits.TMR0IF = 0;
        T0CONbits.TMR0ON = 1;
        }   

    void setup_interupts()
        {
       
        // Timer setup
        T0CON = 0x08;  // Prescale 256, Internal clock
        T0CONbits.T08BIT = 1;
        T0CONbits.TMR0ON = 1;
       
        // Interupts activate
        RCONbits.IPEN = 1; // Allow priorities in interrupts
        INTCONbits.GIE = 1;  // Enable high priority interrupts
        INTCONbits.PEIE = 1; // Enable low priority interrupts
        INTCON2bits.TMR0IP = 1; // Enable timer 0 interupt as high priority
        }

    void delay_ms(long ms)
    {
        long i;
        while (ms--)
            for (i=0; i < 330; i++)
                ;
    }

    void main()
    {
        setup_interupts();
        TRISBbits.TRISB0 = 0;
        TRISBbits.TRISB1 = 0;
        TRISBbits.TRISB2 = 0;
        for(;;)
        {
            PORTBbits.RB0 = x;
            PORTBbits.RB1 = x1;
        }
    }

     
    • Raphael Neider
      Raphael Neider
      2008-09-06

      Maybe you are just missing an
      INTCONbits.TMR0IE = 1; // enable TMR0 IRQs
      in setup_interupts()?

      HTH,
      Raphael

       
    • William Gebers
      William Gebers
      2008-09-06

      Hi Raphael.

      Thanks for the suggestion.  I have added it to the setup_interupts() routine, but still the interupt does not trigger.

      Any more suggestions?

       
    • kein0r
      kein0r
      2008-09-06

      You should try the following to see where the problem is:

      Disable INT priority and use something like if (PORTBbits.RB0) PORTBbits.RB0 = 0; else PORTBbits.RB0 = 1; to toggle a pin in the isr. Dont forget to enable TMR0IE as mentioned before.
      If this works you have a problem configuring the isr prios.

       
    • William Gebers
      William Gebers
      2008-09-06

      Thanks for the help guys!

      I have solved the problem, and for completeness have posted the changes below

      1) Changed the flashing LED as suggested above.
      2) Changed the setup code as follows
          // Timer setup
          T0CON = 0x08;  // Prescale 256, Internal clock
          T0CONbits.T0CS = 0;  // Set to timer mode not counter mode
          T0CONbits.PSA = 0; // Set prescaler to active
          T0CONbits.T08BIT = 0; // Set counter to 16 bit
          T0CONbits.TMR0ON = 1; // Set Timer 0 to on
          INTCON = 0; // Clear INTCON
          INTCONbits.TMR0IE = 1; // Enable Timer interrupt
      `    INTCONbits.TMR0IF = 0; // Clear timer interrupt flag
          // Interupts activate
          RCONbits.IPEN = 0; // Disallow priorities in interrupts
          INTCONbits.GIE = 1;  // Enable interrupts
          INTCONbits.PEIE = 1; // Enable peripheral interrupts
          INTCON2bits.TMR0IP = 1; // Enable timer 0 interrupt as high priority
          T0CONbits.TMR0ON = 1; // Set Timer 0 to on again