Showing results for 
Search instead for 
Did you mean: 

Best use of timer and timer modes

Associate II

Hello all and tks for reading,

I will develop a three-phase 60Hz rectifier, 12 pulses, thyristor controlled. The mpu to be used is the stm32f303RE and I will make the prototype on a Nucleo-64 board.

The mpu control signals will go to an already existing board, which limits the use of some pins. For example, I won't be able to use the timer channels directly, they will be triggered as GPIO's.

The mpu will receive the zero crossing signals on three pins that will be configured as external interrupts for the three phases with zero phase shift. I understand that I will need the "virtual" zero crossing to be used in the three phases shifted 30 degrees. This lag represents a delay of 1.39ms. The gates are a total of six, 3 pins for zero degrees phases and 3 pins for phases 30 degrees.

I did some tests and I'm leaning towards using OC mode, it worked right away, but pwm is still on the radar.

In this post, I would like to hear your opinion on the use of timers, it seems to me that the way I think of using them is a bit exaggerated. I think I will:

 a) use timer 1 for 3 phases with zero degrees of delay (I did the test in OC mode on channels 4, 5 and 6 only as a "frozen" timer, but channels 5 and 6 did not work).

 b) use timer 3 for 3 phases with a shift of 30 degrees, noting that the same thing that happened in T1 regarding channels 5 and 6 must occur in T3.

 c) use timers 6, 7 and 16 to create the delay, with the countdown to interrupt every 1.39ms after the start at zero crossing.

The logic of sequential events would be when a zero crossing occurs (for each phase):

 a) reset of the gate zero degrees of corresponding phase (channel)

 b) load the channel timing value (calculated separately) to adjust the output voltage

 c) start the channel timer for OC interrupt of T1

 d) start T6 (depending on the phase, it could be T7 or T16) loaded to generate an interrupt after 1.39ms

Then, when the T6 callback occurs (or T7 or T16, depending on the current phase):

 a) stop T6

 b) reset the T6 counter

 c) 30 degree offset gate reset

 e) load the channel timing value of T3

 f) start T3 channel in interrupt OC mode

The T1 callback, when it occurs, produces the corresponding gate set (which will be reset at the next zero crossing). The same goes for the T3 callback, with the difference that the gate with a 30 degree shift will be reset when the timer that produces the delay starts (T6, T7 or T16).

After the explanation above, my questions are:

 a) Is there no way to avoid the use of T3, making all activations only using T1? (I didn't see a specific way to do it, but I didn't get to explore all the possibilities of T1, hence the question)

 b) if there is any way to use the six channels of T1, how would it be to generate the 30 degree offset by T1 itself, would that be possible? how?

 c) it seems that there is a high consumption of timers to produce the delay (T6, T7 and T16). Is there no way to use a smaller number of timers?

 d) at the current stage of development, the options are open. I would like to know if the approach (the concept), shown above, is correct or would you suggest a different approach?

Thanks so much for reading and for any responses,

Best regards,


ST Employee

Hello @LCatL​,

First, let me thank you for posting these interesting questions with all the needed details!

 a) You can use timer T1 only for the 3 phrases instead of 3 timers by using the timer channels to configure the required delays

c) Instead of using multiple timers (T6, T7, T16) for generating the delay, consider using a single timer with compare match interrupt (configure the timer to generate an interrupt after x delay), when the interrupt occurs you can perform desired actions

Here are a few suggestions :

  • Consider using PWM instead of OC for better/smoother control of the thyristor firing angles
  • make sure to synchronize the zero crossing to avoid any issues with the rectifier

Hope that helps!

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello @Sarra.S,

Many thanks for answering my questions and also for the suggestions, they really are helpful!!

First of all, I must say that I don't have much knowledge of the AC manipulation and evidently I may be making gross mistakes. That's why the questions can seem like a no-brainer sense, sorry about that.
My initial post also failed to explain that I fully use CubeIDE to generate the C code that the application uses.

About the use of PWM instead of OC, how would be done this better/smoother control that you talk about?
I did the calculations using internal clock (72MHz), prescaler 9, division of clock by 1 and period of 65535. This results in a period of approximately 9ms, slightly beyond the 8.33ms value of a 60Hz half cycle.
Thus, the useful range of the OC I use is from 2000 to approximately 58000, with some left over to avoid any AC error. These values also are the limits of the output of PID calculations and represent something around 3% to 97%
of the period of the sinusoid. To change the value to the timer I use the HAL calls:
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (TIM1->CNT + new_value)); // 2000 - 58000
if (HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK) Error_Handler();
where "new_value" is the time to fire the thyristors - the sample above is the T1 channel 1 and the entire zero crossing routine for one phase is:

if (GPIO_Pin == ZC_R_Pin) // this is EXTI for the R phase
GATE_R_OFF; // turn off the R gate
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (TIM1->CNT + new_value)); // 2000 - 58000
if (HAL_TIM_OC_Start_IT(&htim1, TIM_CHANNEL_1) != HAL_OK) Error_Handler();
// start T6 for 30 degrees phase related to the R phase
if (HAL_TIM_Base_Start_IT(&htim6) != HAL_OK) __Error_Handler(__FILE__, __LINE__);
where "defas_val" is the time for 30 degrees, aproximately 1.39ms
As you can see, each zero crossing the gate is reset and there is the start of the OC interrupt and the timer that will make the lag of 30 degrees.

How should the configuration be to employ PWM? in what sense would it be better to use PWM, also interrupt?
Apparently, the code above is working ok, except when there is some switching on the AC input, from which the zero crossing derives, when then there seems to be failures in the sequence of phases, which leads to problems and misbehavior. So, the next item, synchronism. This is your second suggestion.
Could you please indicate the procedure to obtain a safer and more effective synchronization? I am currently using 3 pins as EXTI, one per phase. Is there any better alternative to get the signal from zero crossing for firmware?

I have an additional question, not described in the first post: the quick response of the mpu makes it possible for some noise to be "seen" how to zero crossing and thus cause synchronism failure with the AC?
What is the best way to reduce this risk? in the execution of the EXTI interrupt it is possible to generate a delay (something between 100 and 200us) and check the state of the pin to confirm that a zero crossing actually occurred? What's the best way to do this? through interrupt? Can I service one interrupt within another?
Is there any additional way to get the firmware-filtered zero crossing signal that I'm not considering? if yes, what would it be?

Again sorry for so many questions, especially if they seem stupid.

Thanks a lot for your help!!!

Yours sincerely,