cancel
Showing results for 
Search instead for 
Did you mean: 

TIM2 as Master and TIM3 as Slave is not working on Blue Pill board (STM32F103C8)

ERABALF
Associate III

Hello everyone.

I am working on a project, where It has 6 PWM channels, and there will be 3 channels active at time, 

As all PWM channels must have the same frecuency, all PWMs channel must start and stop at the same time, I am trying to define TIM2 as MASTER and TIM3 as Slave.

I was testing some options, but I couldn´t move forward.......In order to SYNC (as much as possible) I set Master, Slave and CNT registers in both TIMs, so after that I defined a Breakpoint in order to check if **** are same or almost the same, but CNT from TIM2 and TIM3 are not the same, there are running not tight as I expected..

I was reading RM008 14.3.20 Timer synchronization and wrote the following lines in order to set TIM2 as Master and TIM3 as Slave (as I explained above, and it is not working)

TIM2->CR2 = TIM_TRGO_ENABLE;

TIM3->SMCR = TIM_TS_ITR1 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1; 

HAL_TIM_Base_Start_IT(&htim2);

HAL_TIM_Base_Start_IT(&htim3);

TIM2->CNT=0;

TIM3->CNT=0;

TIM2 and TIM3 are defined using CUBEMX, both timers have the same configuration at this point (setup time), but later when the program is running, when the Overflow interruption on TIM2 happened, I stop timers TIM2 and TIM3, define Master and Slave and Set **** to 0 (I am setting Master and slave every time overflow happened, I know it is not ok, but as I am just testing if clocks are working together, I guess, is not a big issue,

later I will move it outside of the loop, but I did that just to see how the clock is set when Debugger is fired just after set (manually) CNT registers to 0, STM32CUBE debugger shows TIM2/3 **** values are NOT equal...Here is a small list of 4 tests (using RESSUME button in Debug mode).

1° 2° 3° 4°

TIM2_CNT 19752  19636 24790 15430

TIM3_CNT  5351  20811 17058  7503

diff    14401  -1175  7732  7927


_legacyfs_online_stmicro_images_0693W00000Hqyym.png 

The value of **** shows me that TIM2 and TIM3 are not working in SYNC mode.... test N°2 show that TIM2 CNT is = 19636 and TIM3 CNT = 20811, when TIM2 CNT is set to Zero before TIM3 CNT....I know, Timers are not set correctly,

this is the TIM2 and TIM3 configuration done it by CUBMX:

static void MX_TIM2_Init(void)

{

 /* USER CODE BEGIN TIM2_Init 0 */

 /* USER CODE END TIM2_Init 0 */

 TIM_ClockConfigTypeDef sClockSourceConfig = {0};

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 TIM_OC_InitTypeDef sConfigOC = {0};

 /* USER CODE BEGIN TIM2_Init 1 */

 /* USER CODE END TIM2_Init 1 */

 htim2.Instance = TIM2;

 htim2.Init.Prescaler = 0;

 htim2.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim2.Init.Period = 65535;

 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)

 {

  Error_Handler();

 }

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

 if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 0;

 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;

 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM2_Init 2 */

 /* USER CODE END TIM2_Init 2 */

 HAL_TIM_MspPostInit(&htim2);

}

/**

 * @brief TIM3 Initialization Function

 * @PAram None

 * @retval None

 */

static void MX_TIM3_Init(void)

{

 /* USER CODE BEGIN TIM3_Init 0 */

 /* USER CODE END TIM3_Init 0 */

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 TIM_OC_InitTypeDef sConfigOC = {0};

 /* USER CODE BEGIN TIM3_Init 1 */

 /* USER CODE END TIM3_Init 1 */

 htim3.Instance = TIM3;

 htim3.Init.Prescaler = 0;

 htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim3.Init.Period = 65535;

 htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

 if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 0;

 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

 sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;

 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM3_Init 2 */

 /* USER CODE END TIM3_Init 2 */

 HAL_TIM_MspPostInit(&htim3);

}

in few words, I need to control 6 PWMs channels, using Overflow interruption from TIM2, when INT is fire, the main program loads some value from an array to CCRs, here is an example of two PWMs ports:

if (R_negativo==0) // estamos entre el INDICE 0 y 1499, es semiciclo +

{

TIM2->CCR1=lookUptable1[LookUpTableIndiceUsar_R]; //Fase R Semiciclo +

TIM3->CCR1=0;                   //Fase R Semiciclo -

}

else

{

TIM2->CCR1=0;                   //Fase R Semiciclo +

TIM3->CCR1=lookUptable1[LookUpTableIndiceUsar_R]; //Fase R Semiciclo -

  }

So, as all CCRs (there are 6, but 3 are active at the same time) must be loaded at the same time, that is the reason why I need to have TIM2 and TIM3 working as master/slave.

I hope you can understand my issue.

if you can help/guide me, I will appreciate any comments, advice...

Regards

Alfredo

1 ACCEPTED SOLUTION

Accepted Solutions

> It means: I need to set up TIMX as Master (not used until now) and TIM2/TIM3 as Slave?

Yes, exactly.

> is that correct?

I believe so. If it doesn't work, post your full timer setup code and I will take a look.

Careful mixing register access and HAL functions. For the timer, I usually prefer direct register access. But I believe what you wrote should work.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
TDK
Guru

Reading register values in the debugger is not a viable strategy for checking if they're synchronized. First, the timers do not stop by default when the debugger is paused. Second, the debugger is not reading them at the exact same time. In the case of fast timers, there is no hope they will be equal.

A better strategy would be to set up a PWM signal on both timers and verify on scope they put out the same signal.

If you want two timers exactly synchronized, set both of them in slave triggered mode set to start on the TRGO signal of a master timer, then start the master timer. There are other ways, but that one is straightforward. If you can live with a few counts difference, then setting CNT=0 in sequence like you're doing will suffice.

If you feel a post has answered your question, please click "Accept as Solution".
ERABALF
Associate III

Hi TDK.

First, thanks alot for your comments, I will check it with my oscilloscope.

You said:If you want two timers exactly synchronized, set both of them in slave triggered mode set to start on the TRGO signal of a master timer, then start the master timer. There are other ways, but that one is straightforward. If you can live with a few counts difference, then setting CNT=0 in sequence like you're doing will suffice

It means: I need to set up TIMX as Master (not used until now) and TIM2/TIM3 as Slave?

for example:

TIM4 as Master (no used at this time)

TIM2 and TIM3 as Slave (timers handler of 6 PWM channels)

TIM4->CR2 = TIM_TRGO_ENABLE;

TIM2->SMCR = TIM_TS_ITR3 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1; 

TIM3->SMCR = TIM_TS_ITR3 | TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1; 

TIM2->CNT=0;

TIM3->CNT=0;

HAL_TIM_Base_Start_IT(&htim2); // Slave

HAL_TIM_Base_Start_IT(&htim3); // Slave

HAL_TIM_Base_Start_IT(&htim4); // Master

is that correct?

br

Alfredo

> It means: I need to set up TIMX as Master (not used until now) and TIM2/TIM3 as Slave?

Yes, exactly.

> is that correct?

I believe so. If it doesn't work, post your full timer setup code and I will take a look.

Careful mixing register access and HAL functions. For the timer, I usually prefer direct register access. But I believe what you wrote should work.

If you feel a post has answered your question, please click "Accept as Solution".

TDK.

STM32F103C8 has 4 timers:

TIM1 is used for general use, this timer trigger keypad scan, ADC triggering, etc.

TIM2&TIM3 are used by PWM Channels

TIM4 is uded for encoder, I have one encoder working on this TIM4, untik now, as TIM4 is used by an encoder channel, Normal timer is desabled, i guess, it is because encoder is a counter and it is using timer function.....

So, I can´t use an extra TIM as Master to control TIM2 and TIM3.

if there isn´t option to set TIM2 as Master and TIM3 as slave, I will need to use an extra micro (using I2C between then) in order to have an STM32 just to handle 6 PWM channels with 3 timer of 4.

Please, if you can confirm that TIM2 can´t be Master and TIM3 slave, at the same time TIM3 is handling 3 PWM channels and TIM4 too, in order to start to move some function to other STM32,

Alfredo

Hi TDK.

Finally TIM2 is working as Mater and TIM3 as Slave in STM32F103C8.

Here is the setup in both timers...

TIM2 as Master:

0693W00000HrWUCQA3.png 

TIM3 as Slave:

0693W00000HrWUgQAN.png 

This picture was taken when TIM2 and TIM3 were not working as master/Slave:

0693W00000HrWW8QAN.pngAnd now, when TIM2 and TIM3 started to work as master Slave (Slave in TRIGGERED Mode)

0693W00000HrWXVQA3.png 

Thank alot for youe help.

now I have an issue working with I2C ( i am trying to connect 2 Blue Pill Borad with "STM32F103C8"), but until now, Slave can´t received any data, I will find if this issue was reported by other guy, if not I will open a new question in roder to get support from ST community.

Thank you TDK.

br

Alfredo

Hi TDK.

Finally TIM2 is working as Mater and TIM3 as Slave in STM32F103C8.

Here is the setup in both timers...

TIM2 as Master:

0693W00000HrWUCQA3.png 

TIM3 as Slave:

0693W00000HrWUgQAN.png 

This picture was taken when TIM2 and TIM3 were not working as master/Slave:

0693W00000HrWW8QAN.pngAnd now, when TIM2 and TIM3 started to work as master Slave (Slave in TRIGGERED Mode)

0693W00000HrWXVQA3.png 

Thank alot for youe help.

now I have an issue working with I2C ( i am trying to connect 2 Blue Pill Borad with "STM32F103C8"), but until now, Slave can´t received any data, I will find if this issue was reported by other guy, if not I will open a new question in roder to get support from ST community.

Thank you TDK.

br

Alfredo