Skip to main content
anonymous.8
Senior II
Mar 10, 2018 5:41 PM UTC
Solved

Having problems with STM32F7 TIM1 PWM Mode 1 Output pins

Posted on March 10, 2018 at 18:41

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.

    This topic has been closed for replies.
    Tesla DeLorean
    Tesla DeLoreanBest answer
    Guru
    Mar 10, 2018 5:47 PM UTC
    Posted on March 10, 2018 at 18:47

    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;
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..

    2 replies

    Tesla DeLorean
    Tesla DeLoreanBest answer
    Guru
    Mar 10, 2018 5:47 PM UTC
    Posted on March 10, 2018 at 18:47

    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;
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    anonymous.8
    Senior II
    Mar 10, 2018 7:03 PM UTC
    Posted on March 10, 2018 at 19:03

    Clive, thank you so much. Wow, that was a fast reply too! Your suggestion does indeed solve the problem.

    Thanks, David.