We have already seen External Interrupt, Serial, Timer Interrupts in our previous tutorial. In this tutorial we are going to see How to use Multiple External Interrupts in PIC16F877A.
Post Contents
Interrupts in PIC16F877A
As the name suggests Interrupts are special events that requires immediate attention, it stops a microcontroller/microprocessor from the running task and to serve a special task known as Interrupt Service Routine (ISR) or Interrupt Handler.
PIC 16F877A has the following 15 interrupt sources :
- External
- Timer 0
- Timer 1
- RB Port Change
- Parallel Slave Port Read/Write
- A/D Converter
- USART Receive
- USART Transmit
- Synchronous Serial Port
- CCP1 (Capture, Compare, PWM)
- CCP2 (Capture, Compare, PWM)
- TMR2 to PR2 Match
- Comparator
- EEPROM Write Operation
- Bus Collision
As we know already, we have only one external interrupt which is in PortB.0. For example in my project i need to use many external interrupts. How to use many since we have only one in PORTB.0. So In this tutorial we will see How to use Multiple External Interrupts in PIC16F877A.
PORTB Interrupt in PIC16F877A
In PIC16F877A we have one interrupt which is PORTB change interrupt. This Interrupt is used to identify the Port change in PORTB. This will monitor only the PORTB.4, PORTB.5, PORTB.6 and PORTB.7. So first we will see this PORTB change interrupt. For this you have to familiar about the interrupt register available in PIC16F877A. We’ve already discussed about those registers. You can refresh here.
Steps to be followed
- Enable PORTB Change Interrupt.
- Connect external Interrupts pins to RB4, RB5, RB6 and RB7 (PORTB.4 – PORTB.7).
- Whenever anyone of the RB4, RB5, RB6, RB7 state changes, ISR will hit.
- In ISR you should read the PORTB register. Then only it will clears the PORTB interrupt.
Source Code
Whenever anyone of the RB4, RB5, RB6, RB7 state changes, Interrupt will happen. In ISR I am toggling the LED in PORTD.
//PORTB Interrupt #include<pic.h> #define delay for(i=0; i<= 50000; i++) #define LED PORTD unsigned int i; void interrupt ISR(void) { unsigned char temp_PORTB = PORTB; LED = 0xff; delay; LED=0x00; RBIF=0; } void main(void) { /*Port B as a Input */ TRISB0=0xFF; /*Port D as a Output */ TRISD=0; LED=0; /* Register PORTB interrupt */ OPTION_REG |= 0b00000000; INTCON |= 0b10011000; while(1) { } }
Output
[ Please find the output image Here ]
Multiple External Interrupts in PIC16F877A
Steps to be followed
- Before Initializing the Interrupt first store the PORTB value into one variable.
- Enable PORTB Change Interrupt.
- Connect external Interrupts pins to RB4, RB5, RB6 and RB7 (PORTB.4 – PORTB.7).
- Whenever ISR hits, you need to read PORTB value and compare with old PORTB value using XOR method.
- Then you will get the new value and then using OR operator you can find the exact pin interrupted.
Source Code
In this source, whenever PORTB.4 – PORTB.7 changes, I’ve blink the respected LED connected in PORTD.
//Multiple Externel Interrupt #include<pic.h> #define delay for(i=0; i<= 50000; i++) #define LED PORTD #define PORTB_4 (1<<4) #define PORTB_5 (1<<5) #define PORTB_6 (1<<6) #define PORTB_7 (1<<7) unsigned char old_PORTB = 0; unsigned int i; void interrupt ISR(void) { unsigned char key_pressed; unsigned char new_PORTB = PORTB; key_pressed = old_PORTB ^ new_PORTB; if(key_pressed & PORTB_4) { LED = PORTB_4; } else if(key_pressed & PORTB_5) { LED = PORTB_5; } else if(key_pressed & PORTB_6) { LED = PORTB_6; } else if(key_pressed & PORTB_7) { LED = PORTB_7; } else { //junk interrupt } delay; RBIF=0; } void main(void) { /*Port B as a Input */ TRISB0=0xFF; /*Port D as a Output */ TRISD=0; LED=0; /*Storing Original PORTB value*/ old_PORTB = PORTB; /* Register PORTB interrupt */ OPTION_REG |= 0b00000000; INTCON |= 0b10011000; while(1) { LED=0x00; } }
Output
[ Please find the output image Here ]
So now we have 5 external interrupts including PORTB.0 interrupt. You can play with it.