Line 15: Line 15:
 
#First it finishes the instruction it is executing and saves the address of the next instruction (PC) on the stack.
 
#First it finishes the instruction it is executing and saves the address of the next instruction (PC) on the stack.
 
#It also saves the current status of all the interrupts internally.
 
#It also saves the current status of all the interrupts internally.
#It jumps to a fixed location in memory, called the interrupt vector table, that holds the address of the ISR.
+
#It jumps to a fixed location in memory, called the interrupt vector table, that holds the address of the ISR. The microcontroller gets the address of the ISR from the interrupt vector table and jumps to it It starts to execute the interrupt service subroutine until it reaches the last instruction of the subroutine which is RETI (return from interrupt)
The microcontroller gets the address of the ISR from the interrupt vector table and jumps to it It starts to execute the interrupt service subroutine until it reaches the last instruction of the subroutine which is RETI (return from interrupt)
+
 
#Upon executing the RETI instruction, the microcontroller returns to the place where it was interrupted.
 
#Upon executing the RETI instruction, the microcontroller returns to the place where it was interrupted.
 
#First, it gets the program counter (PC) address from the stack by popping the top two bytes of the stack into the PC.
 
#First, it gets the program counter (PC) address from the stack by popping the top two bytes of the stack into the PC.

Revision as of 12:00, 24 August 2016

In this tutorial, we will look at 8051 Interrupts. Interrupts are useful in many cases wherein the process simply wants to continue doing its main job and other units(timers or external events) seek its attention when required. In other words, the microcontroller, need not monitor the timers, the serial communication or the external pins P3.2 and P3.3. Whenever an event related to these units occur, it is informed to the microcontroller with the help of interrupts.

A single microcontroller can serve several devices by two ways:

  • Polling: The microcontroller continuously monitors the status of all the devices. Whenever any device needs the service,it provides the service and moves on to the next device until everyone is serviced. This will be done in an infinite loop.
  • Interrupts: Whenever any device needs its service, the device notifies the microcontroller by sending it an interrupt signal Upon receiving an interrupt signal, the microcontroller interrupts whatever it is doing and serves the device. The program which is associated with the interrupt is called the interrupt service routine (ISR) or interrupt handler


What is an Interrupt?

An interrupt is an external or internal event to get the CPU's attention. Once the controller detects the interrupt, it suspends the current job and executes a special service routine know as Interrupt Service Routine(ISR).

Upon activation of an interrupt, the microcontroller goes through the following steps

  1. First it finishes the instruction it is executing and saves the address of the next instruction (PC) on the stack.
  2. It also saves the current status of all the interrupts internally.
  3. It jumps to a fixed location in memory, called the interrupt vector table, that holds the address of the ISR. The microcontroller gets the address of the ISR from the interrupt vector table and jumps to it It starts to execute the interrupt service subroutine until it reaches the last instruction of the subroutine which is RETI (return from interrupt)
  4. Upon executing the RETI instruction, the microcontroller returns to the place where it was interrupted.
  5. First, it gets the program counter (PC) address from the stack by popping the top two bytes of the stack into the PC.
  6. Then it starts to execute from that address.

Video Tutorial

Basics

Interrupt sources for 8051

08051 Interrupts.png For the 8051 Microcontroller there are six interrupt sources as shown in the table below: }}

Table. 1: Interrupt Vector Table
Interrupt ROM Location(Hex) Pin Flag Clearing Interrupt no. in C
Reset 0000 9 Auto --
External HW Interrupt 0 (INT0) 0003 P3.2(12) Auto 0
Timer 0 Interrupt(TF0) 000B - Auto 1
External HW Interrupt 1 (INT1) 0013 P3.3(13) Auto 2
Timer 1 Interrupt(TF1) 001B - Auto 3
Serial Com Interrupt(RI and TI) 0023 - Program SW 4

As seen in the above table,

  • the reset vector has just 3 bytes allocated to it, meaning it can hold a jump instruction to the location where the main program is stored.
  • The other interrupts have 8 bytes allocated to each of them, hence a small Interrupt service routine(ISR) can be placed here. However, if the ISR needs to larger in length, it has to placed else where and the allocated 8 bytes need to have the code that simple redirects the control to the ISR.
  • INT0 and INT1 are external interrupts on P3.2 and P3.3 respectively. These can be configured to be low level triggered or edge triggered interrupt sources.
  • TF0 and TF1 are timer overflow interrupts for timer 0 and 1 respectively
  • The Serial COM Interrupt can be configured to trigger upon transmit or receipt of a byte during serial communication.

Enabling and Disabling the Interrupts

It should be noted that when the MCU is reset, all the interrupts are disabled. Hence in order to use them, we should enable them. In 8051 Interrupt Enable(EA) Register is used to enable or disable the interrupt. The register is shown below:

EA
D7 D6 D5 D4 D3 D2 D1 D0
EA - ET2 ES ET1 EX1 ET0 EX0

<br\>

  • EA: 0;Disables all interrupts. 1;Enables all interrupts. It is kind of master control, before enabling any of the interrupts this bit should be 1. For all the below interrupts, setting(1) the bit enables the interrupt, 0 disables it.
  • ET2: Timer 2 Overflow interrupt(8052)
  • ES:Serial Port Interrupt
  • ET1:Timer 1 overflow interrupt
  • EX1:External Interrupt 1 on P3.3
  • ET0:Timer 0 overflow interrupt
  • EX0:External Interrupt 0 on P3.2

Example 1: Timer Interrupts

To demonstrate use of timer interrupts, we will blink a LED connected to P3.7 at 50ms(using timer zero) and in the mean time we would also read the SW connected to P3.2 and display on LED connected to P3.6.
Important thing to understand here is, in the main program, the switch is continuous read and displayed on the led, the timer keeps ticking on its own and when it over follows the led connected to P3.7 is toggled.

In real time we should be able to see the LED connected to P3.7 blink continuously and also switch status shown on LED P3.6.

#include<reg51.h>
sbit Led1 =  P3^6; // will show switch status(inverted)
sbit Led2 =  P3^7; // this will be blinking every at 50ms
sbit SW1 = P3^2;
void timer0() interrupt 1
{
  Led2 = ~Led2;
 
  //reload the timer
  TH0 = 0X4b;
  TL0 = 0Xff; 
}
void main()
{
  TMOD = 0X01; //Timer 0 mode 1; 16 bit timer
  TH0 = 0X4b;
  TL0 = 0Xff;
  IE = 0x82; //Enable Interrupts
  SW1 = 1; //make switch as input
  TR0 = 1; //turn on timer
  P3 = 0x0F;//turning off both leds
 
  while(1)
  {
    Led1 = SW1;
  }
 
}

Example 2: External Interrupts

In this example the main program does nothing, whereas when an low signal interrupt is received on P3.2(INT0) we turn on Led1(P3.6) and when interrupt occurs on P3.3(INT1) we turn on Led2(P3.7). Note that two switches are connected to the two pins as shown in the schematic.

#include<reg51.h>
sbit Led1 =  P3^6; 
sbit Led2 =  P3^7; 
sbit SW1 = P3^2;
sbit SW2 = P3^3;
void ext_int_0 () interrupt 0 
{ 
    Led1 = 1; 
} 
void ext_int_1 () interrupt 2 
{ 
   Led2 = 1;
}
void main()
{
   P3 = 0X0F; //leds output, switches input
   EA = 1;
   EX0 = 1;
   EX1 =1;
 
   while(1)
   {
     Led1 = 0;
  Led2 = 0;
 //you could add any other code here as well
   }
}

Schematic

Schematic

8051Interupt.JPG