This post is all about the detailed tutorial of using PWM (Pulse Width Modulation) in the STM32 (STM32F103C) microcontroller.
Overview
Pulse-width modulation (PWM) is used for controlling the amplitude of digital signals in order to control devices and applications requiring power or electricity. This is an advanced tutorial on PWM generation. We will learn how to generate a variable PWM signal with STM32 Series (STM32F103C) microcontroller. Variable PWM signal is used for controlling the speed of DC motors/Fans. It is also used in AC Light Dimmer. PWM solar chargers also work on variable PWM signal. Servo Motors angle and direction is also controlled with the PWM signal.
In this tutorial, we will learn about PWM (Pulse Width Modulation) in STM32 using Servo Motor. We will also learn how to interface Servo with the STM32F103C8 board. A potentiometer is also interfaced to vary the position of the servo motor’s shaft, and an LCD to display the angle value.
Check this post related to Servo Motor Control: How to Control Multiple Servo Motors with Arduino
Components Required
Here is a list of components needed to learn about PWM signal generation in STM32. All the components can be purchased easily from Amazon.
| S.N. | Components Name | Quantity | Purchase Links |
|---|---|---|---|
| 1 | STM32F103C Board | 1 | Amazon | AliExpress |
| 2 | 16x2 LCD Display | 1 | Amazon | AliExpress |
| 3 | Servo Motor SG90 | 1 | Amazon | AliExpress |
| 4 | Potentiometer 10K | 1 | Amazon | AliExpress |
| 5 | Potentiometer 100K | 1 | Amazon | AliExpress |
| 6 | Connecting Wires | 1 | Amazon | AliExpress |
| 7 | Breadboard | 1 | Amazon | AliExpress |
What is PWM (Pulse with Modulation)?
Pulse-width modulation (PWM) is a modulation process or technique used in most communication systems for encoding the amplitude of a signal right into a pulse width or duration of another signal, usually a carrier signal, for transmission. Although PWM is also used in communications, its main purpose is actually to control the power that is supplied to various types of electrical devices, most especially to inertial loads such as AC/DC motors.
Duty Cycle of the PWM
When the signal is high, we call this “on time”. To describe the amount of “on time”, we use the concept of the duty cycle. Duty cycle is measured in percentage. The percentage duty cycle specifically describes the percentage of time a digital signal is on over an interval or period of time. This period is the inverse of the frequency of the waveform.
If a digital signal spends half of the time on and the other half off, we would say the digital signal has a duty cycle of 50% and resembles an ideal square wave. If the percentage is higher than 50%, the digital signal spends more time in the high state than the low state and vice versa if the duty cycle is less than 50%. See the figure below for full understanding:
PWM in STM32
STM32F103C has 15 PWM pins and 10 ADC pins. It has 7 timers and each PWM output is provided by a channel connected to 4 timers. It has 16-bit PWM resolution, i.e 2^16. Because of this its counters and variables can be as large as 65535. As it has 72MHz clock rate, its PWM output can have a maximum period of about one millisecond.
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 will use 100K potentiometer and STM32 to vary the rotational angle of SG90 Servo Motor with the PWM technique. A 16×2 LCD is used to display a rotational angle in degrees.
Circuit Diagram & Connection
In STM32F103C, there are 10 ADC pins (PA0-PB1), and we can use only one pin (PA5) for analogread() for setting the shaft position of the motor by the potentiometer. Also among 15 PWM pins of STM32 (PA0, PA1, PA2, PA3, PA6, PA7, PA8, PA9, PA10, PB0, PB1, PB6, PB7, PB8, PB9), one pin will be used for providing pulses to the Servo motor’s PWM pin PA0.
A 16×2 LCD is interfaced to STM32 with following pin connections rs = PB11, en = PB10, d4 = PA4, d5 = PA3, d6 = PA2, d7 = PA1. It has 10K potentiometer attached to it to adjust the contrast.
Source Code/Program
Here is a code for controlling the Servo Motor with PWM Technique using STM32 Microcontroller.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#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.begin(16,2); lcd.setCursor(2,0); lcd.print("PWM Tutorial"); lcd.setCursor(3,1); lcd.print("Using Servo"); delay(3000); lcd.clear(); 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 } |










