In this section, I wish to introduce about PortB interrupt on change of PIC16F887. If you wish to see about interrupt concept click here.
Beside external interrupt (INT) of at RB0, PortB could trigger an interrupt at any pin from RB0 to RB7.
This's called PortB interrupt on change (IOCB).
You can you any pin of PortB to trigger an interrupt, or all of them.
To program the interrupt on change, we need to work with some register in the SFR.
- PORTB and TRISB
- ANSELH
- OPTION_REG (Optional)
- INTCON
- IOCB
- WPUB (Optional)
First step, we need to set PortB as digital input.
In the INTCON set the RBIE to '1' enabling the PortB interrupt on change.
BIT 7 | BIT 0 | ||||||
GIE | PEIE | T0IE | INTE | RBIE | T0IF | INTF | RBIF |
Setting any bit of the IOCB (interrupt on change port B register) to enable the specific interrupt on change pin.
BIT 7 | BIT 0 | ||||||
IOCB7 | IOCB6 | IOCB5 | IOCB4 | IOCB3 | IOCB2 | IOCB1 | IOCB0 |
In the ISR, check to RBIF to identify the Port B interrupt on change. To check for any pin change, test the RB pin one by one.
#include<xc.h>
// PIC16F887 Configuration Bit Settings
// CONFIG1
#pragma config FOSC = XT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = ON
#pragma config FCMEN = ON
#pragma config LVP = ON
// CONFIG2
#pragma config BOR4V = BOR40V
#pragma config WRT = OFF
/*Interrupt service routine*/
void interrupt _ISR(void){
/*looking for portB interrupt
on change by checking RBIF*/
if(RBIF){
/*Test individual pin*/
if(RB0==0) RD0^=1;
if(RB1==0) RD1^=1;
if(RB2==0) RD2^=1;
if(RB3==0) RD3^=1;
if(RB4==0) RD4^=1;
if(RB5==0) RD5^=1;
if(RB6==0) RD6^=1;
if(RB7==0) RD7^=1;
RBIF=0;
}
}
void main(){
/*clear PortB*/
PORTB=0x00;
/*clear PortD*/
PORTD=0x00;
/*PortD as output*/
TRISD=0x00;
/*PortB as input*/
TRISB=0xFF;
/*disable all analog input of portB*/
ANSELH=0;
/*turn on global weak pull up*/
nRBPU=0;
/*Turn on all pull up resistor of portB*/
WPUB=0xFF;
/*enable portB interrupt on change
of all pins*/
IOCB=0xFF;
RBIE=1;
/*enable global interrupt*/
GIE=1;
/*program main loop does nothing
our could be anythings*/
while(1);
}
I took a screen shot of the running program.
screen shot of the running program Any pin of PortD toggle due to the corresponding interrupt on change of PortB. |
No comments:
Post a Comment