Hi everyone. Here you can find a little informations about interrupts and timers. During the tutorial 8051 ( silabs ) are help us to learn what the heck is interrupts ! End of the tutorial it is possible to blink led using timers and also to generate a delay function. This blinking thing is easy for who starts electronics with 8051. 8051 is a historical microcontroller. There is no doubt, it is good with experience. But nowadays arduino take the flag. This is not totally true. IF you want to learn electronics arduino kind development board are not enough. Then I thought, this tutorial can give any other way to learn electronics. Also who wants to learn 8051, it will be good start.
For 8051 which is exacty c8051f350 and its holybook ( datasheet) you can download from here . I used 8051 from silicon labs. To blink a led with 8051 first question is the what is timer. Then a few questions follow also. What is timer ?
Timers is an controller are inbuilt chips that are controlled by special function registers (SFRs) assigned for timer operations these SFRs are used to configure Timers in different modes of operation. If you ask what are SFRs that 8051 is a flexible microcontroller with a relatively large number of modes of operations. You program may inspect and/or change the operating mode of the 8051 by manipulating the values of the 8051 special function registers (SFRs). SFRs are accessed as if they were normal internal RAM. The only difference is that internal RAM is from address 00H through 7FH whereas SFR registers exist in the address range from 80h through FFh. Each SFR has an address and a name. Basicly the SFRs provide control and data exchange with 8051 resources and peripherals. So, to blink a led, you need to control the timer using its own SFRs. you will see which SFRs you need.
Generally timers have three goals. First Keeping time and/or calculating the amount of time between events, second Counting the events themselves, third, generating baud rates for the serial port. We will use second goal. Timer is incremented by one machine cycle.It is important ! So, what is a machine cycle ? We can say to the machine cycle is system clock shortly SYSCLK. To use timer you need an oscillator, in c8051f350 has two oscillator optioSns. Internal and external. In the tutorial internal oscillator is used to generate a time interrupt.To much better understand, 8051 internal oscillator has 24.5 Mhz frequency which means that, a running timer will be incremented 12.500.000 times per second.Thus it is great to say that if a timer has counted 0 to 10000000 you may calculate 10000000/24500000 = 0.4082 seconds have passed. Lets say we want to know how many times the timer will be incremented in 0.06 seconds. We can do simple multiplication 0.06*24500000 = 1470000. This tells us that it will take 0.06 seconds to count from 0 to 1470000. But generally we will divide the internal oscillators frequency with prescaler to better control the time issue.
Until here we know that to blink ( or whatever you want to do with microcontroller ) we need timer also SFRs to control timer or other features of the microcontroller which is here 8051 just right now. Also we need an Interrupt. New question is, What is an Interrupt. When I tried to understand the interrupts I think that they are if else statment but they work if statement is true whatever happens. For example in you loop there can be thousunds of statemts to progress. And each statement need to wait flow of code. But in the interrupt situation, to interrupt your microcontroller do not have to wait other instructions.
We know what we need then we can start to write the code to blink a led . Note that I have a c8051f350 silicon lab. development board. I will blink the led on the board. But if you follow the instructions and also understand the idea you can control whichever 8051 microcontroller.
First we enable the interrupts. Interrupts can be controlled with IE register. You can find it page 107. Here all registers are 8 bit because 8051 is a 8 bit microcontroller. Each bit you can control different process of the m.controller. So reset value of the IE resiter is 00000000. If we do not write IE our code it will stay 00000000. You can find all explanations about each bit on page 107. We have to use EA bit ( bit 7 ) and ET2 ( bit 5 ). IF we made EA=1 then all interrupts will be available to choose. After when ET2=1; then timer2 interrupt will be ready to use. Note that we use here timer2. There are 4 timers, you can find information in the datasheet about them. So we enable the interrupts. Next let us choose our oscillator. We need it to count events as we talk before. OSCICN register on page 130 can control oscillator. reset value is 11000000. First IOSCEN bit and IFRDY bit are 1. IOSCEN when it is 1 internal oscillator is enabled and when IFRDY is 1 internal oscillator is running at programmed frequecny which is 24.5Mhz. If you use the OSCICN in reset value you have to divide the 24.5Mhz to 8 to find the SYSCLK frequency. so OSCICN=0xC0 it is hex representation. Instead of writing each of bits we can write the whole register in 8 bit hex representation. 11000000 = 0xC0. Also to use internal oscillator we need CLKSEL register which reset value is enough for us. We do not
have to write it but CLKSEL=0x00 it can hold some line in our code. It is on page 136. As I said we use timer 2 so you can read the Timer 2 section in the datasheet much. If you look at the block diagram of the timer 2 we need CKCON, TMR2L, TMR2H, TMR2RLL, TMR2RLH and TMR2CN registers. We use timer2 in 16 bit auto reload mode. Also it has 8 bit mode. You can read the related part about timer 2 in the datasheet. TMR2RLL and TMR2RLH register are used for how mant seconds or how many times after interrupts will work or called. TMR2L and TMR2H are the same with TMR2RLL and TMR2RLH. TMR2RLL is the Timer 2 reload Low. So now lets configure CKCON register , you can find it on page 201. It is reset value is 00000000 in binary representation. There are two bits for timer 2. T2MH and T2ML. They are important when timer 2 is in the 8 split mode. We use timer 2 in 16 reload mode, that is why we do not have to use this sfr. AS it is seen from the timer 2 block diagram systemclock will be divided by 12 before the each process. From oscıcn register, 24.5 Mhz will be divided by 8 and because of timer 2 will be divided by 12, as a result, our time for
each bit of the 65536 (16 bit auto reload mode ) bit is (8*12) / 24.5 Mhz which is closely equal to 3.92 micro seconds. This gives we have a cycle which divided by 65536 parts. And each part takes 3.92 micro seconds for our configuration. Also we can control these some parts as a HIGH and the other parts as a LOW, basicly we define the where we cut the a one cycle. For example, with one cycle ( 65536 – 16 bit auto reload mode ( 0-65535 )) we want to blink a led each 100 milli seconds. Basicly we know that, we have 65536 parts in a cycle. when we divide 100 ms with 3.92 micro seconds we will find how many parts we need to blink a led . Division gives 25520 parts of the 65536. But Actually here, we have to sbtruct 65535 – 25520 = 40015. for in a cycle, our signal or our parts will be 40015 which is 100 ms.
And example code is:
#include <c8051f320.h>
sbit LED = P0^6;
void main(void){
PCA0MD &=~0x40; // Watchdog timer
OSCICN = 0xC0; // SYSCLK (24.5/8) Mhz ( reset value is 0x00 )
TMR2RLL = 0x40;
TMR2RLH = 0x9c;
TMR2L = TMR2RLL;
TMR2H = TMR2RLH;
TMR2CN = 0x04; // pr TR2 = 1
ET2 = 1; // enable Timer2 interrupt
XBR1 = 0x40; //enable crossbar
P0MDOUT = 0x40; //make P0^6 push pull output
EA = 1; // Enable global interrupts
while(1);
}
Timer2_ISR(void) interrupt 5
{
LED = !LED;
TF2H = 0; // TF2H should be setted 0 manually ( it is written
}
Also If you want to create a delay function below the code can give you the idea. Two example code give same result but in totally different way.
#include <c8051f320.h>
void delay();
sbit LED = P0^6;
void main(void){
PCA0MD &=~0x40; // Watchdog timer
delay();
OSCICN = 0xC0; // SYSCLK (24.5/8) Mhz ( reset value is 0x00 )
ET2 = 1; // enable Timer2 interrupt
XBR1 = 0x40; //enable crossbar
P0MDOUT = 0x40; //make P0^6 push pull output
EA = 1; // Enable global interrupts
while(1){
LED = 1;
delay(); // 100 ms delay
LED = 0;
delay();
}
}
void delay()
{
TMR2RLL = 0x40;
TMR2RLH = 0x9c;
TMR2L = TMR2RLL;
TMR2H = TMR2RLH;
TR2 = 1;
while(!TF2H);
TF2H = 0;
}
Actually you can give the same effect without timers just using for loop. But it is not easy to give exact time with for loop.That is why we try to use timers. 15-02-2016