cancel
Showing results for 
Search instead for 
Did you mean: 

How to stop PWMs with Break-Input in master-slave configuration?

Frank Munk
Associate

Hi ST Community,

I hope someone can help me with the following problem:

I am working an a Nucleo STM32F303K8 (with Cube MX and True Atollic) and would like to produce some PWM signals from it. So TIM1 and TIM2 are producing PWM just exactly how I would like to have them.

Further I would like to stop them by an external signal immediately. Therefore I want to use the break function from TIM1 which acts as master for other TIM2. TRGO from TIM1 is set as OC1, and TIM2 is running as slave in the reset mode. Break 2 is used on TIM1.

However after giving an adequate signal in break-2-input, TIM1 stops as it is supposed to stop, but TIM is producing pulses at the exact same rate as before. The same is true when slave mode is changed to trigger. Looks like OC1 is unchanged although the break function should have stopped it? 

Do you have any idea or hints?

Thank you very much in advance!

Regards,

Frank

Timer Config looks like:

static void MX_TIM1_Init(void)

{

 /* USER CODE BEGIN TIM1_Init 0 */

 /* USER CODE END TIM1_Init 0 */

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 TIM_OC_InitTypeDef sConfigOC = {0};

 TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

 /* USER CODE BEGIN TIM1_Init 1 */

 /* USER CODE END TIM1_Init 1 */

 htim1.Instance = TIM1;

 htim1.Init.Prescaler = 0;

 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim1.Init.Period = 120;

 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim1.Init.RepetitionCounter = 0;

 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;

 sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_OC1;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

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

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_COMBINED_PWM2;

 sConfigOC.Pulse = 0;

 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

 sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

 sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

 sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

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

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 20;

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

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_COMBINED_PWM2;

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

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 40;

 if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)

 {

  Error_Handler();

 }

 sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_ENABLE;

 sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_ENABLE;

 sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

 sBreakDeadTimeConfig.DeadTime = 0;

 sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

 sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;

 sBreakDeadTimeConfig.BreakFilter = 0;

 sBreakDeadTimeConfig.Break2State = TIM_BREAK2_ENABLE;

 sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_LOW;

 sBreakDeadTimeConfig.Break2Filter = 0;

 sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;

 if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM1_Init 2 */

 /* USER CODE END TIM1_Init 2 */

 HAL_TIM_MspPostInit(&htim1);

}

/**

 * @brief TIM2 Initialization Function

 * @param None

 * @retval None

 */

static void MX_TIM2_Init(void)

{

 /* USER CODE BEGIN TIM2_Init 0 */

 /* USER CODE END TIM2_Init 0 */

 TIM_ClearInputConfigTypeDef sClearInputConfig = {0};

 TIM_SlaveConfigTypeDef sSlaveConfig = {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 = 160;

 htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim2) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)

 {

  Error_Handler();

 }

 sClearInputConfig.ClearInputState = ENABLE;

 sClearInputConfig.ClearInputSource = TIM_CLEARINPUTSOURCE_OCREFCLR;

 if (HAL_TIM_ConfigOCrefClear(&htim2, &sClearInputConfig, TIM_CHANNEL_1) != HAL_OK)

 {

  Error_Handler();

 }

 if (HAL_TIM_ConfigOCrefClear(&htim2, &sClearInputConfig, TIM_CHANNEL_2) != HAL_OK)

 {

  Error_Handler();

 }

 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;

 sSlaveConfig.InputTrigger = TIM_TS_ITR0;

 if (HAL_TIM_SlaveConfigSynchronization(&htim2, &sSlaveConfig) != HAL_OK)

 {

  Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

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

 {

  Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_COMBINED_PWM2;

 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.OCMode = TIM_OCMODE_PWM1;

 sConfigOC.Pulse = 10;

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

 {

  Error_Handler();

 }

 /* USER CODE BEGIN TIM2_Init 2 */

 /* USER CODE END TIM2_Init 2 */

 HAL_TIM_MspPostInit(&htim2);

1 REPLY 1

> TRGO from TIM1 is set as OC1

There is no such setting; it's just that Cube/CubeMX is written incompetently. Read the reference manual.

You probably set TIMx_CR2.MMS to 0b100, i.e. TRGO is OC1REF. However, breaks act on the output enable module, not on the OCxREF generator, that's why TRGO is unaffected by the break.

JW