You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32正交编码器模式下如何配置定时器每次计数增减触发中断

STM32 TIM编码器模式每次计数变化触发中断的实现方案

问题本质说明

你之前的方案无法实现的核心原因:

STM32定时器的更新中断仅在CNT寄存器上溢(从ARR值跳转到0)或下溢(从0跳转到ARR值)时触发。你设置ARR=1时,CNT每2次变化才会触发1次更新中断,对应100次计数仅产生50次中断符合该逻辑。另外STM32定时器ARR寄存器的合法配置最小值为1,设置为0属于无效配置,因此该路径无法满足需求。

方案1:使用定时器捕获比较(CC)中断实现(推荐)

该方案无需修改原有编码器计数逻辑,性能更稳定,不会出现外部中断可能的抖动问题:

  • 保持TIM4原有编码器模式Encoder Mode TI1 and TI2配置不变,设置TIM4->PSC = 0,TIM4->ARR = 99,刚好匹配你单圈0~99的计数范围
  • 配置TIM4的捕获比较通道1为比较匹配模式,设置初始比较值TIM4->CCR1 = TIM4->CNT,开启通道1比较中断:TIM4->DIER |= TIM_DIER_CC1IE
  • 在NVIC中开启TIM4的中断通道,配置合适的优先级
  • 中断服务函数中每次处理完业务逻辑后,更新比较值为当前CNT的值,下次CNT变化时会自动触发新的比较匹配中断

代码示例

初始化配置

// TIM4时钟、GPIO、编码器模式已配置完成的前提下
TIM4->PSC = 0;
TIM4->ARR = 99;
TIM4->CCR1 = TIM4->CNT; // 初始比较值匹配当前计数器值
TIM4->DIER |= TIM_DIER_CC1IE; // 开启CC1比较中断

// NVIC配置
NVIC_EnableIRQ(TIM4_IRQn);
NVIC_SetPriority(TIM4_IRQn, 2, 0); // 优先级按需调整

// 启动定时器
TIM4->CR1 |= TIM_CR1_CEN;

中断服务函数

void TIM4_IRQHandler(void)
{
    // 判断为CC1比较匹配中断
    if (TIM4->SR & TIM_SR_CC1IF)
    {
        TIM4->SR = ~TIM_SR_CC1IF; // 清除中断标志
        
        // 此处添加你每次计数变化需要执行的业务逻辑
        
        // 更新比较值为当前CNT,下次计数变化自动触发中断
        TIM4->CCR1 = TIM4->CNT;
    }
    
    // 如需保留原有更新中断逻辑,可在此处添加对应判断处理
}

方案2:使用GPIO双边沿外部中断实现

如果不需要占用定时器捕获比较通道,可使用该方案实现:

  • 将TIM4_CH1、TIM4_CH2对应的两个GPIO引脚配置为双边沿触发的外部中断
  • 两个外部中断共用同一个服务函数,每次触发时直接读取TIM4->CNT的值执行业务逻辑即可
  • 注意配置外部中断优先级高于其他低优先级任务,避免丢中断

内容的提问来源于stack exchange,提问作者MHBagh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 23:45:04