STM32 PWM (Pulse Width Modulation) Tutorial with Servo Motor

PWM is a method of adjusting the amplitude of digital signals in order to control equipment and applications that require power or electricity. This is a more advanced PWM generation tutorial. The STM32 Series (STM32F103C) microcontroller will be used to generate a changeable PWM signal. The speed of DC motors/fans is controlled via a variable PWM signal. It can also be found in an AC light dimmer. Solar chargers that use PWM also use a changing PWM signal. The PWM signal is also used to regulate the angle and direction of servo motors.

In this blog, we will discuss PWM (Pulse Width Modulation) with STM32 using a Servo Motor. We’ll also learn how to use the STM32F103C8 board with Servo. An LCD is used to display the angle value and a potentiometer is used to change the position of the servo motor’s shaft.

This tutorial covers how to use PWM (Pulse Width Modulation) in the STM32 (STM32F103C) microcontroller in depth.

Components Required

  • STM32F103c8t6 Bluepill Board
  • 16*2 LCD Display
  • SG90 Servo Motor
  • Potentiometer- 10K,100K
  • Connecting Wires
  • Breadboard

What is PWM (Pulse with Modulation)?

Pulse-width modulation (PWM)  is a modulation procedure or technique used in most communication systems to encode the amplitude of a signal into the pulse width or length of another signal, usually a carrier signal, for transmission. Although PWM is employed in communications, its primary function is to control the power provided to various types of electrical equipment, particularly inertial loads like AC/DC motors.

Duty Cycle of the PWM

We term this “on time” when the signal is strong. The idea of the duty cycle is used to express the amount of “on time.” The duty cycle is expressed as a percentage. The % duty cycle refers to the proportion of time a digital signal is on within a given interval or time period. This period is the inverse of the waveform’s frequency.

If a digital signal is on for half of the time and off for the other half, it is said to have a duty cycle of 50% and resembles a perfect square wave. The digital signal spends more time in the high state than the low state if the duty cycle is greater than 50%, and vice versa if the duty cycle is less than 50%. For a better understanding, look at the diagram below:

PWM Example STM32


STM32F103C8T6 Discovery Board was designed as a development board that is similar to Arduino in terms of advanced capabilities and accessibility. The STM32 Discovery Board enables the development of high-reliability applications by utilizing an advanced performance microcontroller known as the Arm Cortex-M4 32-bit core. I think you’re familiar with ARM Architecture. It provides versatility and customization, allowing you to experiment with libraries, communication protocols, GPIO pins, and so on.

PWM in STM32

There are 15 PWM pins and 10 ADC pins on the STM32F103C. Each PWM output is given by a channel coupled to four timers, and it has seven timers. It has a PWM resolution of 16 bits, or 216. As a result, its counters and variables can have a maximum value of 65535. Its PWM output can have a maximum period of around one millisecond due to its 72MHz clock rate.

1. The value of 65535 gives Full Servo Rotation (100% Duty Cycle)
2. The value of 32767 gives Half Rotation like 90 degrees (50% Duty Cycle)
3. The value of 13107 gives 20% Rotation (20% Duty Cycle)

So, in this PWM tutorial, we’ll use a 100K potentiometer and an STM32 to use the PWM approach to change the rotational angle of an SG90 Servo Motor. The rotating angle in degrees is displayed on a 162 LCD.

Circuit Diagram & Connection

There are 10 ADC pins (PA0-PB1) on the STM32F103C, but we can only utilize one (PA5) for analog read() to set the shaft position of the motor using the potentiometer. In addition, one of the STM32’s 15 PWM pins (PA0, PA1, PA2, PA3, PA6, PA7, PA8, PA9, PA10, PB0, PB1, PB6, PB7, PB8, PB9) will be used to provide pulses to the Servo motor’s PWM pin PA0.

The following pin connections are used to connect a 162 LCD to the STM32: rs = PB11, en = PB10, d4 = PA4, d5 = PA3, d6 = PA2, d7 = PA1. To alter the contrast, it includes a 10K potentiometer linked to it.

Source Code/Program

Here is a code for controlling the Servo Motor with PWM Technique using STM32 Microcontroller.

#include<Servo.h> //including servo library
#include<LiquidCrystal.h> //including LCD display library
const int rs = PB11, en = PB10, d4 = PA4, d5 = PA3, d6 = PA2, d7 = PA1; //declaring pin names and pin numbers of lcd
LiquidCrystal lcd(rs,en,d4,d5,d6,d7); //setting lcd and its paramaters

int servoPin = PA0; //declare and initialize pin for servo output PWM
int potPin = PA5; //potentiometer ADC input

Servo servo; // creating variable servo with datatype Servo

void setup()

lcd.print(“PWM Tutorial”);
lcd.print(“Using Servo”);
servo.attach(servoPin); //it connects pin PA0 with motor as control feedback by providing pulses


void loop()
lcd.clear(); //clears lcd
int angle; //declare varible angle as int
int reading; //declare varible reading as int
reading = analogRead(potPin); //read analog value from pin PA3
angle = (reading/24); //it divides ADC the value according to max angle 170 deg
servo.write(angle); //it puts angle value at servo
lcd.setCursor(0,0); //setting cursor at first row and first column
lcd.print(“Angle:”); //puts Angle in LCD
lcd.print(angle); //puts value at angle
delay(100); //delay in time


Hope this blog helps you to understand how to use PWM (Pulse Width Modulation) in the STM32 (STM32F103C) microcontroller. We, MATHA ELECTRONICS will come back with more informative blogs.

Leave a Reply

Your email address will not be published.