Loading ...
Sorry, an error occurred while loading the content.

Interrupt priorities on PIC18F452

Expand Messages
  • Ron Clough
    I m trying to blink two LEDs at different rates using interrupts from two timers. One interrupt has low priority and the other has high priority. Getting one
    Message 1 of 2 , Aug 7, 2007
    • 0 Attachment
      I'm trying to blink two LEDs at different rates using interrupts from
      two timers. One interrupt has low priority and the other has high
      priority. Getting one LED to run at low priority is no problem. When I
      add the code for the second LED running at high priority, nothing
      works! Has anyone out there successfully operated two interrupts at
      different priorities on a PIC18F452? My code follows. Can anyone see
      what I'm doing wrong?

      Cheers,
      RonC

      Main file:

      //
      // Demonstrate low priority interrupt and high priority interrupt
      running together
      //

      #include <p18f452.h>
      #include "TwoIntsProcs.h"
      #include <stdio.h>

      // Configuartion bits
      #pragma config OSC = HS, OSCS = OFF
      #pragma config PWRT = ON
      #pragma config BOR = ON
      #pragma config WDT = OFF
      #pragma config CCP2MUX = OFF
      #pragma config LVP = OFF

      //
      // Start of main()
      //
      void main (void) {
      // Initialize various subsystems
      initPorts();
      initUART(BAUD_19200);
      printf("\n\r");
      printf("Ports initialized . . .\n\r");
      // Initialize interrupts
      initLED1Flasher();
      initLED2Flasher();
      printf("Interrupts initialized . . .\n\r");
      // Initialize the LEDs
      heartbeat_1 = HEARTBEAT_RATE_1;
      HEARTBEAT_LED_1 = LED_OFF;
      heartbeat_2 = HEARTBEAT_RATE_2;
      HEARTBEAT_LED_2 = LED_OFF;
      // Enable interrupts
      RCONbits.IPEN = 1; // Enable high & low interrupt priorities
      INTCONbits.GIEL = 1; // Enable low priority interrupts
      INTCONbits.GIEH = 1; // Enable high priority interrupts
      printf("Interrupts enabled . . .\n\r");
      printf("\n\r");

      do {
      printf("LEDs blinking\n\r");
      longDelay(ONE_SECOND);
      } while (TRUE);
      } // End of main()

      Header file:

      //
      // Header file for TwoIntsMain.c
      //
      #include <usart.h>
      #include <timers.h>
      #include <stdio.h>

      // Constants
      #define FALSE 0
      #define TRUE 1
      // LED
      #define HEARTBEAT_RATE_1 100
      #define HEARTBEAT_LED_1 LATBbits.LATB1 // Port B bit 1
      #define HEARTBEAT_RATE_2 50
      #define HEARTBEAT_LED_2 LATBbits.LATB2 // Port B bit 2
      #define LED_OFF 1
      #define LED_ON 0
      // longDelay()
      #define PERIOD_100MS 10
      #define ONE_SECOND 100
      // UART
      #define BAUD_19200 64

      // Variables
      unsigned int heartbeat_1, heartbeat_2;
      unsigned int systemTime;

      // Prototypes
      void initPorts(void);
      void initLED1Flasher(void);
      void initLED2Flasher(void);
      void initUART(unsigned char baudRate);
      void longDelay(unsigned int duration);

      void HighPriorityTable(void);
      void LED2_Handler(void);
      void LowPriorityTable(void);
      void LED1_Handler(void);

      // Tell compiler where the high priority interrupt vector is located
      #pragma code high_vector_section=0x08
      void high_interrupt (void)
      {
      _asm GOTO HighPriorityTable _endasm
      } //

      // Tell compiler where the low priority interrupt vector is located
      #pragma code low_vector_section=0x18
      void low_interrupt (void)
      {
      _asm GOTO LowPriorityTable _endasm
      } //
      #pragma code

      //
      // Interrupt handlers
      //
      #pragma interrupthigh HighPriorityTable
      void HighPriorityTable(void) {
      if (PIR1bits.TMR1IF == 1) {
      LED2_Handler();
      }
      } // End of HighPriorityTable()

      void LED2_Handler(void) {
      PIR1bits.TMR1IF = 0; // Clear Timer1 interrupt flag
      WriteTimer1(59286); // Setup timer0 to generate next interrupt
      heartbeat_2--;
      if (heartbeat_2 == 0) {
      HEARTBEAT_LED_2 ^= 1; // Toggle LED
      heartbeat_2 = HEARTBEAT_RATE_2; // Reset "heartbeat_2"
      }
      } // End of LED2_Handler()

      #pragma interruptlow LowPriorityTable
      void LowPriorityTable(void) {
      if (INTCONbits.TMR0IF == 1) {
      LED1_Handler();
      }
      } // End of LowPriorityTable()

      void LED1_Handler (void)
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      //
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      {
      INTCONbits.TMR0IF = 0; // Clear Timer0 interrupt flag
      WriteTimer0(61); // Setup timer0 to generate next interrupt
      systemTime++; // systemTime is used by longDelay()
      heartbeat_1--;
      if (heartbeat_1 == 0) {
      HEARTBEAT_LED_1 ^= 1; // Toggle LED
      heartbeat_1 = HEARTBEAT_RATE_1; // Reset "heartbeat"
      }
      } // End of LED1_Handler()

      //
      // Initialization procedures
      //
      void initPorts(void)
      {
      TRISA = 0b00000000;
      TRISB = 0b00000000; // RB2=HEARTBEAT_LED_2, RB1=HEARTBEAT_LED_1
      TRISC = 0b10000000; // RC7=UART:RX
      TRISD = 0b00000000;
      TRISE = 0b00000000;
      } // End of initPorts()

      void initUART(unsigned char baudRate) {
      CloseUSART();
      OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE &
      USART_EIGHT_BIT & USART_BRGH_HIGH, baudRate);
      } // End of initUART

      void initLED1Flasher(void)
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      // Timer0 interrupts every ~10 ms
      // Fosc = 20 MHz => Tosc = 50 ns => instruction cycle = 200 ns
      // Prescaler = 1:256 => Timer0 is clocked at 200 ns * 256 = 51.2 us
      // 10 ms / 51.2 us = 195
      // Load timer0 with 256 - 195 = 61 so it overflows and interrupts
      every 10 ms
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      {
      CloseTimer0();
      systemTime = 0;
      INTCON2bits.TMR0IP = 0; // Low priority
      INTCONbits.TMR0IF = 0; // Clear interrupt flag
      WriteTimer0(61);
      OpenTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_8BIT & T0_PS_1_256);
      } // End of initLED1Flasher()

      void initLED2Flasher(void) {
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      // Timer1 interrupts every ~10 ms
      // Fosc = 20 MHz => Tosc = 50 ns => instruction cycle = 200 ns
      // Prescaler = 1:8 => Timer1 is clocked at 200 ns * 8 = 1.6 us
      // 10 ms / 1.6 us = 6250
      // Load timer1 with 65536 - 6250 = 59286 so it overflows and
      interrupts every 10 ms
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      CloseTimer1();
      IPR1bits.TMR1IP = 1; // High priority
      PIR1bits.TMR1IF = 0; // Clear interrupt flag
      WriteTimer1(59286);
      OpenTimer1 (TIMER_INT_ON & T1_SOURCE_INT & T1_16BIT_RW & T1_PS_1_8);
      } // End of initLED2Flasher()

      //
      // Other procedures
      //
      void longDelay(unsigned int duration)
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      // longDelay
      // Resolution ~ 10 ms
      // Timer0 interrupt MUST be running
      // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
      * * * * * *
      {
      unsigned int endTime;

      endTime = systemTime + duration;
      while(systemTime <= endTime);
      } // End of longDelay()
    • Ron Clough
      The problem has been solved. Its a C18 compiler gotcha! For the low priority interrupt you have a line like this: #pragma interruptlow LowPriorityTable BUT For
      Message 2 of 2 , Aug 7, 2007
      • 0 Attachment
        The problem has been solved. Its a C18 compiler gotcha!
        For the low priority interrupt you have a line like this:
        #pragma interruptlow LowPriorityTable

        BUT

        For the high priority interrupt you have a line like this:
        #pragma interrupt HighPriorityTable

        Notice that the word 'high' doesn't appear! If you type
        'interrupthigh', the compiler gives a warning only.

        While developing my code I was getting warnings for my printf lines.
        Eventually I stopped looking at the warnings . . . lesson learned!

        Cheers,
        RonC

        --- In ORE_bits@yahoogroups.com, "Ron Clough" <ronclough@...> wrote:
        >
        > I'm trying to blink two LEDs at different rates using interrupts from
        > two timers. One interrupt has low priority and the other has high
        > priority. Getting one LED to run at low priority is no problem. When I
        > add the code for the second LED running at high priority, nothing
        > works! Has anyone out there successfully operated two interrupts at
        > different priorities on a PIC18F452? My code follows. Can anyone see
        > what I'm doing wrong?
        >
        > Cheers,
        > RonC
        >
        > Main file:
        >
        > //
        > // Demonstrate low priority interrupt and high priority interrupt
        > running together
        > //
        >
        > #include <p18f452.h>
        > #include "TwoIntsProcs.h"
        > #include <stdio.h>
        >
        > // Configuartion bits
        > #pragma config OSC = HS, OSCS = OFF
        > #pragma config PWRT = ON
        > #pragma config BOR = ON
        > #pragma config WDT = OFF
        > #pragma config CCP2MUX = OFF
        > #pragma config LVP = OFF
        >
        > //
        > // Start of main()
        > //
        > void main (void) {
        > // Initialize various subsystems
        > initPorts();
        > initUART(BAUD_19200);
        > printf("\n\r");
        > printf("Ports initialized . . .\n\r");
        > // Initialize interrupts
        > initLED1Flasher();
        > initLED2Flasher();
        > printf("Interrupts initialized . . .\n\r");
        > // Initialize the LEDs
        > heartbeat_1 = HEARTBEAT_RATE_1;
        > HEARTBEAT_LED_1 = LED_OFF;
        > heartbeat_2 = HEARTBEAT_RATE_2;
        > HEARTBEAT_LED_2 = LED_OFF;
        > // Enable interrupts
        > RCONbits.IPEN = 1; // Enable high & low interrupt priorities
        > INTCONbits.GIEL = 1; // Enable low priority interrupts
        > INTCONbits.GIEH = 1; // Enable high priority interrupts
        > printf("Interrupts enabled . . .\n\r");
        > printf("\n\r");
        >
        > do {
        > printf("LEDs blinking\n\r");
        > longDelay(ONE_SECOND);
        > } while (TRUE);
        > } // End of main()
        >
        > Header file:
        >
        > //
        > // Header file for TwoIntsMain.c
        > //
        > #include <usart.h>
        > #include <timers.h>
        > #include <stdio.h>
        >
        > // Constants
        > #define FALSE 0
        > #define TRUE 1
        > // LED
        > #define HEARTBEAT_RATE_1 100
        > #define HEARTBEAT_LED_1 LATBbits.LATB1 // Port B bit 1
        > #define HEARTBEAT_RATE_2 50
        > #define HEARTBEAT_LED_2 LATBbits.LATB2 // Port B bit 2
        > #define LED_OFF 1
        > #define LED_ON 0
        > // longDelay()
        > #define PERIOD_100MS 10
        > #define ONE_SECOND 100
        > // UART
        > #define BAUD_19200 64
        >
        > // Variables
        > unsigned int heartbeat_1, heartbeat_2;
        > unsigned int systemTime;
        >
        > // Prototypes
        > void initPorts(void);
        > void initLED1Flasher(void);
        > void initLED2Flasher(void);
        > void initUART(unsigned char baudRate);
        > void longDelay(unsigned int duration);
        >
        > void HighPriorityTable(void);
        > void LED2_Handler(void);
        > void LowPriorityTable(void);
        > void LED1_Handler(void);
        >
        > // Tell compiler where the high priority interrupt vector is located
        > #pragma code high_vector_section=0x08
        > void high_interrupt (void)
        > {
        > _asm GOTO HighPriorityTable _endasm
        > } //
        >
        > // Tell compiler where the low priority interrupt vector is located
        > #pragma code low_vector_section=0x18
        > void low_interrupt (void)
        > {
        > _asm GOTO LowPriorityTable _endasm
        > } //
        > #pragma code
        >
        > //
        > // Interrupt handlers
        > //
        > #pragma interrupthigh HighPriorityTable
        > void HighPriorityTable(void) {
        > if (PIR1bits.TMR1IF == 1) {
        > LED2_Handler();
        > }
        > } // End of HighPriorityTable()
        >
        > void LED2_Handler(void) {
        > PIR1bits.TMR1IF = 0; // Clear Timer1 interrupt flag
        > WriteTimer1(59286); // Setup timer0 to generate next interrupt
        > heartbeat_2--;
        > if (heartbeat_2 == 0) {
        > HEARTBEAT_LED_2 ^= 1; // Toggle LED
        > heartbeat_2 = HEARTBEAT_RATE_2; // Reset "heartbeat_2"
        > }
        > } // End of LED2_Handler()
        >
        > #pragma interruptlow LowPriorityTable
        > void LowPriorityTable(void) {
        > if (INTCONbits.TMR0IF == 1) {
        > LED1_Handler();
        > }
        > } // End of LowPriorityTable()
        >
        > void LED1_Handler (void)
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > //
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > {
        > INTCONbits.TMR0IF = 0; // Clear Timer0 interrupt flag
        > WriteTimer0(61); // Setup timer0 to generate next interrupt
        > systemTime++; // systemTime is used by longDelay()
        > heartbeat_1--;
        > if (heartbeat_1 == 0) {
        > HEARTBEAT_LED_1 ^= 1; // Toggle LED
        > heartbeat_1 = HEARTBEAT_RATE_1; // Reset "heartbeat"
        > }
        > } // End of LED1_Handler()
        >
        > //
        > // Initialization procedures
        > //
        > void initPorts(void)
        > {
        > TRISA = 0b00000000;
        > TRISB = 0b00000000; // RB2=HEARTBEAT_LED_2, RB1=HEARTBEAT_LED_1
        > TRISC = 0b10000000; // RC7=UART:RX
        > TRISD = 0b00000000;
        > TRISE = 0b00000000;
        > } // End of initPorts()
        >
        > void initUART(unsigned char baudRate) {
        > CloseUSART();
        > OpenUSART( USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE &
        > USART_EIGHT_BIT & USART_BRGH_HIGH, baudRate);
        > } // End of initUART
        >
        > void initLED1Flasher(void)
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > // Timer0 interrupts every ~10 ms
        > // Fosc = 20 MHz => Tosc = 50 ns => instruction cycle = 200 ns
        > // Prescaler = 1:256 => Timer0 is clocked at 200 ns * 256 = 51.2 us
        > // 10 ms / 51.2 us = 195
        > // Load timer0 with 256 - 195 = 61 so it overflows and interrupts
        > every 10 ms
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > {
        > CloseTimer0();
        > systemTime = 0;
        > INTCON2bits.TMR0IP = 0; // Low priority
        > INTCONbits.TMR0IF = 0; // Clear interrupt flag
        > WriteTimer0(61);
        > OpenTimer0 (TIMER_INT_ON & T0_SOURCE_INT & T0_8BIT & T0_PS_1_256);
        > } // End of initLED1Flasher()
        >
        > void initLED2Flasher(void) {
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > // Timer1 interrupts every ~10 ms
        > // Fosc = 20 MHz => Tosc = 50 ns => instruction cycle = 200 ns
        > // Prescaler = 1:8 => Timer1 is clocked at 200 ns * 8 = 1.6 us
        > // 10 ms / 1.6 us = 6250
        > // Load timer1 with 65536 - 6250 = 59286 so it overflows and
        > interrupts every 10 ms
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > CloseTimer1();
        > IPR1bits.TMR1IP = 1; // High priority
        > PIR1bits.TMR1IF = 0; // Clear interrupt flag
        > WriteTimer1(59286);
        > OpenTimer1 (TIMER_INT_ON & T1_SOURCE_INT & T1_16BIT_RW & T1_PS_1_8);
        > } // End of initLED2Flasher()
        >
        > //
        > // Other procedures
        > //
        > void longDelay(unsigned int duration)
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > // longDelay
        > // Resolution ~ 10 ms
        > // Timer0 interrupt MUST be running
        > // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        > * * * * * *
        > {
        > unsigned int endTime;
        >
        > endTime = systemTime + duration;
        > while(systemTime <= endTime);
        > } // End of longDelay()
        >
      Your message has been successfully submitted and would be delivered to recipients shortly.