【问题标题】:STM32 Timer Output compare not working properSTM32定时器输出比较不能正常工作
【发布时间】:2020-07-09 17:52:23
【问题描述】:

我正在使用 STM32L476 Nucleo 板和 STM32CubeMX。我想将输出比较通道 1 用于 2 毫秒的超时。我已经配置了定时器,但定时器没有为输出比较提供中断。我在给定时器的时间段内收到中断,但不是输出比较。

这是我的定时器配置:

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);

}

我尝试更改 sConfigOC.Pulse 值,但没有看到预期的行为。

【问题讨论】:

    标签: timer embedded stm32 nucleo


    【解决方案1】:

    您是否在中断处理程序中检查正确的中断标志? 另外请记住,您必须立即清除标志。

    我的 IRQHandler 看起来像这样,如果这对你有帮助的话。

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

    编辑:

    看起来不错,HAL_TIM_OC_DelayElapsedCallback 中断仅在计时器溢出(即重置)时触发。 这意味着您必须启用溢出中断,因为HAL_TIM_OC_Start_IT 仅启用捕获/比较中断。 您只需要在启用计时器之前启用它即可。

    __HAL_TIM_ENABLE_IT(&tim3, TIM_IT_UPDATE );
    

    【讨论】:

    • 这个标志在 HAL 库的定时器处理函数中被清除。
    • 好的,我做了一些研究,发现了一些有趣的东西。但它没有很好的记录。
    【解决方案2】:

    尝试将“TIM_IT_CC1”替换为“TIM_CHANNEL_1”。

    【讨论】:

    • 虽然它可能会解决问题,但这更像是一个评论而不是一个答案,因为它是一个问题并且没有上下文。
    【解决方案3】:

    首先,您必须在启动定时器之前初始化输出引脚:

    /* USER CODE END TIM1_Init 2 */
    HAL_TIM_MspPostInit(&htim1);
    
    /* USER CODE BEGIN TIM1_Init 2 */
    HAL_TIM_OC_Start_IT(&htim1,TIM_IT_CC1);
    

    其次,你要启动输出定时器

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

    你的输出引脚是这样启用的: (此代码适用于 Stm32F4xx)

    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);
    

    我不确定您是否需要 BREAK 代码。看看参考手册中的17.3.12使用break函数

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      相关资源
      最近更新 更多