Skip to main content
Visitor II
August 12, 2024
Question

Phase shift with swapping polarity

  • August 12, 2024
  • 4 replies
  • 1303 views

Hi
I am working on a STM32G484QET6 uC. On a timer I have configured two output channels with Output Compare Toggle Mode. So that I get a quadrature signal.
When configuring the first value, everything works perfectly. The duty cycle is 50% and the phase shift is 90 degrees to each other.
But in my application I have to change the frequency during the run, means also the CCR value to keep the 50% duty cycle. When I update the values, I stop the timer and then, after updating I restart it. Now I have the problem that the polarity is sometimes swapping after changing the values. For example, the channel 1 signal is behind channel 2 and I want it the other way around.
How do I change the values so that this doesn't happen?

Thank you!
RLD

    This topic has been closed for replies.

    4 replies

    RLDAuthor
    Visitor II
    August 12, 2024

    Addition: The pulse for changing the frequency is triggered by a button via interrupt. So there is not much to do in terms of the timing of the change in frequency and timer values.

    ST Employee
    August 16, 2024

    Hello @RLD, welcome to ST Community, 

    I think the right sequence will be 

    1. Stop the timer 

    2. Update CCR values 

    3. Generate an update event (set UG bit in the TIMx_EGR register) to make sure that the new CCR values are loaded correctly 

    4. Restart the timer 

    Would you give it a try and let me know how it went? 

     

    RLDAuthor
    Visitor II
    August 16, 2024

    Hello @Sarra.S

    Sadly, it still doesn't work. The polarity of the phase shift still sometimes changes after calling up the function to change the frequency.

    Here is my function, if that might help:

     

    void UpdateTimerFrequencyPhaseShift(uint16_t frequency, double phaseShift)
    {
    	uint32_t psc = 1;
    	uint32_t arr;
    
    	//================================================================
    	//Calculate optimal prescaler and auto reload register for given new frequency (irrelevant for my problem)
    	while(psc < 2 * MCU_CLK / 0x10000){
    		arr = MCU_CLK / psc / frequency;
    		if(arr <= 0x10000){
    			psc--;
    			arr--;
    
    			break;
    		}
    		psc *= 2;
    		}
    	//================================================================
     HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
     HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_2);
    
    	TIM1->PSC = psc;
    	TIM1->ARR = arr/2;
    	TIM1->CCR2 = 1 + (arr*(phaseShift/360));
    
    	TIM1->EGR |= TIM_EGR_UG;
    
    	HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
    	HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2);
    }

     

    The frequency, the phase shift and the 50% duty cycle work perfectly, it's just this problem with the polarity swapping.

    Thank You!

    RLD

     

     

     

     

    Super User
    August 16, 2024
    TIM1->EGR |= TIM_EGR_UG;

    Don't.

    JW

    RLDAuthor
    Visitor II
    August 16, 2024

    Thank You!

    It works now, generating the update event was not necessary.
    I have now solved it with activating the register preload feature.

    RLD