Sie sind auf Seite 1von 36

Microprocessor Fundamentals

Topic 7 Timing: the Timer/Counter

Objectives
Examine the Timer/Counter Register: TCNT0 Examine the Timer/Counter Control Register: TCCR0 Write a time delay for the previous program example: Light Chaser
Use the Timer/Counter Design a sec. delay for lights on/off Assume a 16 MHz clock

5/11/2010

Timer/Counter
So, we have:
The Light Chaser Program Must add a time delay for the program:
Use the Timer/Counter Design a sec. delay for lights on/off Assume a 16 MHz clock

We need to look up the Timer/Counter

5/11/2010

Timer/Counter
Open the ATmega128 Manual

Click on the 8-Bit Timer/Counter 0

5/11/2010

Timer/Counter
8-Bit Timer/Counter

Click on the 8-Bit Timer/Counter Registers

5/11/2010

TCCR0
The Timer/Counter Control Register

We are most concerned with bits 2, 1, and 0. They control the clock source to be used by the counter

5/11/2010

TCCR0
The Timer/Counter Control Register

We are most concerned with bits 2, 1, and 0. They control the clock source to be used by the counter We can turn off the counter We can use the system clock or We can use a slower signal based on the system clock

5/11/2010

TCCR0
The Timer/Counter Control Register

We are initializing the Timer/Counter so that it will increment at every clock pulse. If the system clock was 10 MHz: If we used the system clock, the Timer/Counter would increment every 100ns

5/11/2010

TCCR0
The Timer/Counter Control Register

We are initializing the Timer/Counter so that it will increment at every clock pulse. If the system clock was 10 MHz: If we used the system clock, the Timer/Counter would increment every 100ns If we used a prescaler of 1024 (bits 2-0 = 111), the Timer/Counter would increment every 100 us

5/11/2010

TCCR0
The Timer/Counter Control Register

The real question: How long must our delay be? The Timer/Counter (an 8-bit register) can count from 0 to 255. With a 10 MHz clock and no prescaler, the Timer/Counter can count from 1 to 255 in 100ns to 25.5 us With a 1024 prescaler, it could count from 1 to 255 in 100us to 25.5 ms

5/11/2010

10

TCCR0
The Timer/Counter Control Register
If we need a delay of 10 us, dont use a prescaler.

The real question: How long must our delay be? The Timer/Counter (an 8-bit register) can count from 0 to 255. With a 10 MHz clock and no prescaler, the Timer/Counter can count from 1 to 255 in 100ns to 25.5 us With a 1024 prescaler, it could count from 1 to 255 in 100us to 25.5 ms

5/11/2010

11

TCCR0
The Timer/Counter Control Register
If we need a delay of 10 us, dont use a prescaler. If we need a delay of 10ms, use the 1024 prescaler

The real question: How long must our delay be? The Timer/Counter (an 8-bit register) can count from 0 to 255. With a 10 MHz clock and no prescaler, the Timer/Counter can count from 1 to 255 in 100ns to 25.5 us With a 1024 prescaler, it could count from 1 to 255 in 100us to 25.5 ms

5/11/2010

12

Example:
Write the initialization routine and the timing loop to form a delay of 10ms (assume a 10 MHz clock)

5/11/2010

13

Example:
Write the initialization routine and the timing loop to form a delay of 10ms (assume a 10 MHz clock)
A 10 MHz clock will take 100ns/cycle A 1024 prescaler means we will increment the TC every 100us To count from 0 to 10 ms and incrementing TC every 100 us/count means we have to count from 0 to 10ms/100us 1 = 100 1 = 9910 = 63X We subtract 1 because we are counting from 0, not 1

5/11/2010

14

Example:
Write the initialization routine and the timing loop to form a delay of 10ms (assume a 10 MHz clock)
;======================================================== .def delayReg = r17 .def TCValue = r18 ;name registers ;=========================== Init: ldi delayReg,0x07 ;set initial parameters for counter out TCCR0,delayReg ;prescaler = 1024 (ATmega128) ;============================ TDelay: ldi delayReg,0 ;initialize timer/counter 0 out TCNT0,delayReg TLoop: in CntValue,TCNT0 cpi CntValue,0x63 brne Tloop ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)

Heres the program. I used a prescaler of 1024 to reduce the counters clock from 10 MHz to 10 kHz (111 in bits 2, 1, 0)

done ;=================================

5/11/2010

15

Example:
Write the initialization routine and the timing loop to form a delay of 10ms (assume a 10 MHz clock)
;======================================================== .def delayReg = r17 .def TCValue = r18 ;name registers ;=========================== Init: ldi delayReg,0x07 ;set initial parameters for counter out TCCR0,delayReg ;prescaler = 1024 (ATmega128) ;============================ TDelay: ldi delayReg,0 ;initialize timer/counter 0 out TCNT0,delayReg TLoop: in CntValue,TCNT0 cpi CntValue,0x63 brne Tloop ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)

Heres the program. I used a prescaler of 1024 to reduce the counters clock from 10 MHz to 10 kHz (111 in bits 2, 1, 0) Then load the TC with 0 to initialize the count (it starts on its own)

done ;=================================

5/11/2010

16

Example:
Write the initialization routine and the timing loop to form a delay of 10ms (assume a 10 MHz clock)
;======================================================== .def delayReg = r17 .def TCValue = r18 ;name registers ;=========================== Init: ldi delayReg,0x07 ;set initial parameters for counter out TCCR0,delayReg ;prescaler = 1024 (ATmega128) ;============================ TDelay: ldi delayReg,0 ;initialize timer/counter 0 out TCNT0,delayReg TLoop: in CntValue,TCNT0 cpi CntValue,0x63 brne Tloop ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)

Heres the program. I used a prescaler of 1024 to reduce the counters clock from 10 MHz to 10 kHz (111 in bits 2, 1, 0) Then load the TC with 0 to initialize the count (it starts on its own) Then we continuously read the TC (TCNT0) until its value is decimal 99 (or hex 63) if it does not have 63 in it yet, go back and read it again

done ;=================================

5/11/2010

17

Exercise:
Write the initialization routine and the timing loop to form a delay of 15ms (assume a 16 MHz clock)

5/11/2010

18

A Solution:
Write the initialization routine and the timing loop to form a delay of 15ms (assume a 16 MHz clock)
;======================================================== .def delayReg = r17 .def TCValue = r18 ;name registers ;=========================== Init: ldi delayReg,0x07 ;set initial parameters for counter out TCCR0,delayReg ;prescaler = 1024 (ATmega128) ;============================ TDelay: ldi delayReg,0 ;initialize timer/counter 0 out TCNT0,delayReg TLoop: in CntValue,TCNT0 cpi CntValue,0xEF brne Tloop ; read timer/counter value ; is it $EF? ; if not $63, read it again (until $EF)

Heres the program. I used a prescaler of 1024 again - to reduce the counters clock from 16 MHz to 16 kHz (111 in bits 2, 1, 0) Then load the TC with 0 to initialize the count (it starts on its own) Then we continuously read the TC (TCNT0) until its value is decimal 239 (or hex EF) if it does not have EF in it yet, go back and read it again

done ;=================================

5/11/2010

19

Longer Delays:
What if we need a longer delay?
Example: sec (500ms) or 1 sec (1000ms)

If we assume a 10 MHz clock, the prescaler will help us get down to 10 kHz
Timer/Counter increments every 100 us Timer/Counter must count to:
5,000 for sec 10,000 for 1 sec

5/11/2010

20

Longer Delays:
What if we need a longer delay?
Example: sec (500ms) or 1 sec (1000ms)

If we assume a 10 MHz clock, the prescaler will help us get down to 10 kHz
Timer/Counter increments every 100 us Timer/Counter must count to:
5,000 for sec 10,000 for 1 sec

8 bit counters can only count to 255


5/11/2010 21

Longer Delays:
To count to sec (500ms) or 1 sec (1000ms):
We need a nested loop Execute the delay loop more than once For example:
Assume a 10 MHz clock, a prescaler of 1024, and a count in the Timer/Counter to 255 (0 to 255 is a count of 256)
The TC increments every 100 us Once through the delay loop is 25.6 ms For a sec delay, we would need to execute the delay loop 500ms/25.6ms = 19.5 times (19 or 20 whichever is closer) For a 1 sec delay: 1000ms/25.6ms = 39 times

5/11/2010

22

Longer Delays:
Now, lets add the longer delay to the Light Chaser program.

5/11/2010

23

Enter Program
Original Program Statements New registers Timer/Counter Initialization Delay Instructions inserted to remove the blank caused by the C bit (see previous topic)

;======================================================== : documentation ;=========================== ; Declarations .device ATmega128 .def lights = r16 ;name registers .def delayReg = r17 .def counter = r18 .def CntValue = r19 ;=========================== Init: ldi lights,0b11111111 ;setup inputs and outputs for PortB out DDRB,lights ldi lights,0b10000000 ;set initial values for outputs out PortB,lights ldi delayReg,0x07 ;set initial parameters for counter out TCCR0,delayReg ;prescaler = 1024 (ATmega128) ;============================ ;Start Program Start: cpi lights,0 brne Next ldi lights,0b10000000 ;reset values for outputs Next: out PortB,lights ; sends data to Port B (1 lights LED) ror lights ; rotate bits once to the left ;================================= ;Time Delay TDelay: ldi counter,31 ;set initial # of times through delay loop ; 32 = .5 sec (64 = 1s) TLoop2: ldi delayReg,0 ;initialize timer/counter 0 out TCNT0,delayReg TLoop: in cpi brne dec brne rjmp CntValue,TCNT0 CntValue,255 TLoop counter TLoop2 Start ; read timer/counter value ; is it 0? ; if not 0, read it again (until 0) ; counting down to 0 for .5 sec

5/11/2010

24

Lights
Now the LEDs should appear as shown when we download this to the AVR board:

and then repeat

5/11/2010

25

Development Process
If we have followed the development process, we have:
Gathered and verified the requirements Laid out the plan (flowcharted) Chosen the target processor Written the program Assembled the program Now we have to simulate, but we have a new problem
5/11/2010 26

Development Process
If we single step through the program as before, it will take a long time to go through the delays Fortunately, we have other options
Set break points Run the program Lets start with the simplest: We get to the instruction

5/11/2010

27

Simulation
Open AVR Studio, Assemble the program

Best place to set a breakpoint is after the delay loop has finished executing

5/11/2010

28

Simulation
Open AVR Studio, Assemble the program

Best place to set a breakpoint is after the delay loop has finished executing To set the breakpoint: place the cursor at the command and click on the hand:

5/11/2010

29

Simulation
Open AVR Studio, Assemble the program

Best place to set a breakpoint is after the delay loop has finished executing To set the breakpoint: place the cursor at the command and click on the hand:

5/11/2010

30

Simulation
To start debugging, click Debug on the Debug Menu or click on the
(Hidden by menu)

5/11/2010

31

Simulation
To start, click on the Run button

5/11/2010

32

Simulation
To simulation will run to the breakpoint and stop
All affected registers will be updated

5/11/2010

33

Simulation
This will show us r18 (counter) counting down (it will take awhile)
Reset the program and change the breakpoint to the rjmp instruction

5/11/2010

34

Simulation
Each time you hit the Run button, youll see the I/O registers get updated
Now we should download it to the board and test it

5/11/2010

35

Summary
We:
Examined the Timer/Counter Register: TCNT0 Examined the Timer/Counter Control Register: TCCR0 Wrote a time delay for the previous program example: Light Chaser
Used the Timer/Counter Designed a sec. delay for lights on/off

5/11/2010

36

Das könnte Ihnen auch gefallen