PIC Interrupts vs. Polling

Program Download:

Main C File
LED_Interrupt.c
LED_Interrupt.hex

The Software
           There are two main portions of code that we are concerned with:
    -Main Loop
    -Interrupt Routine



           The first part of the software is the main loop which is a 'knight rider' single led that goes back and forth on the LED bar. The second section of the code is the interrupt service routine that actives when a hardware interrupt is detected.

Main Loop

------------« Begin Code »------------
#include <p18f452.h>
#include <delays.h>
void InterruptHandlerHigh (void);
void main(void){
unsigned int led_cnt = 0;
unsigned int direction = 0;
TRISC = 0x00;
TRISD = 0x00;
                     //Setup Interrupts
INTCON = 0b10010000;
INTCON2 = 0b00000000;
     while(1){
          Delay10KTCYx(33);
          switch(led_cnt){
          case 0 : PORTC = 0x01;
                     PORTD = 0x00;
                     break;
          case 1 : PORTC = 0x02;
                     PORTD = 0x00;
                     break;
          case 2 : PORTC = 0x04;
                     PORTD = 0x00;
                     break;
          case 3 : PORTC = 0x08;
                     PORTD = 0x00;
                     break;
          case 4 : PORTC = 0x00;
                     PORTD = 0x01;
                     break;
          case 5 : PORTC = 0x00;
                     PORTD = 0x02;
                     break;
          case 6 : PORTC = 0x00;
                    PORTD = 0x04;
                     break;
          case 7 : PORTC = 0x00;
                    PORTD = 0x08;
                     break;
          case 8 : PORTC = 0x10;
                    PORTD = 0x00;
                     break;
          case 9 : PORTC = 0x20;
                    PORTD = 0x00;
                     break;
          default : PORTC = 0x00;
                    PORTD = 0x00;
                     break;
          }
          if(direction == 0)
               led_cnt++;
          else
               led_cnt--;
          if(led_cnt == 10){
               led_cnt = 9;
               direction = 1;
          }
          else if(led_cnt == -1){
               led_cnt = 0;
               direction = 0;
          }
     }
}
------------« End Code »------------

           Using a counter and direction and some math, a control loop is formed that makes a single led bit move back and forth on the LED bar (PORTC and PORTD). The interrupt is setup at the very beginning to get everything ready. INTCON and INTCON2 are the main interrupt registers used.

Interrupt Service Routine

------------« Begin Code »------------
//**BEGIN INTERRUPT CONTROL**
#pragma code InterruptVectorHigh = 0x08 //interrupt pointer address (0x08 high priority)
void InterruptVectorHigh (void)
{
    _asm        //assembly code starts
    goto InterruptHandlerHigh //interrupt control
    _endasm         //assembly code ends
}
#pragma code
#pragma interrupt InterruptHandlerHigh //end interrupt control
//**END INTERRUPT CONTROL**
unsigned int i = 0;
void InterruptHandlerHigh() // Declaration of InterruptHandler
{
  if(INTCONbits.INT0IF){ //if INT0IF interrupt flag is set
  PORTC = 0x00;
  PORTD = 0x00;
  for(i=0;i<2;i++){
      Delay10KTCYx(50);
      PORTC = 0x00;
      PORTD = 0x00;
      Delay10KTCYx(50);
      PORTC = 0x3F;
      PORTD = 0x0F;
    }
  INTCONbits.INT0IF = 0; //Clear INT0IF Flag
  }
  INTCONbits.GIE = 1; //Re-enable all interrupts
return;
}
------------« End Code »------------

           The interrupt service routine occurs when a hardware interrupt is detected. Then the PIC looks at the interrupt vector 0x08 and follows the goto that leads to the InterruptHandlerHigh() function. This function executes and then interrupt flags are cleared and re-enabled. Then the program returns to the exact same state it was when main was looping forever.



;