You are on page 1of 5

2/28/2017 STM32F4PWMtutorialwithTIMERsSTM32F4Discovery

Home
STM32F4/29 Discovery
STM32F4 links
All STD libraries
STD Libraries API
All HAL libraries
HAL Libraries API
ESP8266
All tutorials

About

STM32F4 Discovery Libraries and tutorials for STM32Fxxx series by Tilen Majerle.

About
LinkedIn
Twitter
Google+
Facebook
Github
Instagram

FOLLOW: STM32F4 / STM32F4 DISCOVERY / STM32F429 / MORE


STM32F429 DISCOVERY / TUTORIALS
108 COMMENTS
NEXT STORY
SUBSCRIBE
Library 12- OneWire library for STM32F4
Subscribe if you want to be
STM32F4 PWM tutorial notified about new posts and
other events on this site.
PREVIOUS STORY

Library 11- Button library for ILI9341 LCD


with TIMERs Name
and STMPE811 touch controller on BY TILZ0R MAY 11, 2014
STM32F429 Discovery board
Email *

TOP POSTS
Subscribe
All STM32F4 tutorials
In this tutorial, I will show you, how to implement
STM32F4 PWM tutorial with TIMERs
PWM outputs on STM32F4xx devices. This is for a
All STM32F4 libraries
POLL
STM32F4 External interrupts tutorial lot of people pretty hard work, but believe me, its
All STM32 HAL libraries quite quick and easy. I will go step by step on how Standard peripheral drivers vs

Library 02- STM32F429 Discovery GPIO HAL drivers


to make a PWM output on specific timer.
tutorial with onboard leds and button I like standard peripheral
drivers and I want to stay on
Update: I made a library for PWM, available here.
them.
I want to start with new
RECENT COMMENTS
HAL system
Majerle Tilen on STM32F4 FFT example HighQualityEnameled What are standard
EnameledCopperWire CopperWireLowResistance,
BestPriceGiven! peripheral drivers?
Majerle Tilen on New library system built What are HAL drivers?
on STM32Fxxx HAL drivers
Vote

Majerle Tilen on Ethernet server using STM32F4timers View Results

STM32F4-Discovery and SD card


This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More

https://stm32f4discovery.net/2014/05/stm32f4stm32f429discoverypwmtutorial/ 1/13
2/28/2017 STM32F4PWMtutorialwithTIMERsSTM32F4Discovery

Majerle Tilen on HAL library 3- DELAY for They have up to 14 timers inside. Table below
STM32Fxxx shows their description. You have to know, that SUPPORT US
lets say F401 doesnt have so many timers like
MK on HAL library 3- DELAY for F407 or F429. You have to always check manual
STM32Fxxx
for its chip if it has available timer.

Timer Type Resolution Prescaler Channels MAX SEARCH


CATEGORIES
INTERFACE
To search type and hit enter
ARM Cortex-M CLOCK

Random TIM1,
Advanced 16bit 16bit 4 SysClk/2
TIM8 TWITTER
STM32F4
TIM2, General
32bit 16bit 4 SysClk/4 Tweetsby@tilz0R
STM32F4 Discovery TIM5 purpose
TilenMajerle
TIM3, General @tilz0R
STM32F429 16bit 16bit 4 SysClk/4
TIM4 purpose SourcecodeforICLocker
websiteisonlineandfreeto
STM32F429 Discovery
General use.Youcannowbuildyour
TIM9 16bit 16bit 2 SysClk/2 ownICLockerwebsiteat
purpose
STM32F7 home.
github.com/MaJerle/iclock
TIM10, General
STM32F7 Discovery 16bit 16bit 1 SysClk/2
TIM11 purpose MaJerle/i
Officialre
Tutorials General github.com
TIM12 16bit 16bit 2 SysClk/4
purpose
Uncategorized 18Feb

TIM13, General
16bit 16bit 1 SysClk/4 TilenMajerle
TIM14 purpose @tilz0R

Newlibraries:ESP8266AT,
TIM6,
Basic 16bit 16bit 0 SysClk/4 GSMATandGPS
TIM7 NMEAparsersbit.ly/2ecBYSz

Newlibra
* Clock speed depends on which STM32F4xx Inthepas
stm32f4d
device is used

Timer initialization Embed ViewonTwitter

Before we can use PWM, we have to initialize


timer. Because STM32F429 Discovery board does GOOGLE+
not have leds on PWM pins, I will use STM32F4
RECENT POSTS
Discovery with 168MHz core clock for this
New libraries: ESP8266 AT, GSM AT and example. Leds are connected to pins PD12 to
GPS NMEA parsers
PD15, what give us timer TIM4 with Output
channels 1 to 4.
HAL Library 36- AHRS and IMU
algorithms for calculating roll, pitch and yaw
axes Initialize TIM4
HAL Library 35- GPS parser for Here we will initialize timer, for our PWM Tilen Majerle
google.com/+TilenMajerle
STM32Fxxx frequency. We have to set prescaler and period
Follow
for how fast will it count and how much it will
HAL Library 34- DSP FILTERS for
count for specific PWM frequency. 575 followers
STM32Fxxx
1 void TM_TIMER_Init(void) { Follow me on Google+
IC Locker Online inventory for your IC 2 TIM_TimeBaseInitTypeDef TIM_BaseStruct;
3
components 4 /* Enable clock for TIM4 */
5 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,
6 /*
HAL Library 33- DMA extension for SPI 7 TIM4 is connected to APB1 bus, which has on F407 device 42MHz clock
8 But, timer has internal PLL, which double this frequency for timer, up to 84MHz
on STM32Fxxx
9 Remember: Not each timer is connected to APB1, there are also timers connected
10 on APB2, which works at 84MHz by default, and internal PLL increase
11 this to up to 168MHz
12
This website uses cookies to improve your experience. We'll assume
13 Set timer you're ok with this, but you can opt-out if you wish. Accept
prescaller Read More

https://stm32f4discovery.net/2014/05/stm32f4stm32f429discoverypwmtutorial/ 2/13
2/28/2017 STM32F4PWMtutorialwithTIMERsSTM32F4Discovery
14 Timer count frequency is set with
15
CALENDAR 16 timer_tick_frequency = Timer_default_frequency / (prescaller_set + 1)
17
18 In our case, we want a max frequency for timer, so we set prescaller to 0
May 2014 19 And our timer will have tick frequency
20
21 timer_tick_frequency = 84000000 / (0 + 1) = 84000000
M T W T F S S
22 */
23 TIM_BaseStruct.TIM_Prescaler = 0;
1 2 3 4 24 /* Count up */
25 TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up
5 6 7 8 9 10 11 26 /*
27 Set timer period when it have reset
12 13 14 15 16 17 18 28 First you have to know max value for timer
29 In our case it is 16bit = 65535
19 20 21 22 23 24 25 30 To get your frequency for PWM, equation is simple
31
26 27 28 29 30 31 32 PWM_frequency = timer_tick_frequency / (TIM_Period + 1)
33
Apr Jun 34 If you know your PWM frequency you want to have timer period set correct
35
36 TIM_Period = timer_tick_frequency / PWM_frequency - 1
37
38 In our case, for 10Khz PWM_frequency, set Period to
ARCHIVES 39
40 TIM_Period = 84000000 / 10000 - 1 = 8399
41
November 2016 42 If you get TIM_Period larger than max timer value (in our case 65535),
43 you have to choose larger prescaler and slow down timer tick frequency
44 */
July 2016 45 TIM_BaseStruct.TIM_Period = 8399; /* 10kHz PWM */
46 TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1
47 TIM_BaseStruct.TIM_RepetitionCounter = 0;
April 2016 48 /* Initialize TIM4 */
49 TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
50 /* Start count on TIM4 */
January 2016 51 TIM_Cmd(TIM4, ENABLE);
52 }

December 2015
Initialize PWM 4 channels
November 2015
Set PWM output channels to PWM.
October 2015
1 void TM_PWM_Init(void) {
2 TIM_OCInitTypeDef TIM_OCStruct;
September 2015 3
4 /* Common settings */
5
August 2015 6 /* PWM mode 2 = Clear on compare match */
7 /* PWM mode 1 = Set on compare match */
8 TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
July 2015 9 TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable
10 TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low
11
June 2015 12 /*
13 To get proper duty cycle, you have simple equation
14
May 2015 15 pulse_length = ((TIM_Period + 1) * DutyCycle) / 100 - 1
16
17 where DutyCycle is in percent, between 0 and 100%
April 2015 18
19 25% duty cycle: pulse_length = ((8399 + 1) * 25) / 100 - 1 = 2099
20 50% duty cycle: pulse_length = ((8399 + 1) * 50) / 100 - 1 = 4199
March 2015 21 75% duty cycle: pulse_length = ((8399 + 1) * 75) / 100 - 1 = 6299
22 100% duty cycle:pulse_length = ((8399 + 1) * 100) / 100 - 1 = 8399
23
24 Remember: if pulse_length is larger than TIM_Period, you will have output HIGH all the time
February 2015
25 */
26 TIM_OCStruct.TIM_Pulse = 2099; /* 25% duty cycle */
27 TIM_OC1Init(TIM4, &TIM_OCStruct);
January 2015
28 TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable
29
30 TIM_OCStruct.TIM_Pulse = 4199; /* 50% duty cycle */
December 2014 31 TIM_OC2Init(TIM4, &TIM_OCStruct);
32 TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable
33
November 2014 34 TIM_OCStruct.TIM_Pulse = 6299; /* 75% duty cycle */
35 TIM_OC3Init(TIM4, &TIM_OCStruct);
36 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable
October 2014 37
38 TIM_OCStruct.TIM_Pulse = 8399; /* 100% duty cycle */
39 TIM_OC4Init(TIM4, &TIM_OCStruct);
September 2014 40 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable
41 }

August 2014

July 2014
Initialize outputs
Initialize and connect pins for specific TIM. Notice,
June 2014
that GPIOs have AF (Alternating Function) mode,
May 2014 because timer has full control on them.

1 void TM_LEDS_Init(void) {
April 2014 2 GPIO_InitTypeDef GPIO_InitStruct;
3
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More

https://stm32f4discovery.net/2014/05/stm32f4stm32f429discoverypwmtutorial/ 3/13
2/28/2017 STM32F4PWMtutorialwithTIMERsSTM32F4Discovery
4 /* Clock for GPIOD */
5 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,
6
7 /* Alternating functions for pins */
8 GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4
9 GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4
10 GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4
11 GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4
12
13 /* Set pins */
14 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13
15 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
16 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL
17 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
18 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz
19 GPIO_Init(GPIOD, &GPIO_InitStruct);
20 }

Example
1 /**
2 *PWM example for STM32F4 Discovery
3 *It should work on STM32F429 Discovery too and all other STM32F4xx devices
4 *
5 *@author Tilen Majerle
6 *@emailtilen@majerle.eu
7 *@websitehttp://stm32f4-discovery.com
8 *@ideKeil uVision 5
9 */
10 #include "defines.h"
11 #include "stm32f4xx.h"
12 #include "stm32f4xx_rcc.h"
13 #include "stm32f4xx_gpio.h"
14 #include "stm32f4xx_tim.h"
15
16 void TM_LEDS_Init(void) {
17 GPIO_InitTypeDef GPIO_InitStruct;
18
19 /* Clock for GPIOD */
20 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD
21
22 /* Alternating functions for pins */
23 GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4
24 GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4
25 GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4
26 GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4
27
28 /* Set pins */
29 GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13
30 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
31 GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL
32 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
33 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz
34 GPIO_Init(GPIOD, &GPIO_InitStruct);
35 }
36
37 void TM_TIMER_Init(void) {
38 TIM_TimeBaseInitTypeDef TIM_BaseStruct;
39
40 /* Enable clock for TIM4 */
41 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,
42 /*
43 TIM4 is connected to APB1 bus, which has on F407 device 42MHz clock
44 But, timer has internal PLL, which double this frequency for timer, up to 84MHz
45 Remember: Not each timer is connected to APB1, there are also timers connected
46 on APB2, which works at 84MHz by default, and internal PLL increase
47 this to up to 168MHz
48
49 Set timer prescaller
50 Timer count frequency is set with
51
52 timer_tick_frequency = Timer_default_frequency / (prescaller_set + 1)
53
54 In our case, we want a max frequency for timer, so we set prescaller to 0
55 And our timer will have tick frequency
56
57 timer_tick_frequency = 84000000 / (0 + 1) = 84000000
58 */
59 TIM_BaseStruct.TIM_Prescaler = 0;
60 /* Count up */
61 TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up
62 /*
63 Set timer period when it have reset
64 First you have to know max value for timer
65 In our case it is 16bit = 65535
66 To get your frequency for PWM, equation is simple
67
68 PWM_frequency = timer_tick_frequency / (TIM_Period + 1)
69
70 If you know your PWM frequency you want to have timer period set correct
71
72 TIM_Period = timer_tick_frequency / PWM_frequency - 1
73
74 In our case, for 10Khz PWM_frequency, set Period to
75
76 TIM_Period = 84000000 / 10000 - 1 = 8399
77
78 If you get TIM_Period larger than max timer value (in our case 65535),
79 you have to choose larger prescaler and slow down timer tick frequency
80 */
This website uses cookies to improve your experience. We'll assume you're ok with this, but =
81 TIM_BaseStruct.TIM_Period you8399;
can opt-out if youPWM
/* 10kHz wish.*/ Accept Read More

https://stm32f4discovery.net/2014/05/stm32f4stm32f429discoverypwmtutorial/ 4/13
2/28/2017 STM32F4PWMtutorialwithTIMERsSTM32F4Discovery
82 TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1
83 TIM_BaseStruct.TIM_RepetitionCounter = 0;
84 /* Initialize TIM4 */
85 TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
86 /* Start count on TIM4 */
87 TIM_Cmd(TIM4, ENABLE);
88 }
89
90 void TM_PWM_Init(void) {
91 TIM_OCInitTypeDef TIM_OCStruct;
92
93 /* Common settings */
94
95 /* PWM mode 2 = Clear on compare match */
96 /* PWM mode 1 = Set on compare match */
97 TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
98 TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable
99 TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low
100
101 /*
102 To get proper duty cycle, you have simple equation
103
104 pulse_length = ((TIM_Period + 1) * DutyCycle) / 100 - 1
105
106 where DutyCycle is in percent, between 0 and 100%
107
108 25% duty cycle: pulse_length = ((8399 + 1) * 25) / 100 - 1 = 2099
109 50% duty cycle: pulse_length = ((8399 + 1) * 50) / 100 - 1 = 4199
110 75% duty cycle: pulse_length = ((8399 + 1) * 75) / 100 - 1 = 6299
111 100% duty cycle:pulse_length = ((8399 + 1) * 100) / 100 - 1 = 8399
112
113 Remember: if pulse_length is larger than TIM_Period, you will have output HIGH all the time
114 */
115 TIM_OCStruct.TIM_Pulse = 2099; /* 25% duty cycle */
116 TIM_OC1Init(TIM4, &TIM_OCStruct);
117 TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable
118
119 TIM_OCStruct.TIM_Pulse = 4199; /* 50% duty cycle */
120 TIM_OC2Init(TIM4, &TIM_OCStruct);
121 TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable
122
123 TIM_OCStruct.TIM_Pulse = 6299; /* 75% duty cycle */
124 TIM_OC3Init(TIM4, &TIM_OCStruct);
125 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable
126
127 TIM_OCStruct.TIM_Pulse = 8399; /* 100% duty cycle */
128 TIM_OC4Init(TIM4, &TIM_OCStruct);
129 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable
130 }
131
132 int main(void) {
133 /* Initialize system */
134 SystemInit();
135 /* Init leds */
136 TM_LEDS_Init();
137 /* Init timer */
138 TM_TIMER_Init();
139 /* Init PWM */
140 TM_PWM_Init();
141
142 while (1) {
143
144 }
145 }

Thats it. You have not set your timer to work in


PWM mode.

Hope it helps.

Share this to other users:

Tags: 168MHz gpio keil microcontrollers pwm

STM32F4 discovery stm32f429 stm32f429discovery

stm32f4xx Tim1 tim10 tim11 tim12 tim13 tim14

tim2 tim3 tim4 tim5 tim6 Tim7 tim8 tim9

timers uvision

tilz0R
Owner of this site. Also electronic

enthusiasts, web developer, 3D printer
fan, handball player and more. Big fan of
STM32F4 devices. In anticipation of the
new Discovery board for STM32F7 lines.
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More

https://stm32f4discovery.net/2014/05/stm32f4stm32f429discoverypwmtutorial/ 5/13

You might also like