Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Understanding AVR Timers and PWM

Status
Not open for further replies.

Tahmid

Advanced Member level 6
Joined
Jun 17, 2008
Messages
4,756
Helped
1,798
Reputation
3,588
Reaction score
1,656
Trophy points
1,413
Location
Berkeley, California
Activity points
30,586
Hi all,
I'll try to explain AVR PWM and Timers so that it can be used as a reference.

To start off with, the formulae relating duty cycle, frequency and time period is: f=1/T, D=t/T where D is duty cycle, T is time period, t is on time, f is frequency
Vo = D * Vin, where Vo = average voltage output from AVR pin, D = duty cycle, Vin = Supply Voltage, eg 5v
The output voltage here is in the form of pulses not a complete analog value.
Eg. When frequency is 100Hz, duty cycle is 50% and supply voltage to AVR is 5v, then output from AVR pin is 2.5v. However, this does not mean that the output will be 2.5v DC. The output will be a pulsating output with frequency = 100Hz, 50% on, 50% off, with high state or on state voltage = 5v, low state or off state voltage = 0v. Therefore output = 2.5v, but actually 5v with 50% on and 50% off. This CAN be converted to pure DC by placing an RC or LC filter, which will convert the pulsating DC to a clean fixed DC voltage.
I will refer to ATMEGA8 for example, as this seems to be one of the most popular AVRs.
There are 3 timers – Timer/Counter 0, Timer/Counter 1 and Timer/Counter 2. I will refer to Timer/Counter as TC, so TC0 means Timer/Counter 0.
TC0 and TC2 are 8-bit timers. This means that the timers will count from 0 to (2^8) – 1 = 255. TC2 has one associated compare module. TC1 is 16-bit, so it counts from 0 to (2^16)-1 = 65535. It has two compare modules attached and provides a rich set of PWM functions.
I’ll start off with TC0.
TC0 has 4 registers associated with it that we need to work with. The most important is Timer/Counter 0 Control Register – TCCR0.

Take a look at the registers below:



The CS2, CS1 and CS0 bits determine the rate at which the value of the TC increments. Say we have a clock of 10MHz. Therefore we have a clock cycle = T = 1/F = 1/10MHz = 100ns. Prescaler extends this time by a specific amount. So, looking at TCCR0, if we write 0 to it, we have no clock source, this means the TC is stopped and will not increment. It retains its current value.
If we set CS[2…0] to 1, we have no prescaler, that means that the TC increments each 100ns, ie each clock cycle. If we assign prescaler 8, by writing 2 to CS[2…0], we extend the time at which TC increments by 8. With no prescaling it would take 1 clock cycle for each increment, therefore with a prescaler of 8, the time would be extended 8 times, ie, it would now take 8 clock cycles for each increment, ie 800 ns.
The same follows for prescaler values of 64, 256 and 1024.
Eg. With a clock cycle of 10MHz, prescaler = 1024, the time taken by TC0 for one increment is:
Time for 1 increment with no prescaling = 1 clock cycle = 1/10MHz = 100ns
Therefore, time for 1 increment with prescaler = 1024 = 1024 clock cycles = 1024*0.1us = 102.4 us
[us = microseconds, ns = nanoseconds]
I will not explain the external clock source as it is not required for PWM.


Take a look at the registers below:


The second associated register is TCNT0 that holds the current value of TC0.
E.g. What will be the value in TCNT0 when CS[2…0] is cleared (=0) after a time of 10secs? Clock = 1MHz, prescaler = 8.
Solution:
Each clock cycle = 1/1MHz = 1us [us = microsecond]
TC0 is incremented (if prescaler = 0) each clock cycle, ie each us(microsecond)
Therefore TC0 is incremented (when prescaler = 0) each 8 clock cycles, ie each 8 us(microsecond)
10 seconds = 10,000,000 microseconds
TC0 counts to a maximum of 255. That’s 255 increments. After this it overflows, ie, it rolls over from TOP [TOP means the maximum value to which TC0 can increment], in this case 255, to 0.
Each increment takes 8 us.
Therefore 256 increments (255 increments + 1 increment to overflow to 0) takes 256 * 8us = 2048us = 2.048ms [ms = milliseconds] = 0.002048 seconds
Therefore in 10 seconds, number of overflows = (10/0.002048) = 4882.8125
That’s 4882 overflows. There’s a remainder, 0.8125, which means a remainder of 0.8125*255 = 207.1875
Therefore 207 is stored in TC0.


Take a look at the registers below:


The third associated register is TIMSK – Timer/Counter Interrupt Mask Register. Here bit 0 is what is associated with TC0. TOIE0 – Timer/Counter Overflow Interrupt Enable 0. Setting this bit enables setting TC0 interrupt. I’ll go into details about this later.


Take a look at the registers below:


The last associated register is TIFR – Timer/Counter Interrupt Flag Register. Here bit 0 is what is associated with TC0. TOV0 = Timer/Counter Overflow Flag 0. This flag is set whenever the timer overflows (this has been shown in the above example). Writing one to this bit clears it.


There's more to come about the Timer PWM modes and Timer1 and Timer2 and all PWM modes.

registers.PNG


Please check out my blog at: Tahmid's blog

Hope this is helpful to all.
Tahmid.
 

Nice. Where did you get this information from?
 

Hi sv1437,
I wrote this up by myself. I plan to expand this to make it a complete reference, but I can't find the time to complete it.
 

Hi all,
I'll try to explain AVR PWM and Timers so that it can be used as a reference.

To start off with, the formulae relating duty cycle, frequency and time period is: f=1/T, D=t/T where D is duty cycle, T is time period, t is on time, f is frequency
Vo = D * Vin, where Vo = average voltage output from AVR pin, D = duty cycle, Vin = Supply Voltage, eg 5v
The output voltage here is in the form of pulses not a complete analog value.
Eg. When frequency is 100Hz, duty cycle is 50% and supply voltage to AVR is 5v, then output from AVR pin is 2.5v. However, this does not mean that the output will be 2.5v DC. The output will be a pulsating output with frequency = 100Hz, 50% on, 50% off, with high state or on state voltage = 5v, low state or off state voltage = 0v. Therefore output = 2.5v, but actually 5v with 50% on and 50% off. This CAN be converted to pure DC by placing an RC or LC filter, which will convert the pulsating DC to a clean fixed DC voltage.
I will refer to ATMEGA8 for example, as this seems to be one of the most popular AVRs.
There are 3 timers – Timer/Counter 0, Timer/Counter 1 and Timer/Counter 2. I will refer to Timer/Counter as TC, so TC0 means Timer/Counter 0.
TC0 and TC2 are 8-bit timers. This means that the timers will count from 0 to (2^8) – 1 = 255. TC2 has one associated compare module. TC1 is 16-bit, so it counts from 0 to (2^16)-1 = 65535. It has two compare modules attached and provides a rich set of PWM functions.
I’ll start off with TC0.
TC0 has 4 registers associated with it that we need to work with. The most important is Timer/Counter 0 Control Register – TCCR0.

Take a look at the registers below:



The CS2, CS1 and CS0 bits determine the rate at which the value of the TC increments. Say we have a clock of 10MHz. Therefore we have a clock cycle = T = 1/F = 1/10MHz = 100ns. Prescaler extends this time by a specific amount. So, looking at TCCR0, if we write 0 to it, we have no clock source, this means the TC is stopped and will not increment. It retains its current value.
If we set CS[2…0] to 1, we have no prescaler, that means that the TC increments each 100ns, ie each clock cycle. If we assign prescaler 8, by writing 2 to CS[2…0], we extend the time at which TC increments by 8. With no prescaling it would take 1 clock cycle for each increment, therefore with a prescaler of 8, the time would be extended 8 times, ie, it would now take 8 clock cycles for each increment, ie 800 ns.
The same follows for prescaler values of 64, 256 and 1024.
Eg. With a clock cycle of 10MHz, prescaler = 1024, the time taken by TC0 for one increment is:
Time for 1 increment with no prescaling = 1 clock cycle = 1/10MHz = 100ns
Therefore, time for 1 increment with prescaler = 1024 = 1024 clock cycles = 1024*0.1us = 102.4 us
[us = microseconds, ns = nanoseconds]
I will not explain the external clock source as it is not required for PWM.


Take a look at the registers below:


The second associated register is TCNT0 that holds the current value of TC0.
E.g. What will be the value in TCNT0 when CS[2…0] is cleared (=0) after a time of 10secs? Clock = 1MHz, prescaler = 8.
Solution:
Each clock cycle = 1/1MHz = 1us [us = microsecond]
TC0 is incremented (if prescaler = 0) each clock cycle, ie each us(microsecond)
Therefore TC0 is incremented (when prescaler = 0) each 8 clock cycles, ie each 8 us(microsecond)
10 seconds = 10,000,000 microseconds
TC0 counts to a maximum of 255. That’s 255 increments. After this it overflows, ie, it rolls over from TOP [TOP means the maximum value to which TC0 can increment], in this case 255, to 0.
Each increment takes 8 us.
Therefore 256 increments (255 increments + 1 increment to overflow to 0) takes 256 * 8us = 2048us = 2.048ms [ms = milliseconds] = 0.002048 seconds
Therefore in 10 seconds, number of overflows = (10/0.002048) = 4882.8125
That’s 4882 overflows. There’s a remainder, 0.8125, which means a remainder of 0.8125*255 = 207.1875
Therefore 207 is stored in TC0.


Take a look at the registers below:


The third associated register is TIMSK – Timer/Counter Interrupt Mask Register. Here bit 0 is what is associated with TC0. TOIE0 – Timer/Counter Overflow Interrupt Enable 0. Setting this bit enables setting TC0 interrupt. I’ll go into details about this later.


Take a look at the registers below:


The last associated register is TIFR – Timer/Counter Interrupt Flag Register. Here bit 0 is what is associated with TC0. TOV0 = Timer/Counter Overflow Flag 0. This flag is set whenever the timer overflows (this has been shown in the above example). Writing one to this bit clears it.


There's more to come about the Timer PWM modes and Timer1 and Timer2 and all PWM modes.

registers.PNG


Please check out my blog at: Tahmid's blog

Hope this is helpful to all.
Tahmid.



I read your material and looks interesting. I also doing the project something like this. I have a question. For instance I have an analogue input of 0V up to
3.5V(for AVR micro controller,Atmega32). And I want a PWM output of these values.What should I do.what initializations has to be done first on the C code.

when I have, for instance 2.5V at the input, I want to get at the output the PWM of this value.

Thanks in advance

Million
 

Hi,
You need to read the input value using the ADC and store it in a variable. Then you need to initialize PWM and set the TOP to select a high frequency (a few 10s of kiloHertz). Using the reading from the ADC, process it so that it is between 0 and TOP and the % it is of TOP will determine the output voltage. Then use an RC or LC filter at the output.

Hope this helps.
Tahmid.
 

Hi tahmid,

Nice,

Say that the frequency of PWM is 44100 Hz,
How is the design of RC Filter ?

As my understanding, Is it true that the PWM also consists of sinus wave with variety of frequency.
So, when the PWM frequency is 44100Hz, the analog waveform sinus would also become in 44100Hz ?
( the analog waveform is the reconstruction of sinusoid wave which is allowed by low pass filter to flow)
Thus, the filter change the attenuation ?

Thanks in advance
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top