Introduction
Port B of PIC16F887 is individually able to trigger interrupt signal to the controller. It's called INTERRUPT-ON-CHANGE. It also cover the external interrupt on RB0. However this interrupt source comes with most of new version of PIC microcontroller.
There are some registers relate to this interrupt source, IOCB, and INTCON.
Interrupt Control Register - INTCON
This register contains control and flag bit of interrupt-on-change.
|  | 
| Interrupt Control Register (INTCON) | 
Set the Global Interrupt Enable bit (GIE) to turn on interrupt for PIC16F887 microcontroller. Bit 3 is called PORTB Change Interrupt Enable bit (RBIE). This bit must be set to turn on the PortB-Interrupt-On-Change. RBIF is PORTB Change Interrupt Flag bit. In the ISR the program must test this bit for its interrupt request.
Interrupt-On-Change PORTB Register - IOCB
This 8-bit wide special function register configures the present of PortB-Interrupt-On-Change.
|  | 
| Interrupt-On-Change PortB Register - IOCB | 
IOCB of PIC16F887 Programming in MikroC
Introduction 
There are some more register to make this programming work well. Port B weak pull up resistors must be turned on to save component counts. This job will be done with the OPTION_REGand the WBPU register.
Its internal oscillator with a frequency of 8MHz could fit this simple task. Program will need to configure the OSCCON register to select its 8MHz internal oscillator.
Unlike external interrupt, this interrupt source doesn't have edge selection control bit. Its interrupt flag RBIF is set at the instance of port reading mismatch the previous port value.
Hardware
I made its schematic in Proteus due to its ease of design.
|  | 
| Schematic Diagram | 
SW1 connects to RB7 creates interrupt when it's pressed (shorted to ground). D1 toggles each time the interrupt occurs.
Programming in MikroC
The controller is configured to clock from its internal 8MHz oscillator. Port B input doesn't need external pull up resistor since it's internally connected to its weak pull up resistor by software.
Interrupt-On-Change occurs when the input logic to RB7 change from high to low.
void interrupt() {
if(INTCON.RBIF)
if(PORTB.RB7==0) // check if RB7 is shorted to GND
PORTB.RB0^=1;
INTCON.RBIF=0;
}
void main() {
PORTB=0x00; // CLEAR PORTB
TRISB=0x80; // RB7 IS INPUT
ANSELH=0x00; // DISABLE ALL ANALOG FUNCTION
OPTION_REG.F7=0; // ENABLE WPUB
WPUB=0x80; // TURN ON WPUB FOR RB7
OSCCON|=0x70; // SELECT INTRCIO 8MHz
INTCON.GIE=1; // TURN ON GLOBAL INTERRUPT
INTCON.RBIE=1; // TURN ON IOCB
IOCB=0x80; // RB7 IS USE TO CREATE INTERRUPT
INTCON.RBIF=0; // CLEAR INTERRUPT FLAG
while(1); // STAY HERE
}
Both MikroC and Proteus simulation were recorded in this video.
