Beruflich Dokumente
Kultur Dokumente
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.
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.
.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
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.
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.
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 .
+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.
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.
*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.