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:

  1. Thats a great job u did out there. I am working with a similar project. But its 3phase inverter wth SPWM control. I cant figure out how to generate 3 simultaneous pwms with required phase difference amongst them.

    ReplyDelete
    Replies
    1. thanks for appreciation, you can generate pulses with the help of pwm mode of timers that is for sure...

      but to generate pulses with different phases you have to run timer with several time delay...

      like
      the pseudo code for that would be
      {
      turn timer0 on
      delay
      turn timer1 on
      delay
      turn timer2 on
      }

      here delay between "timer on" can be calculated with the help of phase difference you want....

      I had also similar problem on my project i had to make 2 pulses at 180 phase so i used timer such a way that one is inverting and other is non inverting...
      you can see
      http://keyuracharya.blogspot.in/2012/03/power-inverter-pwm-avr-time.html
      just download source code and have a look..


      do i make a sense to you?
      please leave a comment.

      Delete
    2. Yeah i understood what u were trying to explain. i will try it out and let u know. In the mean time if u can make a post relating to 3phase inverter then it will be appreciated.

      Delete
  2. can i use this code for atmega16 without any modification ..?/

    ReplyDelete
    Replies
    1. yes, as Atmega 8535 and atmega 16 are of same series and pin to pin compatible they are also "code to code" compatible....

      use this code, have fun....

      Delete
    2. thanks Keyur ...Can u provide the simulation of whole inverter ??

      Delete
    3. yes, i am having proteus simulation of whole inverter..
      but nowadays i am so busy with project so don't have time to write blog as soon as i get time i will update the blog...

      Delete
    4. http://keyuracharya.blogspot.in/2012/03/power-inverter-pwm-avr-time.html

      check this out

      Delete
  3. thank you for your expplanations to the mikcocontrollerr. i just copied the sourcecodeexample from:

    http://www.electronicsplanet.ch/mikrocontroller/avrcodesammlung/atmega16timer0fastpwm.htm

    and it worked. but thanks to your explanations, i understand, why it is working ;-)

    ReplyDelete
  4. can you help me to now about timer 0 in pic 16f877

    ReplyDelete

Related Posts Plugin for WordPress, Blogger...