October 16, 2011

Fast Pwm mode of avr timers


Hello folks, I once needed to generate PWM wave  in my project related to power inverter design, I had to generate PWM waveforms according to the potentiometer varied by the user.
For that first method which I adopted was discussed earlier post but now here is another sophisticated method which I came across while studying the datasheet of mine microcontroller (mine favorite Atmega 8535).I came across the PWM modes given inbuilt in AVR series.
There are three modes of generating PWM in Atmega8535
1)Clear timer on compare(CTC) mode.

2)fast PWM mode

3)Phase correct PWM mode.


You can select any of them according to your requirement as in my requirement I had to select fast PWM mode.

Here are the steps given to configure your timer in fast PWM mode…..

Step 1) set Port in output mode
                                As the PWM generated would be given to output pin first of all that pin must be taken to output mode.the PIN where PWM is to be generated depends on the timer which you use to generate PWM. The pin OCn would be your output pin if you are using Timer-n. you can find the location of pin from datasheet.

Step 2) Set TCCRn register
                                You have to configure your timer in prescaler mode, OCn pin in inverting or non-inverting mode, selection of PWM mode etc. can be configured just within one register.
Step 3) Change the value of OCRn register in run time to generate PWM whatever you want…
Now your timer is configured to work with PWM mode
As I discussed earlier if we want to have a variable resistor  that can generate variable PWM for that we have to access ADC given in Atmega.

For adc initialization you have to do following steps
Step 1)  Initialize adc
                                You can do it by ADCSRA register you have to Enable, prescale and set interrupt .
Step 2)give ADC channel no
                                This no is given in ADMUX register.
Step 3)start conversion
                                Setting ADSC bit in ADCSRA register will do this thing.
Step 4) give it some time to convert and then read the result from ADCH and ADCL register.


Now you are done to interface your ADC with Timer

A sample code which I had used is given below.
#include<avr/io.h>
#include<delay.h>
void adc_init()
 {
ADCSRA=0X86;                              //ADC enable, ADC interrupt enable, set prescaller to 64
 }
 unsigned char getdata(unsigned char chno)        
  {
    ADMUX=0X60;                                       //right align the ADC result
    ADMUX|=chno;                                      //select the ADC channel
    ADCSRA|=0X40;                                     //start ADC convertion
    delayms(1);                                             //give some time delay to complit the ADC convertion
            return ADCH;
  }

void main()
{          unsigned char pot=0;
            adc_init();
             SREG=SREG|0x80;//global interrupt enable
             DDRB=0XFF;          //set data direction as output
TCCR0=TCCR0|0x7A;       //fast pwm,inverting mode,8 prescaler
while(1)
             {
             delayms(10);
             OCR0= getdata(0);          //read value from pot to OCR0
            }
}

Link to .zip file containing source code and Proteus ISIS design is this.
and datasheet of Atmega 8535 can be found from here.


if any question  then you can post a comment. 

10 comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...