Topic 19 PWM
Topic 19 PWM
Topic 19 PWM
Objectives
To understand the operation of an 8 bit timer/counter in an AVR microcontroller To understand how to use the timer/counter to generate a PWM signal To understand how PWM signals are used to control servo motors
Position control Speed control
3/25/2010
Modes of Operation
Four modes of operation for Timer/Counter 0
Normal Mode:
we have used this mode to develop timing loops
CTC Mode:
Clear Timer on Compare Match
Fast PWM:
Fast Pulse Width Modulation
3/25/2010
Modes of Operation
We will discuss:
Normal Mode on Timer/Counter 0 (8 bit counter):
we have used this mode to develop timing loops
3/25/2010
Normal Mode
Example Timing Loop
Init: ldi r16,0x07 out TCCR0,r16 ;============================ TDelay: ldi r16,0 out TCNT0,r16 in r17,TCNT0 cpi r17,0x63 brne Tloop ; set the prescaler for the counter ; prescaler = 1024 (ATmega128) ; initialize timer/counter 0 ; starts the counter ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)
TLoop:
done ;=================================
3/25/2010
Normal Mode
TCCR0
Init: ldi r16,0x07 out TCCR0,r16 ;============================ TDelay: ldi r16,0 out TCNT0,r16 in r17,TCNT0 cpi r17,0x63 brne Tloop ; set the prescaler for the counter ; prescaler = 1024 (ATmega128) ; initialize timer/counter 0 ; starts the counter ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)
TLoop:
We are most concerned with bits 2, 1, and 0. They control the prescaler
done ;=================================
3/25/2010
Normal Mode
TCCR0
We can turn off the counter We can use the system clock or We can use a slower signal based on the system clock
3/25/2010
Normal Mode
TCCR0
System Clock (assume 10MHz) If we used the system clock (no prescaling) to increment the counter, it would be incremented every 100ns T = 1/fclk = 1/10MHz = 100ns
3/25/2010
Normal Mode
TCCR0
System Clock (assume 10MHz) If we used a prescaler of 8 to increment the counter, it would be incremented every 8th clock pulse Tclk * 8 = 100ns*8 = 800ns
3/25/2010
Normal Mode
TCCR0
System Clock (assume 10MHz) If we used a prescaler of 1024 to increment the counter, it would be incremented every 1024th clock pulse Tclk * 1024 = 100ns*1024 = 102.4us
3/25/2010
10
Normal Mode
Example Timing Loop
Init: ldi r16,0x07 out TCCR0,r16 ;============================ TDelay: ldi r16,0 out TCNT0,r16 in r17,TCNT0 cpi r17,0x63 brne Tloop ; set the prescaler for the counter ; prescaler = 1024 (ATmega128) ; initialize timer/counter 0 ; starts the counter ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)
Step 1: Initialize the Timer/Counter We used a prescaler of 1024, so bits 0-7 in the Timer/Counter Control Register were set to 1
TLoop:
done ;=================================
3/25/2010
11
Normal Mode
Example Timing Loop
Init: ldi r16,0x07 out TCCR0,r16 ;============================ TDelay: ldi r16,0 out TCNT0,r16 in r17,TCNT0 cpi r17,0x63 brne Tloop ; set the prescaler for the counter ; prescaler = 1024 (ATmega128) ; initialize timer/counter 0 ; starts the counter ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)
TLoop:
done ;=================================
3/25/2010
12
Normal Mode
Example Timing Loop
Init: ldi r16,0x07 out TCCR0,r16 ;============================ TDelay: ldi r16,0 out TCNT0,r16 in r17,TCNT0 cpi r17,0x63 brne Tloop ; set the prescaler for the counter ; prescaler = 1024 (ATmega128) ; initialize timer/counter 0 ; starts the counter ; read timer/counter value ; is it $63? ; if not $63, read it again (until $63)
Step 2: Start the Timer/Counter Step 3: check for the calculated value In this case, the Timer/Counter will increment its count every 1024 clock pulses (every 102.4 us). This loop keeps checking until the Timer/Counter gets to 99 (0x63). So the timer delays for: 100 * 102.4 us = 10.24ms
Note: count from 0 to 99 is 100
TLoop:
done ;=================================
3/25/2010
13
3/25/2010
14
Phase Correct
1 PWM
3/25/2010
15
TNCT0: Timer/Counter 0
To hold the value of the counter
3/25/2010
16
3/25/2010
17
And starts counting up 0 Initial Timer/Counter value is 0 (gets the counter started)
3/25/2010
18
3/25/2010
19
0 Initial Timer/Counter value is 0 (gets the counter started) Then it will count down to 0
3/25/2010
20
0 Initial Timer/Counter value is 0 (gets the counter started) Then it will count down to 0, then up to some maximum .
3/25/2010
21
0 Initial Timer/Counter value is 0 (gets the counter started) Then it will count down to 0, then up to some maximum, then down to 0 .
3/25/2010
22
0 Initial Timer/Counter value is 0 (gets the counter started) Then it will count down to 0, then up to some maximum, then down to 0, etc.
3/25/2010
23
OCR0
The timer will count up, eventually getting to the value in OCR0. It will then continue to count to 0xFF and then start counting down, eventually getting to the value in OCR0 again, then continuing its count down to 0.
3/25/2010
24
OCR0
0
Output signal on OC0
Every time the Timer/Counter gets to the value in OCR0, the output (on OC0) toggles
3/25/2010
25
OCR0
0
Output signal on OC0: Non-inverted
Every time the Timer/Counter gets to the value in OCR0, the output (on OC0) toggles Setting the COM01:0 bits (in TCCR0) to 2 will produce a non-inverted PWM. An inverted PWM output can be generated by setting the COM01:0 to 3
3/25/2010
26
Calculations
The big questions:
How do we calculate the values:
How do we calculate which prescaler value to use? How do we calculate the value OCR0?
Lets assume we are using the positioning servo motor shown on the next page2
3/25/2010
27
Calculations
3 pins: Gnd, Vcc, and Control
3/25/2010
28
Calculations
3 pins: Gnd, Vcc, and Control
The PWM signal should have a period of 10 to 30ms. A pulse 0f 1.5ms sets the neutral position (90), 1ms sets the left position (0) and 2ms sets the right position (180)
3/25/2010
29
Calculations
To calculate the prescaler, the ATMega data sheet gives the following formula (pg102)
fclk foc 0 = N *510
3/25/2010
30
Calculations
To calculate the prescaler, the ATMega data sheet gives the following formula (pg102)
fclk foc 0 = N *510
Assuming we have a system clock of 10MHz and we are using a prescaler of 1024, we would have:
3/25/2010
31
Calculations
To calculate the prescaler, the ATMega data sheet gives the following formula (pg102)
fclk foc 0 = N *510
Assuming we have a system clock of 10MHz and we are using a prescaler of 256, we would have:
3/25/2010
32
Calculations
If we had a system clock of 16MHZ, we would have:
16 x106 foc 0 = 1024*510
foc 0 = 3063Hz Toc 0 = 32.64ms
A little too long. But, lets go back to the 10MHz system clock and the 77Hz (13ms period) OC0 clock
3/25/2010
33
OCR0
0
Output signal on OC0: Non-inverted
Its probably easier to use a non-inverted signal. Set COM01:0 to 2 (in TCCR0), CS02:0 to 7 for a prescaler of 1024, and WGM01 to 0 and WGM00 to 1 for PC PWM.
3/25/2010
34
OCR0
0
Output signal on OC0: Non-inverted
A full count: from OCR0 to Max, down to 0 (through OCR0), and then back up to OCR0 would be one cycle (highlighted above). This represents a count of 256 twice or a count to 512 which represents 13ms (1/77Hz), so a count to 40 represents about 1 ms (0) count from 20 down to 0 and up to 20 (total of 40) OCR0=20 a count to 59 represents about 1.5ms (90) count from 30 down to 0 and then up to 30 (total of 60) OCR0=30 a count to 78 represents about 2ms (180) count from 39 down to 0 and up to 39 (total of 78) OCR0=39
3/25/2010
35
Speed Control
3/25/2010
36
3/25/2010
37
3/25/2010
38
3/25/2010
39
3/25/2010
40
3/25/2010
41
0 Output1
3/25/2010
42
0 Output1
Output2
3/25/2010
43
3/25/2010
44
Forward
Reverse
3/25/2010
45
Forward
Reverse
3/25/2010
46
Speed control is achieved by rapidly switching the motor between two states in the table. Suppose we keep PD6 high (at 5 V, also called a logical 1) and have PD5 alternate quickly between low (0 V or 0) and high. The motor driver will switch between the forward and brake states, causing M1 to turn forward at a reduced speed. For example, if PD6 is high two thirds of the time (a 67% duty cycle), then M1 will turn at approximately 67% of its full speed. Since the motor voltage is a series of pulses of varying width, this method of speed control is called pulse-width modulation (PWM). An example series of PWM pulses is shown in the graph at right: as the size of the pulses decreases from 100% duty cycle down to 0%, the motor speed decreases from full speed down to a stop.3
3/25/20 10
47
In the 3pi, speed control is accomplished using special PWM outputs of the main microcontroller that are linked to the internal timers Timer0 and Timer2. This means that you can set the PWM duty cycle of the two motors once, and the hardware will continue to produce the PWM signal, in the background, without any further attention. The set_motors() function in the Pololu AVR Library (see Section 6.a for more information) lets you set the duty cycle, and it uses 8bit precision: a value of 255 corresponds to 100% duty cycle. For example, to get 67% on M1 and 33% on M2, you would call: 3
Note: 171 = 67% of 255 and 84 = 33% of 255
set_motors (171,84);
3/25/20 10
48
In the 3pi, speed control is accomplished using special PWM outputs of the main microcontroller that are linked to the internal timers Timer0 and Timer2. This means that you can set the PWM duty cycle of the two motors once, and the hardware will continue to produce the PWM signal, in the background, without any further attention. The set_motors() function in the Pololu AVR Library (see Section 6.a for more information) lets you set the duty cycle, and it uses 8bit precision: a value of 255 corresponds to 100% duty cycle. For example, to get 67% on M1 and 33% on M2, you would call: 3 set_motors (171,84);
Note: To get a slowly decreasing PWM sequence like the one shown in the graph, you would need to write a loop that gradually decreases the motor speed over time.
3/25/20 10
49
PWM on Timer/Counter 1
(a 16-bit Timer/Counter)
3/25/2010
50
Phase Correct
1 PWM
51
There are 3 OC1x pins on which the generated PWM signals may appear
OC1A, OC1B, OC1C
3/25/2010
52
TNCT1: Timer/Counter 1
To hold the value of the counter
3/25/2010
53
OCR1x
Every time the Timer/Counter gets to the value in OCR1x, the output (on OC1x) toggles There are three OCR1x registers (OCR1A, OCR1B, and OCR1C) There are three OC1x output lines (OC1A, OC1B, and OC1C)
3/25/2010
54
Calculations
To calculate the prescaler, the ATMega data sheet gives the following formula (pg129)
foc1PWM fclk = 2* N * TOP
TOP is the value in ICR1 For this example, assume a 16MHz system clock and the same servo as before
3/25/2010
55
Calculations
3 pins: Gnd, Vcc, and Control
The PWM signal should have a period of 10 to 30ms. A pulse 0f 1.5ms sets the neutral position (90), 1ms sets the left position (0) and 2ms sets the right position (180)
3/25/2010
56
Calculations
For this example1, assume a 16MHz system clock, and that we want a 20ms period (f=50Hz) We need to calculate the value for TOP
foc1PWM fclk = 2* N * TOP
3/25/2010
57
Calculations
For this example TOP could be:
Prescaler N = 1 then TOP(ICR1) = 160000 Prescaler N = 8 then TOP(ICR1) = 20000 Prescaler N = 64 then TOP(ICR1) = 2500 Prescaler N = 256 then TOP(ICR1) = 625 Prescaler N = 1024 then TOP(ICR1) = 156.25
3/25/2010
58
Calculations
For this example TOP could be:
Prescaler N = 1 then TOP(ICR1) = 160000 Prescaler N = 8 then TOP(ICR1) = 20000 Prescaler N = 64 then TOP(ICR1) = 2500 Prescaler N = 256 then TOP(ICR1) = 625 Prescaler N = 1024 then TOP(ICR1) = 156.25 You cannot use prescaler 1 or 1024 to generate a 50 Hz PWM with a 16 MHz system clock: Prescaler 1 cannot be used since 160000 too large to fit in TCR1. (TCR1 is a 16 bit register with a range from 0 to 65535) Prescaler 1024 should not be used since you cannot put decimals into ICR1 (although you could approximate with 156)
3/25/2010 59
Calculations
Chambers1 suggests:
A prescaler of 8 Set ICR1 to 20000.
This will allow you to change OCR1A between 1000 and 2000 to obtain 1 - 2 ms high pulses.
Simple, even numbers
3/25/2010
60
3/25/2010
61
3/25/2010
62
3/25/2010
63
3/25/2010
64
3/25/2010
65
3/25/2010
66
3/25/2010
67
3/25/2010
68
3/25/2010
69
3/25/2010
70
while (1) { OCR1A = 1000; delay_ms (5000); OCR1A = 2000; delay_ms (5000); };
//position the servo to the left 0 degrees //delay for 5 seconds //position the servo to the right 180 degrees //delay for 5 seconds
3/25/2010
71
Summary
In this topic we discussed:
The operation of an 8 bit timer/counter in an AVR microcontroller How to use the timer/counter to generate a PWM signal How PWM signals are used to control servo motors
Position control Speed control
3/25/2010
72