Skip to main content
anonymous.8
Senior II
March 10, 2018
Solved

Having problems with STM32F7 TIM1 PWM Mode 1 Output pins

  • March 10, 2018
  • 2 replies
  • 746 views
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.
    Best answer by Tesla DeLorean
    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;

    2 replies

    Tesla DeLorean
    Tesla DeLoreanBest answer
    Guru
    March 10, 2018
    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
    March 10, 2018
    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.