Skip to main content
Associate II
August 4, 2017
Question

PWM output issue when cycling frequencies

  • August 4, 2017
  • 5 replies
  • 1522 views
Posted on August 04, 2017 at 22:08

The original post was too long to process during our migration. Please click on the attachment to read the original post.
    This topic has been closed for replies.

    5 replies

    Associate II
    August 4, 2017
    Posted on August 04, 2017 at 22:35

    Looks like I may have been missing a ARPE bit in the CR1 register which enables the shadow buffer of the ARR register.

    Tesla DeLorean
    Guru
    August 4, 2017
    Posted on August 04, 2017 at 22:37

    TIM2->ARR = clk - 1; // N-1 register

    Can you do the update while paying attention to the phase? Check the elapsed time in the Update IRQ? ie >15ms step to next.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Vangelis Fortounas
    Associate II
    August 4, 2017
    Posted on August 04, 2017 at 22:44

    Hello!

    The way you chose to handle the change of cycle and width is quite anorthodox.

    The PWM generation is normaly handled by the hardware.

    If you want to change the cycle and width you must put the new values to  ARR and to CCR and wait tothe next update event of the counter to load the new values

    If you dont want to wait until the next update event you have the option fto set the EGR.UG flag to trigger an imediate update with new values.

    In your code every ttime you call the

    startPWM_Test

      is like to reinitialise the timer.

    It stops counting, loads the same values and again starts etc. .

    If you want clean pwm pulses ,

    just eliminate this code

          

    //TIM2->CNT = 0;

          

    if

    (( TIM2->

    CR1

    & TIM_CR1_CEN ) == 0)                                                         

    // first pass turn on timer and

    cfg

    , otherwise just load CCR2 and ARR to shadow registers

           {

                  TIM2->

    CCER

    &= ~

    TIM_CCER_CC3E

    ;

                  TIM2->

    PSC

    = 0;                                                                          

    // Set

    prescaler

    to 0, so APBCLK/1 i.e 1MHz

                  TIM2->

    CCMR1

    = 0;                                                                                           

    // No input capture

                  TIM2->

    CCMR2

    = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0 |TIM_CCMR2_OC3PE;

    // Set OC3 to PWM

                  TIM2->

    CCER

    |=

    TIM_CCER_CC3E

    ;                                                           

    // Enable the output on OC3 (CC3E = 1)e

                  TIM2->

    CR1

    |= TIM_CR1_CEN;                                                              

    // Enable counter (CEN = 1)

           }

    and /or  (it is your choice ) call

    TIM2->

    EGR |=0x01; //to imediately update the values

    This solution pre includes proper initialisation

    Associate II
    August 4, 2017
    Posted on August 04, 2017 at 23:08

    @ Clive 

    Thanks for noticing the -1.

    @ Vangelis

    This is demo code extracted from the main project to show the issue in a simplified manner. I was originally re-initializing the clock on each pass before I realized that those registers were shadow copied. I changed the code with the 

    if

    (( TIM2->

    CR1

    & TIM_CR1_CEN ) == 0)  statement so the timer is initialized only if the counter is off. 
    Vangelis Fortounas
    Associate II
    August 4, 2017
    Posted on August 04, 2017 at 23:27

    Hi!

    I was overtaken by the infinite loop and did not notice

    this.

    :((

    Rgrds