Interrupt service routine using Timers in 8051 |
Interrupts are one of the most important concepts in a 8051 Microcontroller and we can say that no real world Embedded System exists without using the concept of Interrupts. Interrupt is nothing but a notification or request signal that was received by the controller from device hardware, software or from other external sources. On receiving the Interrupt the Microcontroller completes the execution of current instruction and starts executing a ISR ( Interrupt service Routine ).
ISR is nothing but a piece of code which will be executed in case the Microcontroller encounters any interrupt in during its operation. After the execution of ISR the controller returns back to the instruction from where it performed the jump previously to perform its normal operation.
INTERRUPTS IN 8051:
The 8051 has five interrupt resources. Each of them can be programmed to two priority levels. The interrupt sources are:
- INT0 – Interrupt from external request to P3.2 of 8051
- Timer 0 – This interrupt gets activated whenever Timer 0 activates the Flag TF0.
- INT1 – Interrupt made from external request to P3.3
- Timer 1 – This interrupt gets activated whenever Timer 1 activates the flag TF1.
- Serial Interrupt – Gets activated whenever controller receives or transmits data.
PROGRAMMING INTERRUPTS:
The first step of programming interrupts starts with configuring the Interrupt Enable register (IE) which which enables or disable the available interrupts in the Microcontroller.
IE= 0x81 ; enables External Interrupt0 (EX0)Using this IE register we can enable the interrupts we are about to use in our design. This IE register is also bit addressable. For example:
IE= 0x82; enables Timer Interrupt
Next step is to write a sub routine program for microcontroller to execute when an interrupt occurs , this is commonly known as Interrupt service routine(ISR). For writing a ISR we must include a keyword followed by the interrupt number and using this subroutine for particular interrupt is identified by this number.
Interrupt Number and Keyword |
The above table illustrates the keyword usage for respective interrupts, we should opt for the correct keyword for writing our ISR. For example if we need to write a sub routine for Timer0 interrupt then your code will look like
Void Timer0(void) Interrupt 1
{
Your subroutine Program Goes here….
}
|
PROGRAMMING TIMER INTERRUPTS:
There are two timer Interrupts IT0 and IT1 in 8051 microcontroller. Each of these interrupts are triggered by Timer0 and Timer1 respectively. Before moving into the Interrupt using Timers you must be familiar with Programming Timers of 8051 controller. To program timer interrupts you must follow these steps:
- Configure TMOD register to specify the mode of operation of timers in your system.
- Load the hex values in THx and TLx register.
- Start the Timer using TRx or TCON.
- Monitoring of TFx flag depends on the time period you are about to generate for the system.
- Enable the Timer interrupt using the IE register.
- Write the subroutine for Timer Interrupt with correct keyword listed in the above table.
- To stop the timer you have to clear the TRx in the end of the sub routine program or it will restart form 0000H in case of Timer modes 0 or 1 and from loaded values in mode 2.
We are about to see a sample program in which Timer was programmed to give five seconds delay and Timer interrupt was used to blink LED’s in port 0. For each five seconds the interrupt will toggle the LED’s infinite times. In the above design 6MHz crystal was used so to give five seconds delay
Timer count at Fosc / 12 = 6.0 MHz/12 = 0.5MHz
Each count Takes 1/0.5 =2us
Total counts by a 16 bit timer 65535 * 2us =0.131 sec
To give 5 seconds delay 0.131 sec * 38 = 5 Sec delay
CODE:
#include<stdio.h> #include<reg51.h> unsigned char count; unsigned int value; void main() { P0=0x00; TMOD=0x01; //16 bit mode for timer 0 TH0=0x00; //Upper Timer Register TL0=0x00; //Lower Timer Register TCON=0x10; //Start Timer 0 IE=0x82; //Enable Timer 0 overflow interrupt while(1); } void Timer0(void)interrupt 1 { value++; if(value==38) //To activate LED's after 5 seconds { P0=~P0; value=0; } }
Assume that the INT1 pin is connected to a switch that is normally high. Whenever it goes low, it should turn on an LED. The LED is connected to PI .3 and is normally off. When it is turned on it should stay on for a fraction of a second. As long as the switch is pressed low, the LED should stay on.
You are actually checking whether the timer overflows or not.
while(1);
But i need to interrupt the controller whenever the timer overflows.
I should not check the timer overflow status..
Prem,
While(1) is not for checking the Timer overflow status. While(1) is there to keep the loop from terminating, missing this will cause the main loop to terminate and interrupt will cease to work
Yes. Its correct. But my question is, Is It possible to check the timer overflow status without using polling method. If i use while(TF!=1)> , the CPU checks whether the timer overflows or not.This should not happen.
Thank you for your response……!!
I don’t see what you are intend to say. I haven’t this piece of lin “while(TF!=1)” in the above code. I will clarify again the above code sets to activates the timer interrupt and wait indefinitely for Interrupt routine to take over and do something, simple as that. You don’t need to be worried about overflow flag