Sunday, August 17, 2014

AVR Tutorial - PWM Signal Generation using Timers


In AVR microcontrollers PWM is implemented in hardware, all that left is configure it, by setting required bits in timer registers.

Timer has several compare registers OCR**, and when value in timer will match OCR**, 2 things may happen:
  • Interrupt
  • Changes value on the OC** pin.
OC** pins are used for PWM
We will configure PWM, so when counter == OCR** voltage on corresponfing pin will change from 5 to 0 Volt. When timer will count to final value and starts counting from 0, our pin voltage will change from 0 to 5 Volts. If we connect that pin to oscilloscope we will se square impulses.

There are 3 general types of PWM:

СТС (Clear Timer on Compare) - when timer counts to OCR**, value in OC** pin is changed and timer starts counting from 0. So our PWM always has 50% duty cycle (50% of time we have 0 on output and other 50% we have 1).

Fast PWM - counter ticks from 0 to TOP (some max value 8-bit == 255), sets OC** pin high, after that it starts counting from 0. When timer == OCR**, corresponding OC** pin is cleared.

Phase Correct PWM - Here timer counts from 0 to TOP, after that it counts backward till 
0 and the process repeats. At the first match OCR** with timer our OC** pin is cleared and at the second it is set to high (1).

It is used to keep phase the same when we change PWM duty cycle.


Main registers are TCCR1A and TCCR1B. 





If we want to work with OC1A pin we set bits COM1A1 and COM1A0 
"/" means OR. TCNT1 == OCR1A for PWM on pin OC1A


Top - maximum value that timer can have, after that it starts counting from 0 and corresponding OC** pins will change their state.


#define F_CPU 8000000UL

#include <avr/io.h>
#include <util/delay.h>

int main()
{
 DDRD = 0xFF;
 OCR1A=0xC0;   // Сompare with this values
 OCR1B=0x40;

 //Configure PWM and timer
 TCCR1A|=(1<<COM1B1)|(0<<COM1B0)|(1<<WGM10)|(0<<WGM11)|(1<<COM1A1)|(0<<COM1A0);
 TCCR1B|=(1<<WGM12)|(0<<WGM13)|(1<<CS10);

 while(1);
}

Here we configured our timer, he ticks with the same frequency as our MC (more about timers here), now we have Fast PWM 8 Bit, in addition OC1A pin is cleared when TIMER1 ==  OCR1A and OC1B pin is cleared when TIMER1 == OCR1B.



OCR1A=0xC0;  Blue
OCR1B=0x40;  Yellow

As we can see from oscilloscope, blue signal has more duty cycle, because when counter counts to 255, it sets 1 on OC1A (OC1B) pin and starts counting from 0, but when timer == OCR1A (OC1B), it clears OC1A (OC1B) pin.

0xC0 >0x40 that's why OC1B sets to 0 faster.

Sources:
easyelectronics.ru
samou4ka.net
roboforum.ru/wiki/

No comments :

Post a Comment