In this tutorial we will show how to program ATmega32A microcontroller in Fast PWM mode. This is continued tutorial of the previous tutorial Atmega32A Timer Counter Tutorial Examples. In that tutorial we showed how to program ATmega32A microcontroller Timer/Counter0 in Normal mode and CTC mode.
For Fast PWM mode, the Timer/Counter is configured in Fast PWM mode using the WGM00 and WGM01 bits located in the TCCR0 register. After this we can configure the microcontroller to operate in two kind of Fast PWM mode. One is the non-inverted mode and the other is inverted mode. This mode of Fast PWM is configured with the COM00 and COM01 bits located in the TCCR0 register. We also configure other aspect of the microcontroller like the Pre-scalar value according to our need of output frequency or time delay.
First we have to decide the nature of our PWM signal and decide whether to use non-inverted Fast PWM or inverted Fast PWM mode. We need to know the required frequency of the output PWM signal(or the period) and the duty cycle of the PWM wave. In both the non-inverted and inverted Fast PWM modes, the OCR0 register is loaded with count value and timer is started. Once started, the PWM wave is produced at the OC0 pin which is the PORTB pin 3 in ATmega32A.
Non-Inverted Fast PWM
In the non-inverted Fast PWM mode, when the count value is loaded into OCR0 register and timer is started, the timer counts up until it reaches the OCR0 value. Then match occurs and the OC0 pin set low and stays low until the timer reaches the top value 0xFF at which points the OC0 pin is set high. This cane be seen in the following figure.
In the non-inverted Fast PWM mode, we can calculate the frequency of the output wave using the following equation.
\(F_{w}=\frac{F_{osc}}{256N}\) --------------->(1)
where, \(F_{w}\) is the frequency of the generated wave and N is the pre-scalar which can have value of 1, 8, 64, 256 and 1024.
For example, with 4MHz crystal oscillator, with no-prescalar we get frequency(Fw) of generated as 15.63KHz. You can use the ATmega32 Timer/Counter online calculator on this blog.
The OCR0 register is loaded with count value that depends upon the duty cycle of the output wave. The formula for value to be loaded into OCR0 register given duty cycle is given below.
\(OCR0 = \frac{256D}{100} - 1\) ------------------------>(2)
where D is the Duty cycle that range from 0% to 100%
For example with duty cycle of 75% we get OCR0 vale of 191.
Program Code for ATmega32A in non-inverted Fast PWM
In the following example we will create 15.63KHz PWM signal with duty cycle of 75%. For this we need to load OCR0 register with value of 191. How this values were obtained was explained just above.
#ifndef F_CPU
#define F_CPU 4000000UL
#endif
#include <avr/io.h>
int main()
{
DDRB |= (1<<PB3); //set PORT B pin 3 as output
OCR0 = 191;
TCCR0 |= (1<<WGM01) | (1<<WGM00) | (1<<COM01) | (1<<CS00); //Fast PWM, Non-Inverted, No-Prescalar
while(1);
return 0;
}
Inverted Fast PWM
In the inverted Fast PWM mode, the OCR0 is loaded with count value that is determined by the duty cycle of the output PWM wave. The timer is started and it counts up and when it reaches the value of OCR0, that is, when match occurs the OC0 pin output goes high and stays high until the timer count reaches the top value(0xFF for Timer/Counter0). When the timer count reaches the top value of 0xFF the TOV0 flag is set. This is illustrated in the picture below.
We can calculate the frequency of the output wave in inverted using the following equation.
\(F_{w}=\frac{F_{osc}}{256N}\) --------------->(1)
where, \(F_{w}\) is the frequency of the generated wave and N is the pre-scalar which can have value of 1, 8, 64, 256 and 1024.
For example, with 4MHz crystal oscillator, with 1/8 prescalar value we get frequency(Fw) of generated as 1.95KHz. You can also use the ATmega32 Timer/Counter online calculator on this blog.
Now, the OCR0 register is loaded with count value that is dependent upon the duty cycle of the required output wave. The formula to calculate count value to be loaded OCR0 register for given duty cycle is given below.
\(OCR0 = 255 - \frac{256D}{100}\) ------------------------>(2)
where D is the Duty cycle that range from 0% to 100%
For example with duty cycle of 40% we get OCR0 vale of 101.
Program Code for ATmega32A in inverted Fast PWM
The following program example will create 1.95KHz PWM signal with duty
cycle of 40%. For this we need to load OCR0 register with value of 101.
#ifndef F_CPU
#define F_CPU 4000000UL
#endif
#include <avr/io.h>
int main()
{
DDRB |= (1<<PB3); //set PORT B pin 3 as output
OCR0 = 101;
TCCR0 |= (1<<WGM01) | (1<<WGM00) | (1<<COM01) | (1<<COM00) | (1<<CS01); //Fast PWM, Inverted, 1/8 Prescalar
while(1);
return 0;
}
Next we will show how to program timer counter in Phase Correct PWM mode.