Introduction: STM32F103 PWM Example [Fading LED Using KEIL UV4 and Cubemx]

About: I am embedded system developer, working since 2009. I started my Programming carrier in Assembly language Programming and now working on Many High level Languages as well, like MATLAB, Labview, C#, Java, Kotli…

Introduction:

Using PWM is very basic need of every embedded developer. Generating and using PWM is as important for many of embedded projects as breath for any living being. We use PWM for very different type of applications like

  1. LED Fadings
  2. Multi color Generation with Multicolor LED
  3. DC Motor Speed control
  4. DC Heaters
  5. Buck Converters
  6. Boost Converters
  7. DC to DC converters
  8. PID controlled Applications
  9. Servo controls
  10. and even in Drons

Before Getting started

If you are not familiar with basic stm32cube mx and stm32f1038c blue pill board then please visit this STM32 LED Blinking with Keil and Cubemx tutorial. This will help you to make your first hello world program before jumping into pwm output.

What is PWM?

Well I hope most of you already familiar with this topic very well. If this is true you are free to skip this part, otherwise please proceed.

PWM is short form of Pulse Width Modulation. As we are living in Digital World but we cannot neglect the benefits of Analog Signals. Like changing the input voltages via variable resistor. Reading Temperature value and changing the Fan Speed accordingly. These all are analog applications. So you acomplish such task we have two basic building blocks to help us in Embedded Developement are ADC and DACs mean Analog to Digital Converters to read analog data and convert it to digital form so that microcontrollers could read them, and Digital To analog Converters to get Stream of Digital Bits and simulate them into Analog Data so that the outer world could understand what microcontroller want to say and to respond accordingly.

PWM is very basic form of DAC. Normally a DC wave is pure straight line having no variation in it. to make it analog we need some kind of variation so we apply this variation by 1 and 0 stream like making it ON for some specific time and the OFF for remaning time. This process is called Modulating the Width of a Pulse. or PWM in short.

Terms to keep in Mind.

According to above explanation (which is just a hint not a complete description. To have complete understanding of PWM you can search google for PWM and you will get plenty of them.) we came in to conclusion that there are some important factors in this

ON Time, OFF time, Pulse and Complete Cycle.

Obviously when we change DC into one and zero's form then we came with the result of Pulse. This pulse will hold some on time and some off time. no matter how short off time is. If you turn off time 0 then you will again get straight DC line mean full ON, and also if you make ON Time = 0 then you will face a complete Off or zero voltage at output.

On and Off time combine makes a one Cycle. Number of cycles in One Second calls Frequency of PWM. Duration of On time usually called the Duty Cycle.

Enough Theory, Just Dive into practical

Goto Your main menu and Open STM Cubemx software. Select You STM32 chip in My case it is STM32F103C8 for Bluepill board. Now I used Timer 3 in PWM generation Mode. Just Goto Timer 3 and select channel 4 and change this to PWM generation instead of Dissalbe. This will make pin RB1 to Green on left pannel.

PWM settings

Now Switch to Configuration tab and press Timer3 button

After that a new window will open with the timer settings options change settings according to calculations

t=1/(Clock_freq / Prescaler+1) micro seconds; * Timer_Auto_Relaoad_Value

f = (1/t)*100 frequency in Khz

or

Prescaler = Clock_in_hz/(PWM frequency*PWM resolution) – 1

Set the Pulse equal to the desired Pulse width where the value varies from 0 to Counter Period.

After that Click on Code Generation. Select you desired compiler and code location. In my case I am using MDK uVision4 Keil compiler.

Code:

Now Open project and goto main.c file under application/User location

and change code accordingly

<p>int main(void)<br>{
uint16_t i=0;
SystemClock_Config();
MX_GPIO_Init(); MX_TIM3_Init();
HAL_TIM_Base_Start(&htim3);
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
while (1) {
/* USER CODE END WHILE */
for(i=0;i<200;i+=3) {
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,i);
HAL_Delay(250);
}
for(;i>0;i-=3) {
__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_4,i);
HAL_Delay(250);
}
}
}</p>