Understanding Interrupts in PIC Microcontrollers

Using interrupts is a must in a professional microcontroller program. Basicly, when an event has occured, an interrupt flag will be set and program will branch to the interrupt address. By this method, you don’t need to wait an event in a loop. Interrupts can occur on port change, timer overflow, USART(serial) communication, etc.

interrupt

You will find a PORTB change interrupt example in the following part of this article.
For Timer0 (TMR0) overflow interrupt, check Timing – Timers page.
For USART (Serial Communication – RS232) interrupt, check Serial Communication page.

The interrupt address locates on 0×04 of program memory. At the beginning of our assembly code, we will point this address to a label.

ORG 0×00 ;On reset or power-up, program will branch here
GOTO main
ORG 0×04 ;On interrupt program will branch here
GOTO interruptmain:.instruction
.instruction
.instruction

.

interrupt:
.instruction
.instruction
.

END

When an interrupt occured, program will branch to the interrupt label. Note that, “main” and “interrupt” names are given by us. You can change label names, they are not meaningful for the compiler.

And also, when an interrupt has occured, an interrupt flag will be set. This flags located in INTCON and PIR registers.

Configuring interrupts

To use interrupts, we need to configure them first. There are some special registers (INTCON, PIE, PIR) that control interrupts.

INTCON Register :

INTCON is general interrupt control register. It contains interrupt configuration bits and interrupt result flags.

INTCON

bit 7 <GIE> : Global interrupt enable bit

1 : Enable unmasked interrupts
0 : Disable interrupts

bit 6 <PEIE> : Peripheral interrupt enable bit

1 : Enable unmasked peripheral interrupts
0 : Disable all peripheral interrupts

bit 5 <T0IE> : Timer0 overflow interrupt bit

1 : Enable TMR0 interrupt
0 : Disable TMR0 interrupt

bit 4 <INTE> : RB0/INT external interrupt enable bit

1 : Enable the RB0/INT external interrupt
0 : Disable the RB0/INT external interrupt

bit 3 <RBIE> : RB Port change interrupt enable bit

1 : Enable the RB port change interrupt
0 : Disable the RB port change interrupt

bit 2 <T0IF> : TMR0 overflow interrupt flag bit

1 : TMR0 register has overflowed(must be cleared in software)
0 : TMR0 register did not overflow

bit 1 <INTF> : RB0/INT external interrupt flag bit

1 : The RB0/INT external interrupt occured (must be cleared in software)
0 : The RB0/INT external interrupt did not occured

bit 0 <RBIF> : RB port change interrupt flag bit

1 : When at least one of the RB7:RB4 pins changed state (must be cleared in software)
0 : None of the RB7:RB4 pins changed state

As you can see, several interupts can be controlled by using this register. Disabling an interrupt is called as masking. Non-used interrupts should be masked. Otherwise, they will cause unnecessary branchings to the interrupt label.

An example : Let’s write a code which gets PORTB change. When PORTB changes it will turn-on and turn-off a LED which is connected to PORTA.0.

ORG 0×00
GOTO main
ORG 0×04
GOTO interrupt

main:
BSF STATUS,RP0 ;BANK1
MOVLW h’FF’ ;binary = 11111111
MOVWF TRISB ;All bits as input
CLRF TRISA ;All bits as output
BCF STATUS,RP0 ;BANK0
MOVLW b’00001000′ ;Prepare configuration byte
MOVWF INTCON ;Mask all interrupts except PORTB change
BSF INTCON,GIE ;Start general interrupts
LOOP: ;Continous loop
GOTO LOOP

interrupt:
BTFSS INTCON,RBIF ;Test if PORTB-change caused the interrupt
GOTO exit_int ;If not exit from the interrupt routine
MOVLW b’00000001′ ;
XORWF PORTA,F ;Blink LED
BCF INTCON,RBIF ;We should clear RBIF flag to enable it again
exit_int: ;exit interrupt label
RETFIE ;Enable general interrupts and return

END

The PORTB<7:4> change interrupt is affected by change state on any of the PORTB bits between 4 and 7. When these bits change states, the RBIF bit of INTCON register will be set and program will flow to interrupt routine (label). With the RETFIE instruction program will flow back where it has branched to interrupt routine.

PORTB has two different interrupts. One of them is PORTB change interrupt. The other one is RB0/INT pin interrupt. We used PORTB change interrupt in the example.

RB0 interrupt

RB0/INT interrupt is affected by rising and falling transition on PORTB bit0. Transition can be configured from OPTION register INTEDG bit. Setting INTEDG bit to ’1′ will activate rising edge, to ’0′ will activate falling edge transition. This bit is adaptable for serial communications.

RB0interrupt

Timer0 overflow interrupt

Timer0 overflow interrrupt can be configured and read from INTCON register. You can find how to use Timer0 interrupt from Timer Interrupts page.

Peripheral interrupts

Peripheral interrupts contains internal EEPROM, Serial Communication (USART, SPI/I2C), timers, analog/digital converting,etc.

Peripheral interrupts are configured by using PIE1 registers. (In some microcontrollers there is also PIE2.) The INTCON register has one bit which is called as PIE, to enable/disable all unmasked peripherals.

PIE1 :

bit 7 <EEIE> : EEPROM write complete interrupt

1 : Enables the EE write complete interrupt
0 : Disables the EE write complete interrupt

bit 6 <CMIE> : Comparator interrupt enable bit

1 : Enables the comparator interrupt
0 : Disables the comparator interrupt

bit 5 <RCIE> : USART receive interrupt enable bit

1 : Enables the USART receive interrupt
0 : Disables the USART receive interrupt

bit 4 <TXIE> : USART transmit interrupt enable bit

1 : Enables the USART transmit interrupt
0 : Disables the USART transmit interrupt

bit 3 <Unimplemented> : Read as ’0′

bit 2 <CCP1IE> : CCP1 (capture/compare/pwm)int. enable

1 : Enables the CCP1 interrupt
0 : Disables the CCP1 interrupt

bit 1 <TMR2IE> : TMR2 to PR2 match interrupt enable bit

1 : Enables the TMR2 to PR2 match interrupt
0 : Disables the TMR2 to PR2 match interrupt

bit 0 <TMR1IE> : TMR1 overflow interrupt enable bit

1 : Enables the TMR1 overflow interrupt
0 : Disables the TMR1 overflow interrupt

The peripheral interrupt flags are in PIR1, peripheral interrupt register. (Again in some microcontrollers there is also PIR2 register.)

PIR1 :

bit 7 <EEIF> : EEPROM write operation interrupt flag bit

1 : The write operation completed (must be cleared in software)
0 : The write operation has not completed or has not been started

bit 6 <CMIF> : Comparator interrupt flag bit

1 : Comparator output has changed
0 : Comparator output has not changed

bit 5 <RCIF> : USART receive interrupt flag bit

1 : USART receive buffer is full
0 : USART receive buffer is empty

bit 4 <TXIF> : USART transmit interrupt flag bit

1 : USART transmit buffer is full
0 : USART transmit buffer is empty

bit 3 <Unimplemented> : Read as ’0′

bit 2 <CCP1IF> : CCP1 interrupt flag bit(capture/compare)

1 : TMR1 register capture occured (must be cleared in software)
0 : TMR1 register capture did not occur

 

1 : TMR1 register compare occured (must be cleared in software)
0 : TMR1 register compare did not occur

bit 1 <TMR2IF> : TMR2 to PR2 match interrupt flag bit

1 : TMR2 to PR2 match occured (must be cleared in software)
0 : TMR2 to PR2 match did not occur

bit 0 <TMR1IF> : TMR1 overflow interrupt flag bit

1 : TMR1 overflowed (must be cleared in software)
0 : TMR1 did not overflow

We discussed general interrupts so far. Later, we will study details such as timers, eeprom, serial communication.

Share and Enjoy

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Reddit
  • Add to favorites
  • Email
  • RSS

Leave a Reply