Beruflich Dokumente
Kultur Dokumente
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
5/11/2010
Timer/Counter
Open the ATmega128 Manual
5/11/2010
Timer/Counter
8-Bit Timer/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
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
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:
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