Interrupt handling in 8051 is very simple. To learn interrupts handling in 8051 microcontroller; first of all we must understand what different types of interrupts available in 8051 microcontroller.
Types of interrupts in 8051
- External hardware interrupt – INT0
- External hardware interrupt – INT1
- Timer 0 overflow interrupt – TF0
- Timer 1 overflow interrupt – TF1
- Serial communication interrupt – RI/TI
Timer and serial interrupts are internally generated by the inbuilt timer and USART peripherals modules.
External interrupts are generated by external interfacing devices such as Switches, number pad, RTC etc.
When interrupt occurs, microcontroller first finishes the instruction which it is executing and then jumps to the memory location corresponding to the interrupt. This memory location is also known as interrupt vector. 8051 microcontroller have fixed interrupt vectors for each interrupt as shown in below table.
|Interrupt number||Description||Memory Address|
|0||External hardware interrupt INT0||0003h|
|1||Timer/Counter 0 interrupt||000Bh|
|2||External hardware interrupt INT1||0013h|
|3||Timer/Counter 1 interrupt||001Bh|
|4||Serial communication interrupt||0023h|
In 8051, each interrupt can have either high priority or low priority. Priority level of interrupt can be set to high by setting corresponding bit in Interrupt Priority (IP) resister or it can be set to low by clearing corresponding bit in IP register.
|(MSB) IP.7||IP.6||IP.5||IP.4||IP.3||IP.2||IP.1||(LSB) IP.0|
|Direct Address B8H||–||–||PT2||PS||PT1||PX1||PT0||PX0|
|Bit 5: PT2||0: Low priority for Timer 2 interrupt|
1: High priority for Timer 2 interrupt
|Bit 4: PS||0: Low priority for Serial interrupt|
1: High priority for Serial interrupt
|Bit 3: PT1||0: Low priority for Timer 1 interrupt|
1: High priority for Timer 1 interrupt
|Bit 2: PX1||0: Low priority for External interrupt INT1|
1: High priority for External interrupt INT1
|Bit 1: PT0||0: Low priority for Timer 0 interrupt|
1: High priority for Timer 0 interrupt
|Bit 0: PX0||0: Low priority for External interrupt INT0|
1: High priority for External interrupt INT0
If multiple interrupts of different priority level are received simultaneously then high priority interrupt is serviced first. If requests of the same priority level are received simultaneously, an internal polling sequence determines which request is to be serviced, Thus within each priority level is a second priority structure determined by the polling sequence. Polling sequence is shown in table below.
|Source||Priority within Level|
|1||External hardware interrupt INT0||Highest|
|2||Timer/Counter 0 interrupt|
|3||External hardware interrupt INT1|
|4||Timer/Counter 1 interrupt|
|5||Serial communication interrupt||Lowest|
Combination of IP register and polling sequence gives unique priorities to all 5 interrupts in 8051 microcontroller. If all bits in IP register are cleared then external interrupt INT0 will have highest priority, timer 0 will be next and serial communication interrupt will have lowest priority. If multiple interrupts are triggered at same time, then the interrupts are serviced according to priority. For instance, if external hardware interrupt INT1 and external hardware interrupt INT0 are triggered at exactly same time, then external hardware interrupt INT0 will be serviced first.
Upon reset, all interrupts are disabled (masked), meaning that none will be responded to by the microcontroller if they are activated. The interrupts must be enabled by software in order for the microcontroller to respond to them. There is a register called IE (interrupt enable) that is responsible for enabling (unmasking) and disabling (masking) the interrupts.
In 8051 microcontroller, interrupts can be enabled or disabled by setting or clearing corresponding bits in Interrupt Enable (IE) Register. Also all interrupts can be enabled or disabled globally using EA bit in IE register.
|(MSB) IE.7||IE.6||IE.5||IE.4||IE.3||IE.2||IE.1||(LSB) IE.0|
|Direct Address A8H||EA||–||ET2||ES||ET1||EX1||ET0||EX0|
|Bit 7: EA||0: Disable all interrupts|
1: Enable all interrupts according to individual enable bits
|Bit 5: ET2||0: Disable Timer 2 interrupt|
1: Enable Timer 2 interrupt
|Bit 4: ES||0: Disable Serial interrupt|
1: Enable Serial interrupt
|Bit 3: ET1||0: Disable Timer 1 interrupt|
1: Enable Timer 1 interrupt
|Bit 2: EX1||0: Disable External interrupt INT1|
1: Enable External interrupt INT1
|Bit 1: ET0||0: Disable Timer 0 interrupt|
1: Enable Timer 0 interrupt
|Bit 0: EX0||0: Disable External interrupt INT0|
1: Enable External interrupt INT0
Timer Control Register (TCON):
|(MSB) TCON.7||TCON.6||TCON.5||TCON.4||TCON.3||TCON.2||TCON.1||(LSB) TCON.0|
|Direct Address 88H||TF1||TR1||TF0||TR0||IE1||IT1||IE0||IT0|
|Bit 7: TF1||Timer 1 overflow bit set by controller when timer 1 overflows.|
Cleared when processor vectors to execute interrupt service routine located at program address 001Bh.
|Bit 6: TR1||0: Turn Off Timer 1|
1: Turn On Timer 1
|Bit 5: TF0||Timer 0 overflow bit set by controller when timer 0 overflows.|
Cleared when processor vectors to execute interrupt service routine located at program address 000Bh.
|Bit 4: TR0||0: Turn Off Timer 0|
1: Turn On Timer 0
|Bit 3: IE1||External interrupt 1 Edge flag. Set to 1 when a high-to-low edge signal is received on port 3.3 (INT1).|
Cleared when processor vectors to interrupt service routine at program address 0013h. Not related to timer operations.
|Bit 2: IT1||0: External interrupt INT1 triggered on low level|
1: External interrupt INT1 triggered on falling edge
|Bit 1: IE0||External interrupt 0 Edge flag. Set to 1 when a high-to-low edge signal is received on port 3.2 (INT0).|
Cleared when processor vectors to interrupt service routine at program address 0003h. Not related to timer operations.
|Bit 0: IT0||0: External interrupt INT0 triggered on low level|
1: External interrupt INT0 triggered on falling edge
TF0 and TF1 bits of TCON register are set by controller when all bits of timer 0 or timer 1 roll over from 1 to 0. TF0 and TF1 bits can be polled to detect timer overflow event. These bits are automatically cleared when processor executes interrupt service routine (ISR) located at respective timer vector address.
TR0 and TR1 bits are used to run or stop timer 0 and timer 1 respectively.
IT0 and IT1 bits are used for external interrupts. External interrupt will be triggered on low level of signal if IT0/IT1 bit is set to 0. External interrupt will be triggered on falling edge of signal if IT0/IT1 is set to 1.
IE0 and IE1 bits are external interrupt flags. These bits are set to 1 if falling edge is received on external interrupt pins.
Interrupt flags (TF0, TF1, IE0, IE1) are set by controller when respective interrupt event is received and these bits are cleared automatically when respective ISR is executed by the controller. If interrupts are disabled and interrupt flags are polled through program, then program must take care of clearing respective flags.
Other Related Registers:
Timer 0 Registers – TH0 and TL0 are timer high byte and timer low byte. TH0 and TL0 are byte addressable registers. TH0 and TL0 together make a 16 bit timer register. Since 8051 is 8 bit controller; timer register accessed in two bytes, one byte for TH0 and one for TL0.
Timer 1 Registers – TH1 and TL1 are timer high byte and timer low byte. These are byte addressable registers.
Timer Mode Register (TMOD) – TMOD is used to set timer mode. 8051 controller supports 4 timer modes.
- 13 bit timer
- 16 bit timer
- 8-bit Auto reload
- Split timer mode
|(MSB) TMOD.7||TMOD.6||TMOD.5||TMOD.4||TMOD.3||TMOD.2||TMOD.1||(LSB) TMOD.0|
|Direct Address 89H||GATE1||C/T1||M1||M0||GATE0||C/T0||M1||M0|
|TMOD is not bit Address|
|Bit 7: GATE1||0: Timer 1 runs regardless of state of INT1|
1: Timer 1 runs when INT1 P3.3 is high
|Bit 6: C/T1||0: Timer 1 incremented every machine cycle|
1: Timer 1 incremented every falling edge on INT1 P3.3 (event counter)
|Bit 5: M1||Timer 1 Mode bits|
0 0 : Timer 1 mode 0 – 13 bit timer
0 1 : Timer 1 mode 1 – 16 bit timer
1 0 : Timer 1 mode 2 – 8 bit auto reload
1 1 : Timer 1 mode 3 – Spilt timer mode
|Bit 4: M0|
|Bit 3: GATE0||0: Timer 0 runs regardless of state of INT0|
1: Timer 0 runs when INT0 P3.2 is high
|Bit 2: C/T0||0: Timer 0 incremented every machine cycle|
1: Timer 0 incremented every falling edge on INT1 P3.3 (event counter)
|Bit 1: M0||Timer 0 Mode bits|
0 0 : Timer 0 mode 0 – 13 bit timer
0 1 : Timer 0 mode 1 – 16 bit timer
1 0 : Timer 0 mode 2 – 8 bit auto reload
1 1 : Timer 0 mode 3 – Spilt timer mode
|Bit 0: M1|
Serial Control Register (SCON) – SCON register is used for serial communication.
|(MSB) SCON.7||SCON.6||SCON.5||SCON.4||SCON.3||SCON.2||SCON.1||(LSB) SCON.0|
|Direct Address 98H||SM0||SM1||SM2||REN||TB8||RB8||TI||RI|
|TMOD is not bit Address||9F||9E||9D||9C||9B||9A||99||98|
|Bit 7: SM0||Serial mode select bits|
0 0 : mode 0 – Half duplex with fixed baud rate
0 1 : mode 1 – full duplex with variable baud rate (1 start bit, 8 data bits, 1 stop bit)
1 0 : mode 2 – full duplex 11 bit serial communication
1 1 : Mode 3 – Dull duplex with variable baud rate
|Bit 6: SM1|
|Bit 5: SM2|| Set to 0 in mode 0.|
Used to store stop bit in mode 1.
Used for multiprocessor communication in mode 2 and 3.
|Bit 4: REN||0: Disable serial communication|
1: Enable serial communication
|Bit 3: TB8||Used in mode 2 and 3|
|Bit 2: RB8||Used in mode 2 and 3|
|Bit 1: TI||Transmit interrupt flap set by microcontroller when one character transmission is complete.|
|Bit 0: RI||RI is Receive Interrupt flag, When 8051 receive data via RxD pin|
Serial Buffer (SBUF) – This register is used for transmitting or receiving data serially. We put data in it which we want to transmit, it also contains the data which is transmitted from other peripherals like personal computers (PC) to 8051 micro controller. It is not bit addressable.
Interrupt Handling in 8051
Most instructions in 8051 take 1 machine cycle to complete. Some instructions take 2 or 3 machine cycles. One machine cycle consists of 6 states S1 to S6 and every state has 2 pulses P1 and P2. So a machine cycle takes 12 pulses of clock to execute.
The interrupt flags are sampled at P2 of S5 of every instruction cycle. The samples are polled during next instruction cycle. If one of the flags was set at S5P2 of the preceding machine cycle, the polling detects it and the microcontroller generates interrupt by generating a long call (LCALL) to the appropriate vector address. When an equal or a higher priority interrupt is already being serviced then the microcontroller does not generate LCALL. While the instruction in progress is RETI or any write to IE or IP registers then the microcontroller does not generate LCALL. If interrupt is blocked because of above mentioned reasons then the interrupt will be serviced after removal of blocking conditions only if interrupt flap is still active.
When an interrupt occurs and the program is directed to the interrupt vector address, the Program Counter (PC) value of the interrupted program is stored (pushed) on the stack. The required Interrupt Service Routine (ISR) is executed. At the end of the ISR, the instruction RETI returns the value of the PC from the stack and the originally interrupted program is resumed.
Steps in executing interrupts:
- Microcontroller finishes the instruction it is executing and saves the address of the next instruction (PC) on the stack.
- Jump to a fixed location in memory called the interrupt vector table that holds the address of the interrupt service routine.
- 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, that is RETI (return from interrupt).
- 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. Then it starts to execute from that address.
Programmers must be careful while manipulating data on stack during ISR execution. In ISR number of PUSH and POP must be same.
How to write ISR
ISR is like any other subroutine in program, except that it must end with RETI instruction and not with RET instruction. First line of ISR must begin from corresponding vector address. In some cases ISR will be very long and it may not be practical to write all code starting from vector address. So ISR is kept at some other location in the program memory and an unconditional jump to the starting address of ISR must be provided from corresponding vector address.
Whenever a triggered interrupt is acknowledged and the processor branches to its corresponding vector address, it automatically disables the interrupt in IE register. This disabled interrupt would only be re-enabled upon executing the RETI instruction placed inside the ISR.
Example: ISR for INT0
ORG 0H ; Power on ROM reset location
LJMP MAIN ; bypass all the interrupt vector locations
ORG 0003H ; ISR for INT0 beginning from its vector address
LJMP ISR_INT0 ;unconditional jump from 0003H to the starting
address of ISR
MAIN: SETB IT0 ; configure interrupt 0 for falling edge on INT0
SETB EX0 ; enable external interrupt INT0
SETB EA ; enable global interrupt flag
HERE: SJMP HERE
; ISR for INT0
SETB P0.0 ; turn on some output
SETB P0.1 ; turn on some output
Below is the alternate C code for same ISR. The compiler itself handles the address mapping. You only have to write the ISR function with the corresponding “interrupt number”.
IT0 = 1; // configure interrupt 0 for falling edge on INT0
EX0 = 1; // enable external interrupt INT0
EA = 1; // enable global interrupt flag
// ISR for INT0 beginning from its vector address
void ISR_INT0(void) interrupt 0
P0.0 = 1; // turn on some output
P0.1 = 1; // turn on some output
Software Interrupts in 8051
Software interrupts are generated by program itself inside the controller. Generating software interrupt in 8051 microcontroller is tricky. When external interrupt received at INT0 pin TCON.0 bit (IT0) would be set automatically and processor generates interrupt. If the TCON.0 bit is set in program, microcontroller immediately acknowledges it as interrupt and branch to corresponding ISR of INT0. As a result, 8051 Microcontroller executes software interrupt exactly same as normal ISR.