Hello everyone.
In this article, we will try to use LL to output PWM.
What is LL? If you are wondering what LL is, please refer to the article HAL and LL.
Here is the development environment at the time of posting.
PC: Windows 10 OS
IDE: STM32CubeIDE Version1.5.0
Configurator: STM32CubeMX Version6.1.0
Board: STM32Nucleo-F401RE
What is PWM?
PWM stands for Pulse Width Modulation. In Japanese, it is called Pulse Width Modulation.
It is a function that outputs pulses from an I/O port.
By changing the pulse width, you can control a motor or adjust the brightness of an LED.
The green LED (LD2) on the board happens to be connected to the PWM output port, so we’ll use it this time.
Creating a project
Start the IDE, select File- New – STM32 Project, when the Target Selection window comes up, select the Board Selector tab, select NUCLEO-F401RE from the Boards List and press Next. Click the Next button.
Enter F401PwmLL as the Project name and press the Finish button.
It will ask “Initialize all peripherals with their default Mode ? Press the Yes button.
Preparing to use the UART with LL
If you select the Project Manager tab and look at the Advanced Settings, you will see that there is no TIM item.
So, let’s configure the pins in Pinout & Configuration first.
Look at the diagram of the microcontroller.
The pin to be configured this time is PA5 on the bottom.
Right click on PA5 and select TIM2_CH1 from the list, and the pin will turn yellow.

Then select Pinout & Configuration – Categories – Timers – TIM2 and click
Select PWM Generation CH1 from the list of TIM2 Mode and Configuration – Mode – Channel1.
The pin has changed from yellow to green.
Set the TIM2 Mode and Configuration – Configuration – Parameter Settings as shown below.

Getting ready to use TIM with LL
Once you’ve done this, you’re ready to use LL with TIM.
Select the Project Manager tab and change TIM in Advanced Settings from HAL (default) to LL. (Use the combo box to select)
Click on the HAL section to display a list of combo boxes, and select LL.
Click on the Clock Configuration tab and you will see that the HCLK is 84MHz.
Since HCLK is 84MHz
84MHz / ((83 + 1) * (999 + 1)) = 84 * 10^6 Hz / (84 * 10^3) = 10^3 Hz = 1 kHz
This setting results in a PWM output with a period of 1 kHz.
Select F401PwmLL in the Project Explorer and build it with Project – Build Project.
Adding the code
Code the while() loop part of main() as follows
/* USER CODE BEGIN WHILE */
LL_TIM_EnableCounter(TIM2);
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
while (1)
{
LL_TIM_OC_SetCompareCH1(TIM2, 999);
HAL_Delay(1000);
LL_TIM_OC_SetCompareCH1(TIM2, 500);
HAL_Delay(1000);
/* USER CODE END WHILE */ /* USER CODE BEGIN 3
/* USER CODE BEGIN 3 */ /* USER CODE END WHILE
}
/* USER CODE END 3 */ }
Build and run the program
Build the program, make sure there are no errors, and run it.
Run – Resume
If the green LED gets brighter or darker, you have succeeded.
To confirm, I observed the waveform with an oscilloscope.

We have confirmed that the frequency is about 1 kHz.
Code summary
LL_TIM_EnableCounter(TIM2) and
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1) start the PWM output.
__HAL_TIM_SET_COMPARE is a macro to change the value of register CCR.
LL_TIM_OC_SetCompareCH1(TIM2, 250);
can be used to change the duty ratio of TIM2 and CH1.
If the third argument is 500, the duty ratio is set to 50%. (The left part of the waveform above)
When the value of the third argument is 250, the duration of the H level is reduced to 1/4. (The right part of the waveform above)
In pulse width modulation (PWM) mode, the frequency is determined by the value of the TIMx_ARR register and the duty cycle is determined by the value of the TIMx_CCRx
In Pulse Width Modulation (PWM) mode, a signal can be generated with a frequency determined by the TIMx_ARR register value and a duty cycle determined by the TIMx_CCRx register value.
Counter Period ( == 999 ) in the configuration screen is the value of TIM2_ARR.
The denominator is 1000 because the up-counter is designed to set the first count to 0.
Since the PWM output signal is connected to the anode of the LED, if the value of the third argument of __HAL_TIM_SET_COMPARE() is n
The LED will light up for n / 1000 periods. (n is the value of TIM2_CCRx).
There seems to be no difference in the amount of RAM and code used for PWM between HAL and LL.
The amount of RAM and Flash consumption (unit [KB]) confirmed by the build analyzer is as follows.
Unlike the communication control, there was not much difference since the setting values are only written in registers.
I guess it doesn’t matter which one you use.
| Library | RAM | Flash |
|---|---|---|
| HAL | 1.67 | 10.17 |
| LL | 1.61 | 10.93 |
So, how was it? Did you get good PWM output?
Thank you for your time.





