STM32F100, a PWM on Timer 17
Moderator: RoccoMarco
-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
STM32F100, a PWM on Timer 17
Hello,
I try to generate PWM with Timer 17 but can't to find how to do this. Demo sources and mcuconf.h uses Timer 8 maximum.
What is about TIM17?
I try to generate PWM with Timer 17 but can't to find how to do this. Demo sources and mcuconf.h uses Timer 8 maximum.
What is about TIM17?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32F100, a PWM on Timer 17
TIM17 is not supported currently, it could be added but it only supports a single comparator so you could only use channel 0.
Giovanni
Giovanni
-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
Re: STM32F100, a PWM on Timer 17
Do I understand right that currently it isn't possible to make PWM with TIM17?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32F100, a PWM on Timer 17
Using the PWM driver currently not, you could enable the timer at registers level and do it anyway, not particularly hard to do.
Giovanni
Giovanni
-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
Re: STM32F100, a PWM on Timer 17
The following code runs PWM on TIM17:
Code: Select all
//Enable clock for the timer
RCC->APB2ENR |= RCC_APB2ENR_TIM17EN;
// Enable ARR preloading
TIM17->CR1 |= TIM_CR1_ARPE;
// Enable CCR1 preloading
TIM17->CCMR1 |= TIM_CCMR1_OC2PE;
// PWM mode 1: OC1M = 110
TIM17->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1);
// Prescaler keeps zero to allow control PWM frequency
TIM17->PSC = 0;
// PWM Frequency 36 kHz
TIM17->ARR = 667 - 1;
// Duty cycle: 33%
TIM17->CCR1 = 222;
// Uncomment to change polarity
//TIM2->CCER |= TIM_CCER_CC2P;
// Enable Capture/Compare output 1, ie PB9
TIM17->CCER |= TIM_CCER_CC1E;
// Main Output enable
TIM17->BDTR |= TIM_BDTR_MOE;
// Start timer
TIM17->CR1 |= TIM_CR1_CEN;-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
Re: STM32F100, a PWM on Timer 17

Top three graphics are captured when I have used ChibiOS' PWM on TIM4 channel 3. Looks so strange.
Bottom graphic is captured when I use register's PWM, described above.
The last one is looked as normal PWM. How to get the same with ChibiOS PWM module?
Source code: https://github.com/RaD/armka_demos/blob/97b2d331d92ae2552d04ab2f0d9c51c9718c3f62/apps/ir-tester/main.c
-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
Re: STM32F100, a PWM on Timer 17
This night gave me an idea to check timer's registers after preparing PWM module. Results are following:
[*] TIM17/CH1 (registers way):
[*] TIM4/CH4 (PWM module way):
That's the reason of my problem!
Btw, these timers share the same pin on a chip.
How to tune PWM module to have the values of TIM17 for TIM4?
[*] TIM17/CH1 (registers way):
Code: Select all
TIM17->PSC = 0
TIM17->ARR = 24001
TIM17->CCR1 = 12000[*] TIM4/CH4 (PWM module way):
Code: Select all
TIM4->PSC = 23999
TIM4->ARR = 99
TIM4->CCR1 = 0That's the reason of my problem!
Btw, these timers share the same pin on a chip.
How to tune PWM module to have the values of TIM17 for TIM4?
- Giovanni
- Site Admin
- Posts: 14891
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32F100, a PWM on Timer 17
The PWM driver works as intended here. The values in the registers come from the settings in the PWM configuration structure and I find unlikely you can have the CCR1 set to zero.
If you explain what you expect to get from the PWM and post your configuration structure I could help.
Giovanni
If you explain what you expect to get from the PWM and post your configuration structure I could help.
Giovanni
-
ruslanpopov
- Posts: 35
- Joined: Sun Aug 19, 2012 9:36 pm
Re: STM32F100, a PWM on Timer 17
Digging in sources have helped me to solve this problem.
Register way:
Its output is:
PWM Module way:
Its output is:
My "oscilloscope" shows the following in appropriate order:

I would appreciate an explanation when I should increment ARR value? I talk about this:
How to get the same result using prescaler value lower that STM32_SYSCLK?
Register way:
Code: Select all
//Enable clock for the timer
RCC->APB2ENR |= RCC_APB2ENR_TIM17EN;
// Enable ARR preloading
TIM17->CR1 |= TIM_CR1_ARPE;
// Enable CCR1 preloading
TIM17->CCMR1 |= TIM_CCMR1_OC2PE;
// PWM mode 1: OC1M = 110
TIM17->CCMR1 |= (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1);
// Prescaler keeps zero to allow control PWM frequency
TIM17->PSC = 0;
// PWM Frequency
TIM17->ARR = (uint16_t) (STM32_SYSCLK / PWM_FREQ);
// Duty cycle
TIM17->CCR1 = (uint16_t) (TIM17->ARR * PWM_WIDTH);
// Uncomment to change polarity
//TIM2->CCER |= TIM_CCER_CC2P;
// Enable Capture/Compare output 1, ie PB9
TIM17->CCER |= TIM_CCER_CC1E;
// Main Output enable
TIM17->BDTR |= TIM_BDTR_MOE;
// Start timer
TIM17->CR1 |= TIM_CR1_CEN;
chprintf((BaseSequentialStream *) &SD1, "TIM17->PSC = %d\n", TIM17->PSC);
chprintf((BaseSequentialStream *) &SD1, "TIM17->ARR = %d\n", TIM17->ARR);
chprintf((BaseSequentialStream *) &SD1, "TIM17->CCR1 = %d\n", TIM17->CCR1);Its output is:
Code: Select all
TIM17->PSC = 0
TIM17->ARR = 24000
TIM17->CCR1 = 12000PWM Module way:
Code: Select all
static PWMConfig pwmcfg = {
STM32_SYSCLK, /* PWM clock frequency, PSC register. */
(uint16_t) (STM32_SYSCLK / PWM_FREQ) + 1, /* Initial PWM period. ARR register*/
NULL, /* Periodic callback pointer. */
{ /* Channel configuration set dynamically below, */
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL},
{PWM_OUTPUT_DISABLED, NULL}
},
0 /* TIM CR2 register initialization data. */
#if STM32_PWM_USE_ADVANCED
,0 /* TIM BDTR register initialization data. */
#endif
};
PWMChannelConfig chcfg = { PWM_OUTPUT_ACTIVE_HIGH, NULL };
pwmcfg.channels[PWM4_CHANNEL] = chcfg;
pwmStart(&PWMD4, &pwmcfg);
pwmEnableChannel(&PWMD4, PWM4_CHANNEL,
PWM_PERCENTAGE_TO_WIDTH(&PWMD4, PWM_WIDTH * 10000));
chprintf((BaseSequentialStream *) &SD1, "TIM4->PSC = %d\n", TIM4->PSC);
chprintf((BaseSequentialStream *) &SD1, "TIM4->ARR = %d\n", TIM4->ARR);
chprintf((BaseSequentialStream *) &SD1, "TIM4->CCR4 = %d\n", TIM4->CCR4);Its output is:
Code: Select all
TIM4->PSC = 0
TIM4->ARR = 24000
TIM4->CCR4 = 12000My "oscilloscope" shows the following in appropriate order:

I would appreciate an explanation when I should increment ARR value? I talk about this:
Code: Select all
(uint16_t) (STM32_SYSCLK / PWM_FREQ) + 1How to get the same result using prescaler value lower that STM32_SYSCLK?