1
votes

La sortie de la minuterie STM32 ne fonctionne pas correctement

J'utilise la carte Nucleo STM32L476 et STM32CubeMX. Je souhaite utiliser le canal de comparaison de sortie 1 pour une temporisation de 2 ms. J'ai configuré la minuterie, mais la minuterie ne donne pas d'interruptions pour la comparaison de sortie. Je reçois des interruptions pour la période que j'ai donnée à la minuterie, mais pas pour la comparaison de sortie.

Voici ma configuration de la minuterie:

static void MX_TIM1_Init(void)
{

  /* USER CODE BEGIN TIM1_Init 0 */

  /* USER CODE END TIM1_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_SlaveConfigTypeDef sSlaveConfig = {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 = TIMER1_PRESCALER_VAL;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = TIMER_PERIOD;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_OC_Init(&htim1) != HAL_OK)
  {
    Error_Handler();
  }
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE;
  sSlaveConfig.InputTrigger = TIM_TS_ITR0;
  if (HAL_TIM_SlaveConfigSynchro(&htim1, &sSlaveConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC1REF;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_ACTIVE;
  sConfigOC.Pulse = 1000 * TIMER_OC_1_VAL;
  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_OC_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
  sBreakDeadTimeConfig.DeadTime = 0;
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
  sBreakDeadTimeConfig.BreakFilter = 0;
  sBreakDeadTimeConfig.Break2State = TIM_BREAK2_DISABLE;
  sBreakDeadTimeConfig.Break2Polarity = TIM_BREAK2POLARITY_HIGH;
  sBreakDeadTimeConfig.Break2Filter = 0;
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM1_Init 2 */
  HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);

  /* USER CODE END TIM1_Init 2 */
  HAL_TIM_MspPostInit(&htim1);

}

J'ai essayé de changer le sConfigOC.Pulse mais je ne vois pas le comportement attendu.


0 commentaires

3 Réponses :


1
votes

Recherchez-vous le bon indicateur d'interruption dans le gestionnaire d'interruption? Gardez également à l'esprit que vous devez effacer l'indicateur tout de suite.

Mon IRQHandler ressemble à ceci, si cela peut vous aider.

__HAL_TIM_ENABLE_IT(&tim3, TIM_IT_UPDATE );

Modifier :

OK comme il semble, l'interruption HAL_TIM_OC_DelayElapsedCallback n'est déclenchée que lorsque la minuterie déborde (c'est-à-dire, se réinitialise). Cela signifie que vous devez activer l'interruption de débordement , car HAL_TIM_OC_Start_IT n'active que l'interruption de capture / comparaison. Il vous suffit de l'activer avant d'activer le minuteur.

void TIM3_IRQHandler(void) {

    if(LL_TIM_IsActiveFlag_CC1(TIM3) == 1) {
        LL_TIM_ClearFlag_CC1(TIM3);
        TimerCaptureCompare_Callback();
    }
}


2 commentaires

Cet indicateur est effacé dans la fonction de gestionnaire de minuterie qui fait partie de la bibliothèque HAL.


Ok, j'ai fait des recherches et j'ai trouvé des trucs intéressants. Mais ce n'est pas bien documenté.



0
votes

Essayez de remplacer "TIM_IT_CC1" par "TIM_CHANNEL_1".


1 commentaires

Bien que cela puisse résoudre le problème, il s'agit plus d'un commentaire que d'une réponse car il s'agit d'une question et sans contexte.



0
votes

Premièrement, vous devez initialiser la broche de sortie avant de démarrer le minuteur comme ça:

GPIO_InitStruct.Pin = GPIO_PIN_9; // channel 1
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

Deuxièmement, vous devez démarrer le minuteur de sortie

HAL_TIM_OC_Start_IT( &htim1, TIM_CHANNEL_1 );
HAL_TIM_Base_Start_IT( &htim1 );


0 commentaires