cancel
Showing results for 
Search instead for 
Did you mean: 

Timer 2 as likely watchdog

OGhis
Associate III

Dear,

We using the STM32L071 and timer 2

We will using a timer where the timer output is connected a relay. (watchdog functionality)

The timer prescaler is set to a time of 2 sec.

The output should be high when the timer counter is lower than the comparison (OC1) value and the output should be low when the timer counter is higher than the comparison value.

To ensure that the output does not change, we reset the timer counter faster than the comparison value ( < 2sec)

This should be works without any interrupt.

How we can configure the timer for this functionality?

regards.

used initialisation:

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 = 4000;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 16000;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  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_OC_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
  sConfigOC.Pulse = 8000;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* USER CODE END TIM2_Init 2 */
  HAL_TIM_MspPostInit(&htim2);
 
}

To reset the counter. This will be done faster than the output compare time

__HAL_TIM_SetCounter(&htim2, 0u);

startup of the timer.

   HAL_TIM_Base_Start(&htim2); 
   HAL_TIM_OC_Start(&htim2,  TIM_CHANNEL_1);

With the above code works the timer output partly good, the output is set in high state until we don't reset the timer counter. The output switch to his low state.

After that, when we reset the timer counter again, the output doesn't change more to his high state.

__HAL_TIM_SetCounter(&htim2, 0u);

If there is a possibility to reset the output state at the same time we reset the timer counter can this resolve our issue.

2 REPLIES 2
TDK
Guru

> sConfigOC.OCMode = TIM_OCMODE_ACTIVE;

Instead of using the channel as active on match, use it in PWM mode.

You can also force the OCxREF channel low in TIMx_CCMRy_OCzM bits, but I don't know how that's done in HAL offhand.

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

I have resolved as follow, but is it the best way?

void Sync(void) {
   volatile uint16_t reg;
 
   __HAL_TIM_SetCounter( &htim2, 0u);
 
   /* force output to inactive */
   reg  = htim2.Instance->CCMR1;
   reg &= (uint16_t)(~TIM_CCMR1_OC1M_Msk);
   reg |= TIM_OCMODE_FORCED_INACTIVE;
  htim2.Instance->CCMR1 = reg;
 
   __NOP();
   __NOP();
   __NOP();
   __NOP();
 
   /* for output to active state, normal state */
   reg  = htim2.Instance->CCMR1;
   reg &= (uint16_t)(~TIM_CCMR1_OC1M_Msk);
   reg |= TIM_OCMODE_ACTIVE;
   htim2.Instance->CCMR1 = reg;
 
   /* clear the interrupt flag */
   __HAL_TIM_CLEAR_FLAG( &htim2, TIM_FLAG_CC1);
}