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.