Monday, 16 July 2018

PWM(Pulse Width Modulation) in AVR Microcontroller (Atmega-8)

Aim:

Pulse Width Modulation (PWM) is a comparatively recent power switching technique for providing intermediate amounts of electrical power between fully on and fully off levels. Usually, digital pulses have same on and off time period, but in some situations we need the digital pulse to have more/less on time/offtime. In PWM technique, we create digital pulses with unequal amount of on and off state to get required intermediate voltage values.

Description:


 In my previous post, we have discussed the basic concepts of PWM. Let’s summarize it first:
  • PWM stands for Pulse Width Modulation.
  • It can be generated by comparing predetermined waveform with a reference voltage level or by making simple analog circuits.
  • Duty Cycle of a PWM waveform is given by the following relation.duty cycle
  • There are three modes of PWM operation – Fast PWM, Phase Correct PWM and Frequency and Phase Correct PWM
  • How to choose timer, operation mode and compare output mode for generating the desired PWM.
When you take a square wave, its on for a while and off for a while.  If we divide the on by the off and multiply by 100% we will get what is called a duty cycle.
Duty_Cycle = [ON_time / (ON_time + OFF_time) ] * 100
So if we are on for 1ms and then off for 1ms we will end up with a 50% duty cycle;  If we are on for 1ms and off for 3ms we end up with a 25% duty cycle.
Output_Voltage = Duty_Cycle * Input_Voltage
PWM examples
Now if we take our duty cycle and multiply it by our voltage we will get the output voltage.  So if we have a 5V power supply and we activate a PWM on a 25% duty cycle we will make an analog device behave as if it was receiving a 1.25V signal. Cool eh!?
Much like the counter functions PWM can be simulated in software however, the hardware version is preferred because it just sort of does its own thing and, with very little coding you can get a constant square wave going.
Remember the Prescaler? well its back in the PWM.  And much like in the counter, its roll is to slow things down.  This is good because it allows us to run the PWM at different frequencies.  This is important because some devices are sensitive to PWM speeds.  A motor for example will get hot if the PWM waveform is too fast, and will jitter if the PWM is too slow.  Since I already planted the question in your head, the answer is start at 10kHz.  Different motors like different frequencies but 10kHz will get you into the ball park.
The ATmega8 has 3 PWM outputs, 2 are located on timer/counter1 (16bit) and 1 is located on timer/counter2 (8bit).
As always, the output pin has the same limitations as any output (see the Digital Output Chapter for details).
This mode is recommended for motor control.
The frequency of the Phase Corrected PWM can be calculated by the following equation.
PWM_frequency = clock_speed / ( Prescaller_value * 510 )
 7 bit 6 bit  5 bit  4 bit  3 bit  2 bit  1 bit  0 bit
 TCCR2FOC2WGM21COM21COM20WGM20 CS22 CS21CS20
Timer/Counter Control Register 2
 CS22 CS21  CS20  DESCRIPTION
000 Timer/Counter2 Disabled
001 No Prescaling
010 Clock / 8
011 Clock / 32
100 Clock / 64
101 Clock / 128
110 Clock / 256
111 Clock / 1024
CS bits
 MODEWGM21WGM20  DESCRIPTION
000 Normal
101 PWM Phase Corrected
210 CTC
311 Fast PWM
Waveform Generator Mode bits
COM21COM20  DESCRIPTION
00 OC2 disabled
01 Reserved
10 None-inverted mode (HIGH at bottom, LOW on Match)
11 Inverted mode (LOW at bottom, HIGH on Match)
Applies only to PWM modes
 7 bit 6 bit  5 bit  4 bit  3 bit  2 bit  1 bit  0 bit
 TIMSK OCIE2TOIE2TICIE1OCIE1AOCIE1B TOIE1 –TOIE0
Timer/Counter Interrupt Mask Register
 7 bit 6 bit  5 bit  4 bit  3 bit  2 bit  1 bit  0 bit
 TIFR OCF2TOV2ICF1OCF1AOCF1B TOV1 –TOV0
Timer/Counter Interrupt Flag Register
 7 bit 6 bit  5 bit  4 bit  3 bit  2 bit  1 bit  0 bit
 TCNT2
Timer/Counter Register (stores the counter value)
 7 bit 6 bit  5 bit  4 bit  3 bit  2 bit  1 bit  0 bit
 OCR2
Output Compare Register (stores the compare value)

Block Diagram

pwm

Schematic

pwm

Code

// ***********************************************
// Project: Interfacing PWM to atmega8
// Author: Hack Projects India
// Module description: Operate array of LED's
// ***********************************************

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>

void pwminit(void)
{
 TCNT1=0x00;//Initial counter value is 0
 TCCR1B = 0x01;//Timer with no prescalling
 TCCR1A = (1<<COM1A0) | (1<<COM1A1) |(1<<COM1B0) | (1<<COM1B1) | (1<<WGM10) | (0<<WGM11);// Timerr PWM mode
}

int main(void)
{
 int count=0;
 DDRC=0x00;
 DDRB=0xff;
 pwminit();
 OCR1A=255;
 OCR1B=255;
 while(1)
 {
  _delay_ms(50);
  OCR1A=count;
  count++;
  if(count>255)
  count=0;
 }
}

Downloads:

The code was compiled in Atmel Studio 6 and simulation was made in Proteus v7.7.
To download code and proteus simulation click here.

Further Reading suggestions:

No comments:

Post a Comment