Chapter 7 – RB0/INT Interrupt

The RB0 pin (or RB0/INT) can trigger an interrupt when it detects a signal transition event. A signal transition can either be a falling edge (+5V to 0V transition) or a rising edge (0V to +5V transition). Two special function registers are associated with RB0/INT interrupt operation: INTCON and OPTION. As mentioned previously, the INTCON’s INTE and INTF bits are named as the RB0 Interrupt Enable and Flag bits, respectively. As for the OPTION register (below), only its INTEDG bit (RB0 Interrupt Edge Select) affects RB0 interrupt. This bit determines which signal transition will generate an interrupt. If INTEDG is set (and GIE and INTE are also set), a rising edge signal transition set the INTF flag (and trigger an interrupt); otherwise, a falling edge will set the INTF. INTEDG is a read/write bit, and it defaults to ‘1’ during a device reset.

option register Chapter 7   RB0/INT Interrupt

Figure 7.3 The OPTION register. Only the INTEDG bit affect RB0/INT interrupt operation

To demonstrate, we will now create our first RB0/INT interrupt application. In the application circuit, a button switch is connected to the RB0/INT pin, which is configured as an interrupt source. An LED is also connected to another pin. When the button is pressed (as the application is running), the RB0/INT pin will detect the signal transition, set the INF flag bit, and triggers an interrupt. The ISR is executed, which contains the statement to toggle the status of the LED.


// HARDWARE:
// - PIC16F84A with 4MHz crystal Oscillator
//   - LED --> RA1 pin
//   - Button --> RB0 pin

#include <htc.h>

/* Configuration bits */
__CONFIG(FOSC_XT && WDTE_OFF && PWRTE_OFF && CP_OFF);

//------------------------------------------------------------------------------

/* Macro */
#define LED       RA1
#define LED_TRIS  TRISA1

#define TOGGLE 1
#define OFF    0

//------------------------------------------------------------------------------

/* Interrupt Service Routine */
void interrupt isr_RB0(void)
{
  LED ^= TOGGLE;                     //Toggle LED.
  INTF = 0;                          //Clear RB0 interrupt flag.
  return;
}

//------------------------------------------------------------------------------

void main()
{
  /* Initialize RB0/INT pin interrupt. */
  INTEDG = 1; //RB0 will detect the falling edge of the signal
  INTF = 0; //Clear RB0 interrupt flag
  INTE = 1; //Eable RB0 interrupt
  GIE = 1; //Eable interrupt

  LED_TRIS = 0; //LED
  LED = 0;

  while(1)
  {
    //Do nothing but wait for interrupt to occur
    // then execute the ISR.
  }
}

Assemble the hardware, build the project, program the microcontroller, and run the application. When you press the button, the LED is toggled.

Let’s dissect the code line by line below.

Line 35:

Again, when you clear the INTEDG bit, the RB0/INT pin is configured to detect the falling edge of an input signal. Remember that when the button is idle, the RB0/INT pin is at high logic level since it is pulled up by the resistor to VDD. But when you press the button, an [almost] instantaneous VDD-to-0V transition occurs since the RB0/INT is shorted to ground. The internal circuitry of the RB0/INT pin will detect the signal transition, sets the INTF bit, and asserts the interrupt line to the CPU.

Line 36:

You need to clear the INTF bit just before enabling the interrupt. This is a usual precaution to prevent false triggering of the RB0/INT interrupt immediately following initialization. Each time RB0/INT detects a signal transition event, INTF is automatically set by the hardware. INTF should be cleared by software, usually within the ISR.

Line 37:

The INTE bit is set to enable RB0/INT as an interrupt source.

Line 38:

You set the GIE to enable the interrupt operation. You may think of the GIE as the on/off switch of the PIC16 interrupt logic circuitry.

Line 43-47:

The program loop is empty. The program loops around doing nothing, and it simply waits for the RB0/INT interrupt to trigger.

Line 23-28:

This is the definition of the interrupt service routine. The ISR, as appearing in our code, is a special function that has the interrupt keyword in the function header. The name of the ISR can be any valid (and descriptive) name. Personally, I prefer to add an isr pre-/postfix to the name of the ISR, for obvious reason. Unlike other user-defined C functions, the ISR is invoked by the hardware, and not through any function call statements within the application program. Also, the ISR cannot accept any parameter, or return any value.

In the example, the ISR is automatically executed each time the RB0/INT interrupt is triggered, and it can happen at any point during the program execution after the interrupt is enabled. To be precise, if both GIE and INTE are set, the ISR is executed each time the INTF is set – i.e., a signal transition event is detected at RB0/INT pin. Note also that a PIC16 application program can only have one definition of the ISR. The ISR will be discussed in depth later in the chapter.

Line 25:

The first statement inside the ISR will toggle the LED.

Line 27:

Before exiting from the ISR, you need to clear INTF bit to prepare for the next occurrence of the RB0/INT interrupt. If you fail to include this statement, the ISR will restart execution immediately after exiting, and the CPU never returns to the main program flow. Thus, the application becomes unresponsive.

As an additional exercise, you may modify the previous application code. Try setting the INTEDG bit in the initialization part of main(). As previously mentioned, if INTEDG is set, a rising edge transition at the RB0/INT pin will trigger an interrupt. When you run the application, you will observe that the LED will toggle only after you release the button switch. In contrast, if INTEDG is cleared, the LED will toggle immediately when you pressed down the button.

No comments yet.

Leave a Reply


*