2018-03-10 09:41 AM
Hi all. I am using an STM32F767VGT6 in a custom board. I am trying to use TIM1 to generate four independent PWM output pulses on each of its CH1 - CH4 output pins.
I have successfully implemented this elsewhere in my system using one channel only, CH1, on TIM10. My TIM1 Timer init code is almost identical, yet I cannot get the PWM pulses to appear on the PB9, PB11, PB13 and PB14 pins.If I switch on the TIM1 Update and CC interrupts and poke the pins in the interrupt handlers, I can get the correct waveforms, but I shouldn't have to do that, the TIM1 peripheral should change the pins by itself with no interrupts needed.
So I know the pins, when set as regular GPIO pins, and also the board, all work. The problem is that when I set those pins to be GPIO_AF1_TIM1 and switch off the interrupts which are not needed for any other purpose, I don't get any PWM waveform on any of those CH1 - CH4 pins.Apart from the fact that TIM1 is an advanced timer with lots of bells and whistles which I don't need, and TIM10 is a regular simpler timer, I can't figure out what I am missing in my TIM1 init code to make it work just like my TIM10 does elsewhere.
I have attached my TIM1 Init code here. Can anyone see what is wrong? Thanks.
Solved! Go to Solution.
2018-03-10 09:47 AM
On Advanced TIM (ie 1 and 8) you must explicitly enable PWM Output (Input)
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
{ /* Check the parameters */ assert_param(IS_TIM_LIST4_PERIPH(TIMx)); assert_param(IS_FUNCTIONAL_STATE(NewState));if (NewState != DISABLE)
{ /* Enable the TIM Main Output */ TIMx->BDTR |= TIM_BDTR_MOE; } else { /* Disable the TIM Main Output */ TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE; }}Also ARR needs to be written as an N-1 value, marks the last value on N for 0 thru N-1
// Setup 16ms period using the AutoReload register
TIM1->ARR = 16000 - 1;2018-03-10 09:47 AM
On Advanced TIM (ie 1 and 8) you must explicitly enable PWM Output (Input)
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
{ /* Check the parameters */ assert_param(IS_TIM_LIST4_PERIPH(TIMx)); assert_param(IS_FUNCTIONAL_STATE(NewState));if (NewState != DISABLE)
{ /* Enable the TIM Main Output */ TIMx->BDTR |= TIM_BDTR_MOE; } else { /* Disable the TIM Main Output */ TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE; }}Also ARR needs to be written as an N-1 value, marks the last value on N for 0 thru N-1
// Setup 16ms period using the AutoReload register
TIM1->ARR = 16000 - 1;2018-03-10 11:03 AM
Clive, thank you so much. Wow, that was a fast reply too! Your suggestion does indeed solve the problem.
Thanks, David.