AMERICAN INTERNATIONAL UNIVERSITY – BANGLADESH (AIUB)
Where leaders are created
Pulse Width Modulation (PWM)
Department of EEE
Microprocessor and Embedded Systems
PWM
Pulse Width Modulation, or PWM, is a technique for getting analog results with
digital means. Digital control is used to create a square wave, a signal switched
between on and off. This on-off pattern can simulate voltages in between the full VCC
of the board (e.g., 5 V on UNO) and off (0 Volts). The duration of "on time" is called
the pulse width. To get varying analog values, the pulse width can be varied. If this
on-off pattern is repeated fast enough with an LED, for example, the result is as if the
signal is a steady voltage between 0 and VCC controlling the brightness of the LED.
Duty Cycle is defined as the
ratio of ON pulse duration to
the time period.
𝑻𝑶𝑵
𝑫= × 𝟏𝟎𝟎%
𝑻
TON TOFF Here, TON = ON pulse duration
T = Timer period = TON + TOFF
,where TOFF = OFF pulse
27 May 2025
2
duration 2
Microprocessor and Embedded Systems
PWM
PWM
The Arduino’s programming language
makes PWM easy to use; simply call
the built-in function analogWrite(pin,
dutyCycle), where dutyCycle is a
value from 0 to 255, and pin is one of
the PWM pins (3, 5, 6, 9, 10, or 11).
The analogWrite() function provides
a simple interface to the hardware
PWM, but doesn’t provide any
control over frequency.
Note the tilde ~ sign with the pin
numbers of the image.
27 May 2025
3 3
Microprocessor and Embedded Systems
Sample Code for PWM control (ref: PWM lab)
int in1 = 9; //Declaring the pins where in1 in2 from the driver are wired
int in2 = 8; //here they are wired with D9 and D8 from Arduino
int enA = 10; //And we add the pin to control the speed after we remove its jumper
//Make sure it's connected to a pin that can deliver a PWM signal
void setup() {
pinMode(in1, OUTPUT); //Declaring the pin modes, obviously they're outputs
pinMode(in2, OUTPUT);
pinMode(enA, OUTPUT); void TurnMotorA2(){
} digitalWrite(in1, LOW);
//Speed range (0-255) digitalWrite(in2, HIGH);
// in1 and in2 = for logic input pin analogWrite(enA,255);
void TurnMotorA(){ // HIGH and LOW = one direction
}
digitalWrite(in1, HIGH); // LOW and HIGH = another direction
digitalWrite(in2, LOW);
// LOW and LOW = motor stop void loop() {
// HIGH and HIGH = motor stop
analogWrite(enA,100); TurnMotorA();
} delay(2000);
TurnOFFA(); •PWM – to control speed
void TurnOFFA(){ delay(2000);
digitalWrite(in1, LOW); •H-Bridge – to control
TurnMotorA2();
digitalWrite(in2, LOW); the spinning direction
delay(4000);
analogWrite(enA,0);
}
TurnOFFA();
delay(2000);
}
4
// Turn on motor A Microprocessor and Embedded Systems
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// Motor A connections delay(2000);
int enA = 9; // Now change motor directions // in1 and in2 = for logic input pin
// HIGH and LOW = CW direction
int in1 = 8; digitalWrite(in1, LOW); // LOW and HIGH = ACW direction
int in2 = 7; digitalWrite(in2, HIGH); // LOW and LOW = motor stop
delay(2000); // HIGH and HIGH = motor stop
void setup() {
// Set all the motor control pins to outputs // Turn off motors
pinMode(enA, OUTPUT); digitalWrite(in1, LOW);
pinMode(in1, OUTPUT); digitalWrite(in2, LOW); }
pinMode(in2, OUTPUT);
// This function lets you control speed of the motors
// Turn off motors - Initial state void speedControl() {
digitalWrite(in1, LOW); // Turn on motors
digitalWrite(in2, LOW); } digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
void loop() { // Accelerate from zero to maximum speed
directionControl(); for (int i = 0; i < 256; i++) {
delay(1000); analogWrite(enA, i);
speedControl(); delay(20); }
delay(1000); }
// Deaccelerate from maximum speed to zero
// This function lets you control spinning direction of motor for (int i = 255; i >= 0; --i) {
void directionControl() { analogWrite(enA, i);
// Set motors to maximum speed delay(20); }
// For PWM maximum possible values are 0 to 255 // Now turn off motors
analogWrite(enA, 255); digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
} 5
Microprocessor and Embedded Systems
PWM
PWM
The main PWM modes are "Fast PWM" and "Phase-correct PWM“.
There are two Fast PWM modes for Timer/Counter 0 unit. These are modes 3 and 7,
which are selected using the waveform generation mode bits (WGM02, WGM01, and
WGM00). The WGM01 and WGM00 bits are located in the TCCR0A register. The
WGM02 bit is located in the TCCR0B register.
There are 2 types of Fast PWM modes: (a) Non-inverting and (b) Inverting Fast PWM
27 May 2025
6 6
Microprocessor and Embedded Systems
PWM
The difference between the mode 3 and mode 7 Fast PWMs is their TOP values.
For mode 3, the TOP value is fixed (0xFF), whereas that for mode 7 is OCRnA value.
So, if mode 7 is used then we have to load a count value into the OCRnA register.
Once a mode is selected, the timer/counter starts counting from BOTTOM to TOP
value and when the TOP value is reached the counting is repeated from BOTTOM.
The table in the left shows the WGM bits
combination for mode 3 and mode 7.
27 May 2025
7 7
Microprocessor and Embedded Systems
Fast PWM Mode: Setting Modes
In the fast PWM mode, the Compare Output Mode bits COM0A1, COM0A0 (in the
TCCR0A register) for the output at OC0A and bits COM0B1, COM0B0 (in the TCCR0A
register) for the output at OC0B, are used to configure the output as either non-
inverting or inverting mode of operation. Table 12-3 shows how to select COM0A1,
COM0A0 bits to generate non-inverting and inverting mode’s fast PWM waveform.
27 May 2025
8 8
Microprocessor and Embedded Systems
Fast PWM Mode: Setting Modes
In the fast PWM mode, the compare unit allows the generation of PWM waveforms
on the OC0x pins. Table 12.6 shows the COM0B1:0 bit functionality when the
WGM02:0 bits are set to the fast PWM mode.
27 May 2025
9 9
Microprocessor and Embedded Systems
Fast PWM Mode: Setting Modes
Setting the COM0x1:0 bits to 10 will produce a non-inverted PWM and an inverted
PWM output can be generated by setting the COM0x1:0 to 11.
Setting the COM0A1:0 bits to 01 allows the OC0A pin to toggle on Compare Matches
if the WGM02 bit is set. This option is not available for the OC0B pin (see Table 12-6 ).
27 May 2025
10 10
Microprocessor and Embedded Systems
Fast PWM Mode
• The Fast Pulse Width Modulation or Fast
PWM Mode (WGM02:0 = 3 or 7) provides
a high-frequency PWM waveform
generation option. The Fast PWM differs
from the other PWM option in its single-
slope operation.
• The counter starts counting from BOTTOM
to TOP and then restarts from BOTTOM.
• In Non-inverting Compare Output Mode,
the Output Compare (OC0x) is cleared on
the compare match between TCNT0 and
OCR0x, and set at BOTTOM.
• In Inverting Compare Output Mode, the
output is set on compare match and
cleared at BOTTOM.
27 May 2025
11 11
Microprocessor and Embedded Systems
Fast PWM Mode
• Due to the single-slope operation, the operating frequency of the Fast PWM mode
can be twice as high as the phase correct PWM mode that uses dual-slope
operation.
• This high frequency makes the fast PWM mode well suited for power regulation,
rectification, and DAC applications.
• High frequency allows physically small-sized external components (coils, capacitors),
and therefore reduces the total system cost.
• In fast PWM mode, the counter is incremented until the counter value matches the
TOP value, the register TCNTn counts from bottom value to maximum value stored in
the register OCRn. The counter is then cleared/reset to zero at the following timer
clock cycle. If the timer is configured in non-inverting mode, PWM output pin (OCn)
goes low when the value of the above two registers matches. The OCn pin becomes
high when the TCNTn register reaches at bottom value. In inverting mode, OCn pin
behaves opposite to non-inverting mode. 12
27 May 2025 12
Microprocessor and Embedded Systems
Fast PWM Mode
• The timing diagram for the Fast PWM Mode is shown in Figure 12.6.
• The TCNT0 value is in the timing diagram shown as a histogram for illustrating the single-
slope operation.
• The diagram includes non-inverted
and inverted PWM outputs.
The small horizontal line
marks on the TCNT0 slopes
represent compare matches
between OCR0x and TCNT0.
Fig. 12.6 Timing Diagram of Fast PWM Mode
27 May 2025
13 13
Microprocessor and Embedded Systems
Fast PWM Mode: Output Frequency
• The actual OC0x value will only be visible on the port pin if the data direction for
the port pin is set as output.
• The PWM waveform is generated by setting (or clearing) the OC0x Register at the
compare match between OCR0x and TCNT0, and clearing (or setting) the OC0x
Register at the timer clock cycle the counter is cleared (i.e., from TOP to BOTTOM).
• The PWM frequency for the output can be calculated by the following equation:
𝒇𝒄𝒍𝒌_𝑰𝑶
𝒇𝑶𝑪𝒏𝒙𝑷𝑾𝑴 =
𝑵 × 𝟐𝟓𝟔
• The N variable represents the pre-scale factor (1, 8, 64, 256, or 1024).
𝒇𝒄𝒍𝒌_𝑰𝑶
• If OCR0A is given, the formula would be, 𝒇𝑶𝑪𝟎 =
𝑵× 𝟏+𝑶𝑪𝑹𝒏𝒙
27 May 2025
14 14
Microprocessor and Embedded Systems
Fast/Phase Correct PWM Mode
• Non-Inverting Duty Cycle
• The duty cycle of the Non-Inverting mode Fast/PC PWM signal is calculated using
the following formula.
𝟐𝟓𝟔𝑫
𝑶𝑪𝑹𝟎𝒙 = − 𝟏; 𝒙 = 𝑨 𝒐𝒓 𝑩
𝟏𝟎𝟎
• where, D is the Duty cycle that range from 0% to 100%. This duty cycle value is the
count value that has to be loaded into the OCR0A (or OCR0B) register.
• Example: A PWM signal is to have 75% duty cycle. Compute the value for OCR0A.
𝟐𝟓𝟔 × 𝟕𝟓
𝑶𝑪𝑹𝟎𝑨 = − 𝟏 = 𝟏𝟗𝟐 − 𝟏 = 𝟏𝟗𝟏
𝟏𝟎𝟎
27 May 2025
15
Ref: https://www.engineersgarage.com/phase-correct-pwm-pulse-width-modulation-mode-of-avr-microcontroller-timer-part-17-46/
15
Microprocessor and Embedded Systems
Fast/Phase Correct PWM Mode
• Inverting Duty Cycle
• The formula for frequency computation is the same as for non-inverting fast PWM.
But, the duty cycle of the Inverting mode Fast/PC PWM signal is calculated using
the following formula.
𝟐𝟓𝟔𝑫
𝑶𝑪𝑹𝟎𝒙 = 𝟐𝟓𝟓 − ; 𝒙 = 𝑨 𝒐𝒓 𝑩
𝟏𝟎𝟎
• where, D is the Duty cycle that range from 0% to 100%. This duty cycle value is the
count value that has to be loaded into the OCR0A (or OCR0B) register.
• Example: A PWM signal is to have 75% duty cycle. Compute the value for OCR0A.
𝟐𝟓𝟔 × 𝟕𝟓
𝑶𝑪𝑹𝟎𝑨 = 𝟐𝟓𝟓 − = 𝟐𝟓𝟓 − 𝟏𝟗𝟐 = 𝟔𝟑
𝟏𝟎𝟎
27 May 2025
16 16
Microprocessor and Embedded Systems
Phase correct PWM Mode
• The phase correct PWM mode (WGM02:0 = 1 or 5) provides a high-resolution phase
correct PWM waveform generation option. The phase correct PWM mode is based
on a dual-slope operation. The counter counts repeatedly from BOTTOM to TOP
and then from TOP to BOTTOM.
• In non-inverting Compare Output mode, the Output Compare (OC0x) is cleared on
the compare match between TCNT0 and OCR0x while up counting, and set on the
compare match while down counting.
• In inverting Output Compare mode, the operation is inverted.
• The dual-slope operation has a lower maximum operation frequency than the
single-slope operation.
• However, due to the symmetric feature of the dual-slope PWM modes, these modes
are preferred for motor control applications.
27 May 2025
17 17
Microprocessor and Embedded Systems
Phase correct PWM Mode
• In phase correct PWM mode, the counter is incremented until the counter value
matches TOP. When the counter reaches TOP, it changes the count direction.
• The TCNT0 value will be equal to TOP for one timer clock cycle. The timing diagram
for the phase correct PWM mode is shown on Figure 12.7.
• The TCNT0 value is in the timing diagram shown as a histogram for illustrating the
dual-slope operation.
• The diagram includes non-inverted and inverted PWM outputs.
• The small horizontal line marks on the TCNT0 slopes represent compare matches
between OCR0x and TCNT0.
27 May 2025
18 18
Microprocessor and Embedded Systems
Phase correct PWM Mode
• The diagram includes non-inverted
and inverted PWM outputs.
• The small horizontal line marks on
the TCNT0 slopes represent compare
matches between OCR0x and TCNT0.
• The Timer/Counter Overflow
Flag (TOV0) is set each time
the counter reaches BOTTOM.
• The Interrupt Flag can be used
to generate an interrupt each
time the counter reaches the
BOTTOM value. Figure 12.7 Timing Diagram of the Phase Correct PWM Mode
27 May 2025
19 19
Microprocessor and Embedded Systems
Phase Correct PWM Mode
In Phase Correct PWM mode, the compare unit allows the generation of PWM
waveforms on the OC0x pins. Table 12.6 shows the COM0B1:0 bit functionality when
the WGM02:0 bits are set to Phase Correct PWM mode.
27 May 2025
20 20
Microprocessor and Embedded Systems
Phase Correct PWM Mode
• In phase correct PWM mode, the compare unit allows the generation of PWM
waveforms on the OC0x pins. Setting the COM0x1:0 bits to 10 will produce a non-
inverted PWM.
• An inverted PWM output can be generated by setting the COM0x1:0 to 11.
• Setting the COM0A0 bits to 01 allows the OC0A pin to toggle on Compare Matches
if the WGM02 bit is set. This option is not available for the OC0B pin (Table 12-7).
27 May 2025
21 21
Microprocessor and Embedded Systems
Phase correct PWM Mode
• The PWM waveform is generated by clearing (or setting) the OC0x Register at the
compare match between OCR0x and TCNT0 when the counter increments, and
setting (or clearing) the OC0x Register at compare match between OCR0x and
TCNT0 when the counter decrements.
• The PWM frequency for the output when using phase correct PWM can be
calculated by the following equation:
𝒇𝒄𝒍𝒌_𝑰𝑶
𝒇𝑶𝑪𝒏𝒙𝑷𝑪𝑷𝑾𝑴 =
𝑵 × 𝟓𝟏𝟎
• The N variable represents the pre-scale factor (1, 8, 64, 256, or 1024).
• The waveform generated will have a maximum frequency of 𝒇𝑶𝑪𝟎 = 𝒇𝒄𝒍𝒌_𝑰𝑶 .
27 May 2025
22 22
Microprocessor and Embedded Systems
Phase correct PWM Mode
• The extreme values for the OCR0A Register represent special cases when
generating a PWM waveform output in the phase correct PWM mode.
• If the OCR0A is set equal to BOTTOM, the output will be continuously low
and if set equal to MAX the output will be continuously high for non-
inverted PWM mode.
• For inverted PWM, the output will have the opposite logic values.
27 May 2025
23 23
Microprocessor and Embedded Systems
Example to Self practice:
Calculate the PWM frequency for the output when using Fast PWM Mode and Phase
Correct PWM Mode when fclk_IO is 10 MHz and the pre-scale factors are 256 or 1024.
Comment on the results afterward.
Solution:
The PWM frequency for the Fast PWM Mode:
𝒇𝒄𝒍𝒌_𝑰𝑶 𝟏𝟎𝑴𝑯𝒛
𝒇𝑶𝑪𝒏𝒙𝑷𝑾𝑴 = = = 𝟑𝟖. 𝟏𝟓 Hz
𝑵×𝟐𝟓𝟔 𝟏𝟎𝟐𝟒×𝟐𝟓𝟔
The PWM frequency for the Phase Correct PWM Mode:
𝒇𝒄𝒍𝒌_𝑰𝑶 𝟏𝟎𝑴𝑯𝒛
𝒇𝑶𝑪𝒏𝒙𝑷𝑪𝑷𝑾𝑴 = = = 𝟏𝟗. 𝟏𝟓 Hz
𝑵×𝟓𝟏𝟎 𝟏𝟎𝟐𝟒×𝟓𝟏𝟎
Now repeat for N=256 and comment afterwards.
27 May 2025
24 24
Microprocessor and Embedded Systems
Example for Practice
Use ATmega328p Timer 0 Fast PWM mode with TOP at OCR0A (mode 7) and toggle on OC0A
pin. Calculate the PWM frequency. With simulation, the frequency changes with OCR0A value
loaded, OCR0A = 100 and OCR0A = 200. Calculate the PWM frequency in this mode. The Pre-
scaler value, N = 1, and the system clock frequency, fclk_IO = 16 MHz.
The PWM frequency for the Fast PWM Mode:
𝒇𝒄𝒍𝒌_𝑰𝑶 𝟏𝟔𝑴𝑯𝒛
𝒇𝑶𝑪𝟎𝑨𝑷𝑾𝑴 = = = 𝟏𝟓𝟖 kHz
𝑵× 𝟏+𝑶𝑪𝑹𝟎𝑨 𝟏×𝟏𝟎𝟏
𝒇𝒄𝒍𝒌_𝑰𝑶 𝟏𝟔𝑴𝑯𝒛
𝒇𝑶𝑪𝟎𝑨𝑷𝑾𝑴 = = = 𝟕𝟗. 𝟔 kHz
𝑵× 𝟏+𝑶𝑪𝑹𝟎𝑨 𝟏×𝟐𝟎𝟏
The PWM frequency for the PC PWM Mode:
𝒇𝒄𝒍𝒌_𝑰𝑶 𝟏𝟔𝑴𝑯𝒛
𝒇𝑶𝑪𝟎𝑨𝑷𝑾𝑴 = = = 𝟕𝟗. 𝟐 kHz
𝟐𝑵× 𝟏+𝑶𝑪𝑹𝟎𝑨 𝟐×𝟏×𝟏𝟎𝟏
𝒇𝒄𝒍𝒌_𝑰𝑶 𝟏𝟔𝑴𝑯𝒛
𝒇𝑶𝑪𝟎𝑨𝑷𝑾𝑴 = = = 𝟑𝟗. 𝟖 kHz
𝟐𝑵× 𝟏+𝑶𝑪𝑹𝟎𝑨 𝟐×𝟏×𝟐𝟎𝟏
27 May 2025
25 25
Microprocessor and Embedded Systems
Programming Arduino for Fast PWM
#ifndef F_CPU
#define F_CPU 8000000UL // Clock frequency is 8 MHz
#endif
#include <avr/io.h>
int main() {
// OC0B pin is set as PWM output pin by sending a HIGH to Port D’s Data Direction Register, DDRD
DDRD |= (1<<PD5);
OCR0B= 191; // Load 191 into OCR0B for setting its duty cycle to 75% (See previous example)
// Configure TCCR0A and TCCR0B register for (i) non-inverting (10), (ii) Fast PWM mode 7 (111), (iii) No
// Pre-scalar (001) for frequency control. By default, 0s are there, but you may set them explicitly.
TCCR0A |= (1 << COM0B1) | (1<<WGM01) | (1<<WGM00);
TCCR0B |= (1<<WGM02) | (1<<CS00);
while(1);
return 0;
}
27 May 2025
26 26
Microprocessor and Embedded Systems
Programming Arduino for Fast PWM
#ifndef F_CPU
#define F_CPU 8000000UL // Clock frequency is 8 MHz
#endif
#include <avr/io.h>
int main() {
// OC0B pin is set as PWM output pin by sending a HIGH to Port D’s Data Direction Register, DDRD
DDRD |= (1<<PD5);
OCR0A = 200; // Top Value of 200 (must be equal or greater than the Duty Cycle)
OCR0B= 191; // Load 191 into OCR0B for setting its duty cycle to 75% (See previous example)
// Configure TCCR0A and TCCR0B register for (i) non-inverting (11), (ii) Fast PWM mode 7 (111), (iii) No
// Pre-scalar (001) for frequency control. By default, 0s are there, but you may set them explicitly.
TCCR0A |= (1 << COM0B1) | (1 << COM0A0) | (1<<WGM01) | (1<<WGM00);
TCCR0B |= (1<<WGM02) | (1<<CS00);
while(1);
return 0;
} 27
27 May 2025 27
Microprocessor and Embedded Systems
Programming Arduino for Fast PWM
#ifndef F_CPU
#define F_CPU 8000000UL // Clock frequency is 8 MHz
#endif
#include <avr/io.h>
int main() {
// OC0A pin is set as PWM output pin by sending a HIGH to Port D’s Data Direction Register, DDRD
DDRD |= (1<<PD6);
OCR0A= 0xFF; // Load 63 into OCR0A for setting its duty cycle to 75% (See previous example)
// Configure TCCR0A and TCCR0B register for (i) inverting (11), (ii) Fast PWM mode 3 (011), (iii) No
// Pre-scalar (001) for frequency control. By default, 0s are there, but you may set them explicitly.
TCCR0A |= (1 << COM0A1) | (1 << COM0A0) | (1<<WGM01) | (1<<WGM00);
TCCR0B |= (1<<CS00);
while(1);
return 0;
}
27 May 2025
28 28
Microprocessor and Embedded Systems
Thanks for attending….
?
27 May 2025
29 29