Sie sind auf Seite 1von 10

8051 Tutorial: Timers

The 8051 comes equipped with two timers, both of which may be controlled, set, read, and configured individually. The 8051 timers have three general functions: 1 !eeping time and"or calculating the amount of time between events, # $ounting the events themselves, or % &enerating baud rates for the serial port. The three timer uses are distinct so we will tal' about each of them separately. The first two uses will be discussed in this chapter while the use of timers for baud rate generation will be discussed in the chapter relating to serial ports.

How does a timer count?


(ow does a timer count) The answer to this question is very simple: * timer always counts up. +t doesnt matter whether the timer is being used as a timer, a counter, or a baud rate generator: * timer is always incremented by the microcontroller. Programming Tip: ,ome derivative chips actually allow the program to configure whether the timers count up or down. (owever, since this option only e-ists on some derivatives it is beyond the scope of this tutorial which is aimed at the standard 8051. +t is only mentioned here in the event that you absolutely need a timer to count bac'wards, you will 'now that you may be able to find an 8051. compatible microcontroller that does it.

USING TI !"S T#

!$SU"! TI !

/bviously, one of the primary uses of timers is to measure time. 0e will discuss this use of timers first and will subsequently discuss the use of timers to count events. 0hen a timer is used to measure time it is also called an 1interval timer1 since it is measuring the time of the interval between two events.

How long does a timer ta%e to count?


2irst, its worth mentioning that when a timer is in interval timer mode 3as opposed to event counter mode and correctly configured, it will increment by 1 every machine cycle. *s you will recall from the previous chapter, a single machine cycle consists of 1# crystal pulses. Thus a running timer will be incremented: 11,054,000 " 1# 5 4#1,58% 4#1,58% times per second. 6nli'e instructions..some of which require 1 machine cycle, others #, and others 7..the timers are consistent: They will always be incremented once per machine cycle. Thus if a timer has counted from 0 to 50,000 you may calculate: 50,000 " 4#1,58% 5 .057#

.057# seconds have passed. +n plain 8nglish, about half of a tenth of a second, or one. twentieth of a second. /bviously its not very useful to 'now .057# seconds have passed. +f you want to e-ecute an event once per second youd have to wait for the timer to count from 0 to 50,000 18.75 times. (ow can you wait 1half of a time)1 9ou cant. ,o we come to another important calculation. :ets say we want to 'now how many times the timer will be incremented in .05 seconds. 0e can do simple multiplication: .05 ; 4#1,58% 5 7<,0=4.15. This tells us that it will ta'e .05 seconds 31"#0th of a second to count from 0 to 7<,0=4. *ctually, it will ta'e it .0744448%= seconds..so were off by .0000001<% seconds..however, thats close enough for government wor'. $onsider that if you were building a watch based on the 8051 and made the above assumption your watch would only gain about one second every # months. *gain, + thin' thats accurate enough for most applications..+ wish my watch only gained one second every two months> /bviously, this is a little more useful. +f you 'now it ta'es 1"#0th of a second to count from 0 to 7<,0=4 and you want to e-ecute some event every second you simply wait for the timer to count from 0 to 7<,0=4 twenty times? then you e-ecute your event, reset the timers, and wait for the timer to count up another #0 times. +n this manner you will effectively e-ecute your event once per second, accurate to within thousandths of a second. Thus, we now have a system with which to measure time. *ll we need to review is how to control the timers and initiali@e them to provide us with the information we need.

Timer S&"s
*s mentioned before, the 8051 has two timers which each function essentially the same way. /ne timer is T+A8B0 and the other is T+A8B1. The two timers share two ,2Bs 3TA/C and T$/D which control the timers, and each timer also has two ,2Bs dedicated solely to itself 3T(0"T:0 and T(1"T:1 . 0eve given ,2Bs names to ma'e it easier to refer to them, but in reality an ,2B has a numeric address. +t is often useful to 'now the numeric address that corresponds to an ,2B name. The ,2Bs relating to timers are:
S&" Name T(0 T:0 T(1 T:1 'escription Timer 0 (igh Eyte Timer 0 :ow Eyte Timer 1 (igh Eyte Timer 1 :ow Eyte S&" $ddress 8$h 8*h 8Ch 8Eh

T$/D TA/C

Timer $ontrol Timer Aode

88h 84h

0hen you enter the name of an ,2B into an assembler, it internally converts it to a number. 2or e-ample, the command: A/F T(0,G#5h moves the value #5h into the T(0 ,2B. (owever, since T(0 is the same as ,2B address 8$h this command is equivalent to: A/F 8$h,G#5h Dow, bac' to the timers. 2irst, lets tal' about Timer 0. Timer 0 has two ,2Bs dedicated e-clusively to itself: T(0 and T:0. 0ithout ma'ing things too complicated to start off with, you may Hust thin' of this as the high and low byte of the timer. That is to say, when Timer 0 has a value of 0, both T(0 and T:0 will contain 0. 0hen Timer 0 has the value 1000, T(0 will hold the high byte of the value 3% decimal and T:0 will contain the low byte of the value 3#%# decimal . Beviewing low"high byte notation, recall that you must multiply the high byte by #5< and add the low byte to calculate the final value. That is to say: T(0 ; #5< I T:0 5 1000 % ; #5< I #%# 5 1000 Timer 1 wor's the e-act same way, but its ,2Bs are T(1 and T:1. ,ince there are only two bytes devoted to the value of each timer it is apparent that the ma-imum value a timer may have is <5,5%5. +f a timer contains the value <5,5%5 and is subsequently incremented, it will reset..or overflow..bac' to 0.

T(e T #' S&"


:ets first tal' about our first control ,2B: TA/C 3Timer Aode . The TA/C ,2B is used to control the mode of operation of both timers. 8ach bit of the ,2B gives the microcontroller specific information concerning how to run a timer. The high four bits 3bits 7 through = relate to Timer 1 whereas the low four bits 3bits 0 through % perform the e-act same functions, but for timer 0. The individual bits of TA/C have the following functions: TA/C 384h ,2B
)it Name = < !*planation o+ &unction Timer 0hen this bit is set the timer will only run when +DT1 3J%.% &*T81 is high. 0hen this bit is clear the timer will run regardless of 1 the state of +DT1. $"T1 0hen this bit is set the timer will count events on T1 3J%.5 . 1 0hen this bit is clear the timer will be incremented every

machine cycle. 5 7 % T1A1 T1A0 Timer mode bit 3see below Timer mode bit 3see below 1 1

0hen this bit is set the timer will only run when +DT0 3J%.# &*T80 is high. 0hen this bit is clear the timer will run regardless of 0 the state of +DT0. $"T0 T0A1 T0A0 0hen this bit is set the timer will count events on T0 3J%.7 . 0hen this bit is clear the timer will be incremented every 0 machine cycle. Timer mode bit 3see below Timer mode bit 3see below 0 0

# 1 0

*s you can see in the above chart, four bits 3two for each timer are used to specify a mode of operation. The modes of operation are:
T* 1 0 0 1 1 T* 0 0 1 0 1 Timer Aode 0 1 # % Cescription of Aode 1%.bit Timer. 1<.bit Timer 8.bit auto.reload ,plit timer mode

1,-.it Time

ode /mode 00

Timer mode 101 is a 1%.bit timer. This is a relic that was 'ept around in the 8051 to maintain compatability with its predecesor, the 8078. &enerally the 1%.bit timer mode is not used in new development. 0hen the timer is in 1%.bit mode, T:- will count from 0 to %1. 0hen T:- is incremented from %1, it will 1reset1 to 0 and increment T(-. Thus, effectively, only 1% bits of the two timer bytes are being used: bits 0.7 of T:- and bits 0.= of T(-. This also means, in essence, the timer can only contain 814# values. +f you set a 1%.bit timer to 0, it will overflow bac' to @ero 814# machine cycles later. *gain, there is very little reason to use this mode and it is only mentioned so you wont be surprised if you ever end up analy@ing archaeic code which has been passed down through the generations 3a generation in a programming shop is often on the order of about % or 7 months .

11-.it Time

ode /mode 10

Timer mode 111 is a 1<.bit timer. This is a very commonly used mode. +t functions Hust li'e 1%.bit mode e-cept that all 1< bits are used. T:- is incremented from 0 to #55. 0hen T:- is incremented from #55, it resets to 0 and causes T(- to be incremented by 1. ,ince this is a full 1<.bit timer, the timer may contain up to <55%< distinct values. +f you set a 1<.bit timer to 0, it will overflow bac' to 0 after <5,5%< machine cycles.

8-.it Time

ode /mode 20

Timer mode 1#1 is an 8.bit auto.reload mode. 0hat is that, you may as') ,imple. 0hen a timer is in mode #, T(- holds the 1reload value1 and T:- is the timer itself. Thus, T:- starts counting up. 0hen T:- reaches #55 and is subsequently incremented, instead of resetting to 0 3as in the case of modes 0 and 1 , it will be reset to the value stored in T(-. 2or e-ample, lets say T(0 holds the value 2Ch and T:0 holds the value 28h. +f we were to watch the values of T(0 and T:0 for a few machine cycles this is what wed see:
ac(ine 34cle TH0 5alue T60 5alue 1 # % 7 5 < = 2Ch 2Ch 2Ch 2Ch 2Ch 2Ch 2Ch 28h 22h 2Ch 28h 22h 2Ch 28h

*s you can see, the value of T(0 never changed. +n fact, when you use mode # you almost always set T(- to a 'nown value and T:- is the ,2B that is constantly incremented. 0hats the benefit of auto.reload mode) Jerhaps you want the timer to always have a value from #00 to #55. +f you use mode 0 or 1, youd have to chec' in code to see if the timer had overflowed and, if so, reset the timer to #00. This ta'es precious instructions of e-ecution time to chec' the value and"or to reload it. 0hen you use mode # the microcontroller ta'es care of this for you. /nce youve configured a timer in mode # you dont have to worry about chec'ing to see if the timer has overflowed nor do you have to worry about resetting the value..the microcontroller hardware will do it all for you. The auto.reload mode is very commonly used for establishing a baud rate which we will tal' more about in the ,erial $ommunications chapter.

Split Timer

ode /mode ,0

Timer mode 1%1 is a split.timer mode. 0hen Timer 0 is placed in mode %, it essentially becomes two separate 8.bit timers. That is to say, Timer 0 is T:0 and Timer 1 is T(0. Eoth timers count from 0 to #55 and overflow bac' to 0. *ll the bits that are related to Timer 1 will now be tied to T(0. 0hile Timer 0 is in split mode, the real Timer 1 3i.e. T(1 and T:1 can be put into modes 0, 1 or # normally..however, you may not start or stop the real timer 1 since the bits that do that are now lin'ed to T(0. The real timer 1, in this case, will be incremented every machine cycle no matter what.

The only real use + can see of using split timer mode is if you need to have two separate timers and, additionally, a baud rate generator. +n such case you can use the real Timer 1 as a baud rate generator and use T(0"T:0 as two separate timers.

T(e T3#N S&"


2inally, theres one more ,2B that controls the two timers and provides valuable information about them. The T$/D ,2B has the following structure: T$/D 388h ,2B
)it Name = < 5 7 T21 TB1 T20 TB0 )it $ddress 82h 88h 8Ch 8$h !*planation o+ &unction Timer

Timer 1 #7er+low. This bit is set by the microcontroller when 1 Timer 1 overflows. Timer 1 "un. 0hen this bit is set Timer 1 is turned on. 0hen 1 this bit is clear Timer 1 is off. Timer 0 #7er+low. This bit is set by the microcontroller when 0 Timer 0 overflows. Timer 0 "un. 0hen this bit is set Timer 0 is turned on. 0hen 0 this bit is clear Timer 0 is off.

*s you may notice, weve only defined 7 of the 8 bits. Thats because the other 7 bits of the ,2B dont have anything to do with timers..they have to do with +nterrupts and they will be discussed in the chapter that addresses interrupts. * new piece of information in this chart is the column 1bit address.1 This is because this ,2B is 1bit.addressable.1 0hat does this mean) +t means if you want to set the bit T21..which is the highest bit of T$/D..you could e-ecute the command: A/F T$/D, G80h ... or, since the ,2B is bit.addressable, you could Hust e-ecute the command: ,8TE T21 This has the benefit of setting the high bit of T$/D without changing the value of any of the other bits of the ,2B. 6sually when you start or stop a timer you dont want to modify the other values in T$/D, so you ta'e advantage of the fact that the ,2B is bit.addressable.

Initiali8ing a Timer
Dow that weve discussed the timer.related ,2Bs we are ready to write code that will initiali@e the timer and start it running. *s youll recall, we first must decide what mode we want the timer to be in. +n this case we want a 1<.bit timer that runs continuously? that is to say, it is not dependent on any e-ternal pins.

0e must first initiali@e the TA/C ,2B. ,ince we are wor'ing with timer 0 we will be using the lowest 7 bits of TA/C. The first two bits, &*T80 and $"T0 are both 0 since we want the timer to be independent of the e-ternal pins. 1<.bit mode is timer mode 1 so we must clear T0A1 and set T0A0. 8ffectively, the only bit we want to turn on is bit 0 of TA/C. Thus to initiali@e the timer we e-ecute the instruction: A/F TA/C,G01h Timer 0 is now in 1<.bit timer mode. (owever, the timer is not running. To start the timer running we must set the TB0 bit 0e can do that by e-ecuting the instruction: ,8TE TB0 6pon e-ecuting these two instructions timer 0 will immediately begin counting, being incremented once every machine cycle 3every 1# crystal pulses .

"eading t(e Timer


There are two common ways of reading the value of a 1<.bit timer? which you use depends on your specific application. 9ou may either read the actual value of the timer as a 1<.bit number, or you may simply detect when the timer has overflowed.

"eading t(e 7alue o+ a Timer


+f your timer is in an 8.bit mode..that is, either 8.bit *utoBeload mode or in split timer mode..then reading the value of the timer is simple. 9ou simply read the 1.byte value of the timer and youre done. (owever, if youre dealing with a 1%.bit or 1<.bit timer the chore is a little more complicated. $onsider what would happen if you read the low byte of the timer as #55, then read the high byte of the timer as 15. +n this case, what actually happened was that the timer value was 17"#55 3high byte 17, low byte #55 but you read 15"#55. 0hy) Eecause you read the low byte as #55. Eut when you e-ecuted the ne-t instruction a small amount of time passed..but enough for the timer to increment again at which time the value rolled over from 17"#55 to 15"0. Eut in the process youve read the timer as being 15"#55. /bviously theres a problem there. The solution) +ts not too tric'y, really. 9ou read the high byte of the timer, then read the low byte, then read the high byte again. +f the high byte read the second time is not the same as the high byte read the first time you repeat the cycle. +n code, this would appear as:
B8J8*T: A/F *,T(0 A/F B0,T:0 $KD8 *,T(0,B8J8*T ...

+n this case, we load the accumulator with the high byte of Timer 0. 0e then load B0 with the low byte of Timer 0. 2inally, we chec' to see if the high byte we read out of Timer 0..which is now stored in the *ccumulator..is the same as the current Timer 0 high byte. +f it isnt it means weve Hust 1rolled over1 and must reread the timers value..

which we do by going bac' to B8J8*T. 0hen the loop e-its we will have the low byte of the timer in B0 and the high byte in the *ccumulator. *nother much simpler alternative is to simply turn off the timer run bit 3i.e. $:B TB0 , read the timer value, and then turn on the timer run bit 3i.e. ,8TE TB0 . +n that case, the timer isnt running so no special tric's are necessary. /f course, this implies that your timer will be stopped for a few machine cycles. 0hether or not this is tolerable depends on your specific application.

'etecting Timer #7er+low


/ften it is necessary to Hust 'now that the timer has reset to 0. That is to say, you are not particularly interest in the value of the timer but rather you are interested in 'nowing when the timer has overflowed bac' to 0. 0henever a timer overflows from its highest value bac' to 0, the microcontroller automatically sets the T2- bit in the T$/D register. This is useful since rather than chec'ing the e-act value of the timer you can Hust chec' if the T2- bit is set. +f T20 is set it means that timer 0 has overflowed? if T21 is set it means that timer 1 has overflowed. 0e can use this approach to cause the program to e-ecute a fi-ed delay. *s youll recall, we calculated earlier that it ta'es the 8051 1"#0th of a second to count from 0 to 7<,0=4. (owever, the T2- flag is set when the timer overflows bac' to 0. Thus, if we want to use the T2- flag to indicate when 1"#0th of a second has passed we must set the timer initially to <55%< less 7<0=4, or 14,75=. +f we set the timer to 14,75=, 1"#0th of a second later the timer will overflow. Thus we come up with the following code to e-ecute a pause of 1"#0th of a second: #5 TH09:;1?(igh byte of 14,75= 3=< ; #5< 5 14,75< #5 T609:01?:ow byte of 14,75= 314,75< I 1 5 14,75= #5 T #'9:01?Jut Timer 0 in 1<.bit mode S!T) T"0?Aa'e Timer 0 start counting <N) T&09=?+f T20 is not set, Hump bac' to this same instruction +n the above code the first two lines initiali@e the Timer 0 starting value to 14,75=. The ne-t two instructions configure timer 0 and turn it on. 2inally, the last instruction <N) T&09=, reads 1Kump, if T20 is not set, bac' to this same instruction.1 The 1L1 operand means, in most assemblers, the address of the current instruction. Thus as long as the timer has not overflowed and the T20 bit has not been set the program will 'eep e-ecuting this same instruction. *fter 1"#0th of a second timer 0 will overflow, set the T20 bit, and program e-ecution will then brea' out of the loop.

Timing t(e lengt( o+ e7ents


The 8051 provides another cool toy that can be used to time the length of events. 2or e-ample, letMs say weMre trying to save electricity in the office and weMre interested in how long a light is turned on each day. 0hen the light is turned on, we want to measure time. 0hen the light is turned off we donMt. /ne option would be to connect the lightswitch to one of the pins, constantly read the pin, and turn the timer on or off

based on the state of that pin. 0hile this would wor' fine, the 8051 provides us with an easier method of accomplishing this. :oo'ing again at the TA/C ,2B, there is a bit called &*T80. ,o far weMve always cleared this bit because we wanted the timer to run regardless of the state of the e-ternal pins. (owever, now it would be nice if an e-ternal pin could control whether the timer was running or not. +t can. *ll we need to do is connect the lightswitch to pin +DT0 3J%.# on the 8051 and set the bit &*T80. 0hen &*T80 is set Timer 0 will only run if J%.# is high. 0hen J%.# is low 3i.e., the lightswitch is off the timer will automatically be stopped. Thus, with no control code whatsoever, the e-ternal pin J%.# can control whether or not our timer is running or not.

USING TI !"S $S !5!NT 3#UNT!"S


0eMve discussed how a timer can be used for the obvious purpose of 'eeping trac' of time. (owever, the 8051 also allows us to use the timers to count events. (ow can this be useful) :etMs say you had a sensor placed across a road that would send a pulse every time a car passed over it. This could be used to determine the volume of traffic on the road. 0e could attach this sensor to one of the 8051Ms +"/ lines and constantly monitor it, detecting when it pulsed high and then incrementing our counter when it went bac' to a low state. This is not terribly difficult, but requires some code. :etMs say we hoo'ed the sensor to J1.0? the code to count cars passing would loo' something li'e this:
KDE J1.0,L ?+f a car hasnMt raised the signal, 'eep waiting KE J1.0,L ?The line is high which means the car is on the sensor right now +D$ $/6DT8B ?The car has passed completely, so we count it

*s you can see, itMs only three lines of code. Eut what if you need to be doing other processing at the same time) 9ou canMt be stuc' in the KDE J1.0,L loop waiting for a car to pass if you need to be doing other things. /f course, there are ways to get around even this limitation but the code quic'ly becomes big, comple-, and ugly. :uc'ily, since the 8051 provides us with a way to use the timers to count events we donMt have to bother with it. +t is actually painfully easy. 0e only have to configure one additional bit. :etMs say we want to use Timer 0 to count the number of cars that pass. +f you loo' bac' to the bit table for the T$/D ,2B you will there is a bit called 1$"T01..itMs bit # 3T$/D.# . Beviewing the e-planation of the bit we see that if the bit is clear then timer 0 will be incremented every machine cycle. This is what weMve already used to measure time. (owever, if we set $"T0 timer 0 will monitor the J%.7 line. +nstead of being incremented every machine cycle, timer 0 will count events on the J%.7 line. ,o in our case we simply connect our sensor to J%.7 and let the 8051 do the wor'. Then, when we want to 'now how many cars have passed, we Hust read the value of timer 0..the value of timer 0 will be the number of cars that have passed.

,o what e-actly is an event) 0hat does timer 0 actually 1count)1 ,pea'ing at the electrical level, the 8051 counts 1.0 transitions on the J%.7 line. This means that when a car first runs over our sensor it will raise the input to a high 3111 condition. *t that point the 8051 will not count anything since this is a 0.1 transition. (owever, when the car has passed the sensor will fall bac' to a low 3101 state. This is a 1.0 transition and at that instant the counter will be incremented by 1. +t is important to note that the 8051 chec's the J%.7 line each instruction cycle 31# cloc' cycles . This means that if J%.7 is low, goes high, and goes bac' low in < cloc' cycles it will probably not be detected by the 8051. This also means the 8051 event counter is only capable of counting events that occur at a ma-imum of 1"#7th the rate of the crystal frequency. That is to say, if the crystal frequency is 1#.000 Ah@ it can count a ma-imum of 500,000 events per second 31#.000 Ah@ ; 1"#7 5 500,000 . +f the event being counted occurs more than 500,000 times per second it will not be able to be accurately counted by the 8051.

Das könnte Ihnen auch gefallen