如何配置STM32定时器在每次递增/递减时触发中断?

Posted

技术标签:

【中文标题】如何配置STM32定时器在每次递增/递减时触发中断?【英文标题】:How to configure STM32 timer to trigger interrupt on every increment/decrement? 【发布时间】:2019-09-07 20:07:12 【问题描述】:

我尝试将旋转编码器与 STM32F7 连接。计时器 (TIM1) 应该对 0-100 之间的值进行计数,并在每次增加或减少该值时触发中断。

计数有效,但我只能在每个更新事件上配置一个中断。 (如果计数器上溢/下溢)

如何配置这样的计时器?

static void MX_TIM1_Init(void)


  TIM_Encoder_InitTypeDef sConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim1.Instance = TIM1;
  htim1.Init.Prescaler = 0;
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim1.Init.Period = 99;
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim1.Init.RepetitionCounter = 0;
  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  sConfig.EncoderMode = TIM_ENCODERMODE_TI1;
  sConfig.IC1Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC1Filter = 0;
  sConfig.IC2Polarity = TIM_ICPOLARITY_RISING;
  sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI;
  sConfig.IC2Prescaler = TIM_ICPSC_DIV1;
  sConfig.IC2Filter = 0;
  if (HAL_TIM_Encoder_Init(&htim1, &sConfig) != HAL_OK)
  
    _Error_Handler(__FILE__, __LINE__);
  

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterOutputTrigger2 = TIM_TRGO2_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
  
    _Error_Handler(__FILE__, __LINE__);
  


【问题讨论】:

【参考方案1】:

这是不可能的直接 - 但你可以设置 PWM ,然后在那条线上设置 EXTI 中断。

【讨论】:

中断可能比编码器计数器快,因此如果您收到 EXTI 中断,则计数器值尚未更新。这是个坏主意。 exti from pwm 由定时器生成。那么如何让计数器无法更新 btwq st.com/content/ccc/resource/technical/document/application_note/… 编码器模式 我阅读了这份文件。我的理解是中断不是由定时器产生的,而是由外部线路上升/下降沿产生的。在这种情况下,计数器可以在该行之后更新。我知道有人得到了这个问题。但是如果你真的知道一个由定时器而不是由引脚边缘产生的中断,那么请给我解释一下。这正是我的问题。 @Caniko 这很简单 - 您的计时器会在 内部引脚 上生成 PWM。您在此引脚(线)上设置了 |EXTI。边沿由定时器生成,带出口的引脚与编码器引脚没有连接(电气)。【参考方案2】:

我相信捕获中断机制会在编码器模式下工作,所以设置TIM1->DIER |= TIM_DIER_CC1IE应该会在每次计数器变化时产生一个中断。

如果上述方法不起作用,则在 其他输入引脚上设置一个 EXTI 中断,即映射到通道 2 的那个,它不会直接更改计数器。这样您就可以稳定地读取计数器值。

【讨论】:

【参考方案3】:

您可以使用边缘检测触发器 TI1F_ED STM32F030F4P6 示例:

/* Trigger Edge Detector */
/* 100: TI1 Edge Detector (TI1F_ED) */
TIM3->SMCR &= ~(TIM_SMCR_TS_0 | TIM_SMCR_TS_1);
TIM3->SMCR |= TIM_SMCR_TS_2;
/* 1: Trigger interrupt enabled. */
TIM3->DIER |= TIM_DIER_TIE;
NVIC_EnableIRQ(TIM3_IRQn);

void TIM3_IRQHandler(void)
    if(TIM3->SR & TIM_SR_TIF)
        
    /* Here code */
    
        /* Interrupt enabled */
        TIM3->SR &= ~TIM_SR_TIF;
    

更多信息: https://www.youtube.com/watch?v=1CPk9UD4440 https://cxemka.com/71-podklyuchenie-enkodera-dupa-k-stm32-cmsis-i-hal.html

【讨论】:

以上是关于如何配置STM32定时器在每次递增/递减时触发中断?的主要内容,如果未能解决你的问题,请参考以下文章

STM32 系统定时器(SysTick)

STM32定时器触发ADC怎么配置

STM32F030 定时器多次溢出才触发中断的问题

STM32F7 定时器触发定时器

systick定时器

stm32 外部中断打断PWM