TIM2 as Master and TIM3 as Slave is not working on Blue Pill board (STM32F103C8)
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
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
*
* @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
