Я работаю с микроконтроллером STM32F407VGT6 и у меня возникли проблемы с внешними прерываниями (EXTI
).Я настроил два контакта как EXTI
, и они PE7
и PE15
.Они подключены к датчику Холла привода и обнаруживают края зубьев спускового колеса.Один является первичным источником с несколькими зубьями, а другое колесо - это однозубое колесо, которое подтверждает положение.Дело в том, что они могут работать индивидуально самостоятельно без проблем, но если я соединю их обоих, они начнут мешать друг другу, и я теряю синхронизацию положения, потому что MCU обнаруживает ложные фронты.Я могу воссоздать то же поведение, подключив любой контакт к слабому сигналу, а другой к драйверу HALL.Но если я отключу EXTI
и оставлю пин-код в качестве входа, проблема исчезнет.Я понятия не имею, что здесь происходит.
Кроме того, у меня были проблемы с PE15
и EXTI
раньше, и это может быть связано с этим.EXTI
работал только в режимах EXTI_Trigger_Rising
и EXTI_Trigger_Rising_Falling
, но EXTI_Trigger_Falling
давал обнаружение случайных фронтов, и единственным решением этой проблемы было прослушивание обоих краев и отмена того, который мне не нужен.Я не смог найти ничего об этом в таблице.
Этот STM32F4 вызывает головную боль, и у меня заканчиваются варианты.Ну, последний вариант - перенаправить драйверы зала на другие контакты и использовать входной захват / таймер.
Конфигурация основного колеса:
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);
}
Конфигурация дополнительного колеса:
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:
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();
}