首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F4 EXTI中断相互干扰

STM32F4 EXTI中断相互干扰
EN

Stack Overflow用户
提问于 2018-09-14 06:39:29
回答 1查看 6.9K关注 0票数 3

我正在与STM32F407VGT6单片机和我有问题的外部中断(EXTI)。我已经将两个引脚配置为EXTI,它们是PE7PE15。它们连接到霍尔传感器驱动器,并检测触发轮的尖角边缘。一个是多齿的主要来源,另一个是确定位置的单齿轮。问题是,他们可以单独工作,没有问题,但如果我把两者连接起来,他们开始互相干扰,我正在失去位置同步,因为单片机正在检测假的边缘。我可以通过连接任何一个引脚到低信号和其他霍尔驱动器重新创建相同的行为。但是,如果我禁用EXTI并将引脚作为输入,问题就会消失。我不知道这里发生了什么。

而且,我以前对PE15EXTI有过问题,这可能与此有关。EXTI只在EXTI_Trigger_RisingEXTI_Trigger_Rising_Falling模式下工作,但是EXTI_Trigger_Falling提供了随机的边缘检测,而解决这一问题的唯一解决方案是侦听两个边,并揭穿我不需要的边。我在数据表里什么都找不到。

这个STM32F4让我头疼,我没有选择了。最后一种选择是将霍尔驱动器重新路由到其他引脚,并使用输入捕获/计时器。

主轮配置:

代码语言:javascript
复制
void Trigger_Configure_Primary(void) {
  // GPIO
  GPIOE->OSPEEDR |= (0x03 << (2 * 15)); // high speed

  // EXTI
  SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI15_PE; // Tell system that you will use PE15 for EXTI15
  EXTI->RTSR |= (1 << 15); // rising edge
  EXTI->FTSR |= (1 << 15); // falling edge
  EXTI->IMR |= (1 << 15); // Unmask EXTI15 interrupt
  EXTI->PR |= (1 << 15); // Clear pending bit

  /* Add IRQ vector to NVIC */
  NVIC_SetPriority(EXTI15_10_IRQn, 0);
  NVIC_EnableIRQ(EXTI15_10_IRQn);
}

次级轮配置:

代码语言:javascript
复制
void Trigger_Configure_Secondary(void) {
  // GPIO
  GPIOE->OSPEEDR |= (0x03 << (2 * 7)); // high speed

  // EXTI
  SYSCFG->EXTICR[1] = SYSCFG_EXTICR2_EXTI7_PE; // Tell system that you will use PE7 for EXTI7
  EXTI->RTSR |= (1 << 7); // rising edge
  EXTI->FTSR |= (1 << 7); // falling edge
  EXTI->IMR |= (1 << 7); // Unmask EXTI7 interrupt
  EXTI->PR |= (1 << 7); // Clear pending bit

  /* Add IRQ vector to NVIC */
  NVIC_SetPriority(EXTI9_5_IRQn, 0);
  NVIC_EnableIRQ(EXTI9_5_IRQn);
}

IRQ处理程序:

代码语言:javascript
复制
void EXTI9_5_IRQHandler(void) {
  __disable_irq();
  /* Make sure that interrupt flag is set */
  if ((EXTI->PR & EXTI_Line7) != 0) {
    // Secondary trigger IRQ
    uint32_t now_nt = GET_TIMESTAMP();

    uint8_t edge = ((GPIOE->IDR & SECONDARY_PIN) == 0 ? 0 : 1);
    TD_Decode_Secondary_Trigger_Event(
      now_nt,
      edge
    );

#ifdef DEBUG
    // Stats
    secondary_ticks = (GET_TIMESTAMP() - now_nt);
#endif

    /* Clear interrupt flag */
    EXTI->PR |= EXTI_Line7;

    ++s_cnt;
  }
  __enable_irq();
}

void EXTI15_10_IRQHandler(void) {
  __disable_irq();
  /* Make sure that interrupt flag is set */
  if ((EXTI->PR & EXTI_Line15) != 0) {
    // Primary trigger IRQ
    uint32_t now_nt = GET_TIMESTAMP();

    uint8_t edge = ((GPIOE->IDR & PRIMARY_PIN) == 0 ? 0 : 1);
    if (primary_edge == edge) {
      TD_Decode_Primary_Trigger(now_nt);
    }

#ifdef DEBUG
    // Stats
    primary_ticks = (GET_TIMESTAMP() - now_nt);
#endif

    /* Clear interrupt flag */
    EXTI->PR |= EXTI_Line15;

    ++p_cnt;
  }
  __enable_irq();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-14 22:21:04

RM0090,12.3.6待决寄存器(EXTI_PR):

通过将其编程为“1”来清除此位。

因此,这个代码

代码语言:javascript
复制
/* Clear interrupt flag */
EXTI->PR |= EXTI_Line7;

不仅清除EXTI_Line7,而且清除所有挂起的中断,因为它为所有触发的中断读取带有1EXTI-PR,然后OR位EXTI_Line7并将所有1-es写入回。

使用

代码语言:javascript
复制
/* Clear interrupt flag */
EXTI->PR = EXTI_Line7;
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52326225

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档