2024-08-21 02:09 AM
Hello, my problem is as follows:
I am working with an STM32G484QET6 uC. I have configured two timers with two output channels as Output Compare Toggle Mode. So that I get two independent quadrature signals.
I now want to synchronise these two quadrature signals. My idea of the procedure is like this:
1. stop both timer and signal generation
2. reset both timers
3. start both timer and signal generation
This is my code:
void syncTimers(void);
{
HAL_TIM_Base_Stop(&htim1);
HAL_TIM_Base_Stop(&htim8);
HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Stop(&htim1, TIM_CHANNEL_2);
HAL_TIM_OC_Stop(&htim8, TIM_CHANNEL_1);
HAL_TIM_OC_Stop(&htim8, TIM_CHANNEL_2);
TIM1->EGR |= TIM_EGR_UG;
TIM8->EGR |= TIM_EGR_UG;
HAL_TIM_Base_Start(&htim1);
HAL_TIM_Base_Start(&htim8);
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim1, TIM_CHANNEL_2);
HAL_TIM_OC_Start(&htim8, TIM_CHANNEL_1);
HAL_TIM_OC_Start(&htim8, TIM_CHANNEL_2);
}
This works quite well so far, the Timers are then synchronised with each other. However, the problem is probably that, since I have configured OC mode Toggle, the start values of the quadrature signal are different and are therefore the signal is sometimes inverted.
Correct:
wrong:
My question now is this: How can I reset the pin value completely so that both timers start cleanly from 0? Or is there another way to achieve the wanted synchronisation?
Solved! Go to Solution.
2024-08-21 05:32 AM
A few different ways to do this. Probably easiest is to force the value low by modifying OCxM temporarily before switching back to toggle mode.
2024-08-21 05:32 AM
A few different ways to do this. Probably easiest is to force the value low by modifying OCxM temporarily before switching back to toggle mode.
2024-08-22 01:47 AM
Thank you very much, that worked, the leading signal is now always synchronised. However, it now sometimes happens that the phase shift signals are inverted in relation to each other.
I think this is due to the same problem as before. I also tried to reset them with the CCMR2 register, but that didn't work. Is there another possibility?
I thought I could solve the current problem by reading the status of the pins and correcting the phase shift manually. Can I do this with the HAL_GPIO_ReadPin() function, even though they are configured as timer output?
2024-08-22 02:12 AM
> I thought I could solve the current problem by reading the status of the pins and correcting the phase shift manually. Can I do this with the HAL_GPIO_ReadPin() function, even though they are configured as timer output?
Yes - pins can be always read even if set to AF (or Out - but not Analog).
JW
2024-08-22 05:25 AM
> I also tried to reset them with the CCMR2 register, but that didn't work. Is there another possibility?
You're using channels 1 and 2 which are controlled with the OC1M and OC2M fields which are both in the CCMR1 register. That should work. CCMR2 controls channels 3 and 4.
Or use HAL_GPIO_ReadPin() but that seems more complicated.
2024-08-22 06:07 AM
I personally would perhaps give up on the idea of using the Toggle mode for this purpose, as it sounds to be an easy source of problems. If the output is not to be very fast, I would perhaps simply do things in software; if it would need to be faster, I would perhaps try timer-triggered-DMA-to-GPIO from a couple of tables (one for "forward", other for "reverse" direction).
But of course there are many ways to implement this and the circumstances may determine which are better.
JW
2024-08-22 07:09 AM
If only two signals required use "Combine PWM" mode, G4 supports it. Only 1 timer necessary.
2024-08-22 09:58 PM
Alright, the output speed is not such a problem for me, but I will have a look at this option
2024-08-22 10:03 PM
Yes, that would be the simplest solution, but unfortunately I have to use two timers because I also have to control the quadrature signals individually (frequency, duty cycle and phase shift). And that wouldn't be possible with one timer, as it can only have one frequency. The synchronisation of the signals is only a necessary feature in my application and not a main function.