Vous êtes sur la page 1sur 17

C programs for Timer

• Fundamentally not too different from asm


• assignment statement instead of MOV
• while (TF0==0) ; to poll TF0 flag.
• TR0 = 1 to start,TR0 = 0 to stop
• Delay accomplished by count-up roll-over
Example asm vs C for
timer (ex. 9-20)
#include <8051.h>

void T0Delay(void);

void main(void) { _main:

while(1) { L:

P1 = 0x55; MOV P1, #55H

T0Delay(); ACALL T0Delay

P1 = 0xAA; MOV P1, #AAH

} } SJMP L
Example asm vs C for
timer (cont'd)
void T0Delay(void) { _T0Delay:
TMOD = 0x01; MOV TMOD, #01H
TL0 = 0x00; MOV TL0, #00H
TH0 = 0x35; MOV TH0, #35H
TR0 = 1; SETB TR0
while (TF0 == 0) ; L: JNB TF0, L
TR0 = 0; CLR TR0
TF0 = 0; CLR TF0
} RET
Delay vs. Periodic task
• Delay: relative to a point in time
• Mode 0, Mode 1 are not as appropriate
• Periodic task (e.g., "do task every 500ms")
• Mode 2 (with auto reload) may be better
• however, need to be careful with
overhead, since timer reg is only 8 bits
Ex. 9-23: toggle every
250ms (but no good)
#include <8051.h> void T0M2Delay(void) {
void T0M2Delay(void); TMOD = 0x02;
sbit at 0x95 mybit; // P1.5 TH0 = -23;
void main(void) { TR0 = 1;
unsigned char x, y; while (TF0 == 0) ;
while(1) { TR0 = 0;
mybit = ~mybit; TF0 = 0;
for (x=0;x<250;x++) }
for (y=0; y<36; y++)
T0M2Delay();
} }
Why is this example
no good?
• Totally defeats the purpose of auto-reload!
• Problem w/ Ex. 9-23: repeat T0M2Delay()
• pay overhead each time! relative to after
overhead, not periodic.
• Correct way:
• Set up the reload once (not T0M2Delay)
• Repeat polling TF0 in loop
Ex. 9-23:What's wrong
#include <8051.h> void T0M2Delay(void) {
void T0M2Delay(void); TMOD = 0x02;
sbit at 0x95 mybit; // P1.5 TH0 = -23;
void main(void) { TR0 = 1;
unsigned char x, y; while (TF0 == 0) ;
while(1) { TR0 = 0;
mybit = ~mybit; TF0 = 0;
for (x=0;x<250;x++) } should clear only flag,
for (y=0; y<36; y++) but not turn-off timer!

T0M2Delay();
setup should be separated
} } from polling; not delay
Timing for original 9-23
while(1)
for (x..) for (x..)
CPL CPL
for (y..) for (y..)
mybit mybit
T0M2Delay T0M2Delay

Timer off Timer on Timer off Timer on Timer off

time tick
starting
time tick
starting

time tick
mybit
ending
delta2
(After tick!!)
delta1 delta1
(Before tick) (Before tick)
delta1
(Before tick) base error margin
not including Timer-off error
time
Better way to do Ex.
9-23
#include <8051.h> void SetupT0M2(void) {
void SetupT0M2(void), PollT0(void); TMOD = 0x02;
void main(void) {unsigned char x, TH0 = -23;
SetupT0M2(void); TR0 = 1;
while (1) { }
mybit = ~mybit;
for (x = 0; x < 250; x++) { void PollT0(void) {
for (y = 0; y < 36; y++) { while (TF0 == 0) ;
PollT0(); TF0 = 0;
} } }
} }
Timing for better 9-23
SetupT0M2 while(1)
for (x..) for (x..)
TR0 CPL CPL
for (y..) for (y..)
= 1 mybit mybit
PollT0 ... PollT0 PollT0

Timer off Timer on


time tick

mybit
time tick latency1
latency1 latency2

ddiff
time
Summary of corrected
9-23
• Use auto-reload to absorb overhead
• don't disable/re-enable timer on reloads!
• Line up with timer as precisely as possible
• Immediately after start running timer
• Immediately after polling TF going high
• 1st high interval is diff longer; others exact
• easy to fix by padding nops
Counter programming
• Counter: count number of pulses
• set the T0 or T1 pin to high for input
• set mode (13 or 16 bit or 8-bit reload)
• normally clear count
• Otherwise, works the same way as timer
• Set/clear TR0 or TR1 to start/stop
• Poll/clear TF0 or TF1 flag on rollover
Example 9-27: count &
display (16-bit) count
#include <8051.h>
sbit at 0xA5 T1;
void main(void) {
T0 = 1; // make T0 (counter pin) input
TMOD = 0x05; // C/T=1, Mode=1: no reload
TH0 = 0;TL0 = 0; // initialize count value
while (1) {
TR1 = 1; // outside do-loop, not inside as book!
do { P1 = TL0; // output value to Port P1
P2 = TH0; // and to P2
} while (TF1==0); // until flag up (rollover)
TR0 = 0; // turn off
TF0 = 0; // clear flag
} }
Example 9-26: count &
display (8-bit) count
#include <8051.h>
sbit at 0xA5 T1;
void main(void) {
T1 = 1; // make T1 (counter pin) input
TMOD = 0x60; // C/T=1, Mode=2: auto-reload
TH1 = 0; // auto reload value = 0
while (1) {
TR1 = 1; // start counter (should do only once outside!)
do P1 = TL1; // output value to TL1
} while (TF1==0); // until flag up (rollover)
TR1 = 0; // turn off (not necessary!)
TF1 = 0; // clear flag
} }
Example 9-28: to ascii
main loop
correction
from book
while (1) { while (1) {
do { TR0 = 1;
TR0 = 1; do {
value = TL0; value = TL0;
BinToASCII(value); BinToASCII(value);
} while (TF0 == 0); } while (TF0 == 0);
TR0 = 0; TR0 = 0;
TF0 = 0; TF0 = 0;
} }
Example 9-29 timer as
wall clock
• Input
• 60Hz pulse to T0 input (P3.4)
• Task
• Use counter mode 2: every 60 pulses
• Reload from TH1 every 60 times (use -60)
• Display (binary) on I/O port
Bug with 9-29
#include <8051.h>
void ToTime(unsigned char);
void main(void) {
unsigned char val; // val not initialized or assigned
T0 = 1;
TMOD = 0x06;
TH0 = -60;
while (1) {
do { TR0 = 1; // should not enable repeatedly!
sec = TL0; // sec not declared! they meant
ToTime(val); // TL0 is 1/60 sec, not seconds!!
} while (TF0 == 0);
TF0 = 0;TF0 = 0;
} }

Vous aimerez peut-être aussi