STM32F0: Прерывание на EXTI1/EXTI2 не срабатывает, в то время как EXTI4 работает. *смущенный*

не могли бы вы помочь мне здесь и сказать мне, что я делаю неправильно? EXTI1 и EXTI2 не срабатывают, а EXTI4 работает безупречно. Это не оборудование. Если я переключу контакты, новая кнопка EXTI4 будет продолжать срабатывать, а кнопка, с которой я ее переключил, больше не срабатывает.

Я тщательно проверил все сегменты и не могу понять, почему EXTI0

ENCODER_STM32_configureInterface();
IRQHandler не срабатывает, а EXTI4_15_IRQHandler срабатывает. Пожалуйста, посмотрите два файла ниже, которые я использую для библиотеки. Я использую SPL с OpenSTM32 IDE. "main.c" только вызывает

ENCODER_STM32_configureInterface();

так что на самом деле больше ничего не происходит.

// ENCODER_STM32 library: This library shall enable interfacing an encoder on an STM32F0 chip.

// GPIO Definitions
#define    ENCODER_GPIO_PORT       GPIOA
#define    ENCODER_GPIO_CLK_PIN    GPIO_Pin_1
#define    ENCODER_GPIO_DT_PIN     GPIO_Pin_2
#define    ENCODER_GPIO_SW_PIN     GPIO_Pin_4
#define    ENCODER_GPIO_PERIPH     RCC_AHBPeriph_GPIOA

// EXTI Definitions
#define    ENCODER_EXTI_PORTSRC    EXTI_PortSourceGPIOA
#define    ENCODER_EXTI_CLK_PINSRC EXTI_PinSource1
#define    ENCODER_EXTI_CLK_LINE   EXTI_Line1
#define    ENCODER_EXTI_DT_PINSRC  EXTI_PinSource2
#define    ENCODER_EXTI_DT_LINE    EXTI_Line2
#define    ENCODER_EXTI_SW_PINSRC  EXTI_PinSource4
#define    ENCODER_EXTI_SW_LINE    EXTI_Line4
#define    ENCODER_EXTI_PERIPH     RCC_APB2Periph_SYSCFG
#define    ENCODER_EXTI_MODE       EXTI_Mode_Interrupt
#define    ENCODER_EXTI_TRIGGER    EXTI_Trigger_Falling

// NVIC Definitions
#define    ENCODER_NVIC_CLK_CHA    EXTI0_1_IRQn
#define    ENCODER_NVIC_DT_CHA     EXTI2
#include "stm32f0xx.h"
#include "usart_stm32_console.h"
#include "encoder_stm32.h"

void ENCODER_STM32_configureInterface(void) {

    // Enabling Clocks
    RCC_AHBPeriphClockCmd(ENCODER_GPIO_PERIPH, ENABLE);
    RCC_APB2PeriphClockCmd(ENCODER_EXTI_PERIPH, ENABLE);

    // Configuring GPIO
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Pin = ENCODER_GPIO_CLK_PIN | ENCODER_GPIO_DT_PIN | ENCODER_GPIO_SW_PIN;
    GPIO_Init(ENCODER_GPIO_PORT, &GPIO_InitStructure);

    // Configuring EXTI
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = ENCODER_EXTI_CLK_LINE | ENCODER_EXTI_DT_LINE | ENCODER_EXTI_SW_LINE;
    EXTI_InitStructure.EXTI_Mode = ENCODER_EXTI_MODE;
    EXTI_InitStructure.EXTI_Trigger = ENCODER_EXTI_TRIGGER;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    SYSCFG_EXTILineConfig(ENCODER_EXTI_PORTSRC, ENCODER_EXTI_CLK_PINSRC);
    SYSCFG_EXTILineConfig(ENCODER_EXTI_PORTSRC, ENCODER_EXTI_DT_PINSRC);
    SYSCFG_EXTILineConfig(ENCODER_EXTI_PORTSRC, ENCODER_EXTI_SW_PINSRC);
    EXTI_Init(&EXTI_InitStructure);

    // Configuring NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = ENCODER_NVIC_CLK_CHA | ENCODER_NVIC_DT_CHA | ENCODER_NVIC_SW_CHA;
    NVIC_InitStructure.NVIC_IRQChannelPriority = ENCODER_NVIC_PRIORITY;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}


void EXTI0_1_IRQHandler(void) {

    USART_STM32_sendToUSART("IRQ0_1 triggered");

    if(EXTI_GetITStatus(ENCODER_EXTI_CLK_LINE) != RESET) {
        USART_STM32_sendToUSART("CLK triggered");
        EXTI_ClearITPendingBit(ENCODER_EXTI_CLK_LINE);
    }

}


void EXTI2_3_IRQHandler(void) {

    USART_STM32_sendToUSART("IRQ2_3 triggered");

    if(EXTI_GetITStatus(ENCODER_EXTI_DT_LINE) != RESET) {
        USART_STM32_sendToUSART("DT triggered");
        EXTI_ClearITPendingBit(ENCODER_EXTI_DT_LINE);
    }

}


void EXTI4_15_IRQHandler(void) {

    USART_STM32_sendToUSART("IRQ4_15 triggered");

    if(EXTI_GetITStatus(ENCODER_EXTI_SW_LINE) != RESET) {
        USART_STM32_sendToUSART("SW triggered");
        EXTI_ClearITPendingBit(ENCODER_EXTI_SW_LINE);
    }

}
IRQn #define ENCODER_NVIC_SW_CHA EXTI4_15_IRQn #define ENCODER_NVIC_PRIORITY 0x03 // Variable Definitions // Parameter Definitions // Function Definitions // Function Declarations void ENCODER_STM32_configureInterface(void);

и...

#include "stm32f0xx.h"
#include "usart_stm32_console.h"
#include "encoder_stm32.h"

void ENCODER_STM32_configureInterface(void) {

    // Enabling Clocks
    RCC_AHBPeriphClockCmd(ENCODER_GPIO_PERIPH, ENABLE);
    RCC_APB2PeriphClockCmd(ENCODER_EXTI_PERIPH, ENABLE);

    // Configuring GPIO
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Pin = ENCODER_GPIO_CLK_PIN | ENCODER_GPIO_DT_PIN | ENCODER_GPIO_SW_PIN;
    GPIO_Init(ENCODER_GPIO_PORT, &GPIO_InitStructure);

    // Configuring EXTI
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line = ENCODER_EXTI_CLK_LINE | ENCODER_EXTI_DT_LINE | ENCODER_EXTI_SW_LINE;
    EXTI_InitStructure.EXTI_Mode = ENCODER_EXTI_MODE;
    EXTI_InitStructure.EXTI_Trigger = ENCODER_EXTI_TRIGGER;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    SYSCFG_EXTILineConfig(ENCODER_EXTI_PORTSRC, ENCODER_EXTI_CLK_PINSRC);
    SYSCFG_EXTILineConfig(ENCODER_EXTI_PORTSRC, ENCODER_EXTI_DT_PINSRC);
    SYSCFG_EXTILineConfig(ENCODER_EXTI_PORTSRC, ENCODER_EXTI_SW_PINSRC);
    EXTI_Init(&EXTI_InitStructure);

    // Configuring NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = ENCODER_NVIC_CLK_CHA | ENCODER_NVIC_DT_CHA | ENCODER_NVIC_SW_CHA;
    NVIC_InitStructure.NVIC_IRQChannelPriority = ENCODER_NVIC_PRIORITY;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

}


void EXTI0_1_IRQHandler(void) {

    USART_STM32_sendToUSART("IRQ0_1 triggered");

    if(EXTI_GetITStatus(ENCODER_EXTI_CLK_LINE) != RESET) {
        USART_STM32_sendToUSART("CLK triggered");
        EXTI_ClearITPendingBit(ENCODER_EXTI_CLK_LINE);
    }

}


void EXTI2_3_IRQHandler(void) {

    USART_STM32_sendToUSART("IRQ2_3 triggered");

    if(EXTI_GetITStatus(ENCODER_EXTI_DT_LINE) != RESET) {
        USART_STM32_sendToUSART("DT triggered");
        EXTI_ClearITPendingBit(ENCODER_EXTI_DT_LINE);
    }

}


void EXTI4_15_IRQHandler(void) {

    USART_STM32_sendToUSART("IRQ4_15 triggered");

    if(EXTI_GetITStatus(ENCODER_EXTI_SW_LINE) != RESET) {
        USART_STM32_sendToUSART("SW triggered");
        EXTI_ClearITPendingBit(ENCODER_EXTI_SW_LINE);
    }

}

person Florian Uhlemann    schedule 15.07.2017    source источник
comment
Я пробовал с HAL через CubeMX, и он работает, поэтому проблема не может быть в перегрузке активированных компонентов. Что-то не так с кодом в конфигурации SPL, как указано выше, что мешает ему работать. Я просто не вижу этого.   -  person Florian Uhlemann    schedule 15.07.2017
comment
Кого волнует SPL, который уже мертв 5 лет. В любом случае, по моему личному мнению, писать такие простые подпрограммы с использованием таких замечательных библиотек, как HAL или SPL, просто смешно.   -  person 0___________    schedule 15.07.2017


Ответы (1)


NVIC_Init() работает с одним прерыванием за раз, потому что NVIC_InitStructure.NVIC_IRQChannel — это не битовая маска, а простой идентификатор.

Посмотрите определение каналов IRQ в шапке:

  EXTI0_1_IRQn                = 5,      /*!< EXTI Line 0 and 1 Interrupts                            */
  EXTI2_3_IRQn                = 6,      /*!< EXTI Line 2 and 3 Interrupts                            */
  EXTI4_15_IRQn               = 7,      /*!< EXTI Line 4 to 15 Interrupts                            */

Или объединять их вместе, как биты маски, не имеет смысла, но в данном конкретном случае 5|6|7 дает 7, что случайно равняется номеру прерывания EXTI4, поэтому эта кнопка работает.

Просто позвоните NVIC_Init() три раза:

NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = ENCODER_NVIC_CLK_CHA;
NVIC_InitStructure.NVIC_IRQChannelPriority = ENCODER_NVIC_PRIORITY;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = ENCODER_NVIC_DT_CHA;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = ENCODER_NVIC_SW_CHA;
NVIC_Init(&NVIC_InitStructure);
person followed Monica to Codidact    schedule 17.07.2017
comment
Благодарю вас! Это действительно помогло мне понять. Извините за такой вопрос новичка. Первый раз работаю с платформой STM. - person Florian Uhlemann; 17.07.2017