STM32 GPIO Прерывание с использованием регистра IDR - PullRequest
1 голос
/ 20 февраля 2020
    /* Configure EXTI interupt PB4 */
    SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR2_EXTI4_PB; 
    EXTI->IMR |= EXTI_IMR_IM4;                                                                          //Interrupt Mask on line 2  */
    EXTI->RTSR |= EXTI_RTSR_RT4;                                                                        
    EXTI->FTSR |= EXTI_FTSR_FT4;                                                                        
    NVIC_EnableIRQ(EXTI4_15_IRQn);                                                                          //Załączenie przerwania na pinie zasilania
    NVIC_SetPriority(EXTI4_15_IRQn,1); 

Так я настраиваю EXTI

    GPIOB->MODER =      (0U << GPIO_MODER_MODE4_Pos);
    GPIOB->PUPDR =      (1U << GPIO_PUPDR_PUPD4_Pos);

Так я управляю пин

    while(1)
    {
        if(state == 0){
            ServoToggle(0, 100, 255);
            delay(1000);
        } else {
            ServoToggle(0, 115, 255);
            delay(1000);
            ServoToggle(0, 60, 255);
            delay(1000);
        }
        delay(1);
    }

Это то, что делает моя программа после простоя

void EXTI4_15_IRQHandler(void)
{
    if(!(GPIOB->IDR & GPIO_IDR_ID4)){
        state = 0;
    } else {
        state = 1;
    } 
    EXTI->PR = EXTI_PR_PR4;
}

Вот как я пытаюсь обработать прерывание.

И эта вещь не работает. Ибо почему, но для PA0 это работает как брелок, но переход на PB4 прекращает всплывающее событие прерывания.

У меня есть кнопка, подключенная к выводу, который изменил регистр IDR на , нажмите .

Чего мне не хватает?

Я использую семейство STM32L052

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020

Для PA0, я полагаю, это необходимо для этой строки:

SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR2_EXTI4_PB;

Согласно справочному руководству, PB[x] (где x равно 4) отображается в бит 0-3 SYSCFG_EXTICR2. Так что в вашем случае это должно быть:

SYSCFG->EXTICR[2] &= ~SYSCFG_EXTICR2_EXTI4;
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR2_EXTI4_PB;

PA0 сопоставлен с SYSCFG-> EXTICR [0]. SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR2_EXTI4_PB; означает, что AND содержимое SYSCFG->EXTICR[0] с обратным SYSCFG_EXTICR2_EXTI4_PB, что равно 0xFE. Если предположить, что SYSCFG->EXTICR[0] был всеми нулями, то вы, по сути, просто AND куча нулей вместе, поэтому PA0 работает.

Еще одна вещь, которую я заметил, это то, что в вашем обработчике прерываний я бы проверял флаги внешнего обработчика прерываний, а не регистр IDR GPIO, чтобы проверить, была ли нажата кнопка. Из моего понимания вопроса, вы хотите нажать sh кнопку для переключения переменной state. Нажатие на кнопку запускает прерывание, поэтому вы как бы побеждаете цель, проверяя регистр IDR в любом случае. В обработчике прерываний EXTI вы проверяете, что это правильное прерывание через ожидающий регистр / PR. Другие прерывания EXTI выглядят так, как будто они используют один и тот же обработчик, поэтому вы можете использовать регистр EXTR->PR для проверки правильного ожидающего бита.

Вот пример кода STM32F407, который у меня есть в качестве примера:

#define PORTD_ALL 0x0000F000
void EXTI0_IRQHandler(void){

  // Check for EXTI 0 flag
  if((EXTI->PR & EXTI_PR_PR0) == EXTI_PR_PR0){

    // Toggle all LED on board
    GPIOD->ODR ^= PORTD_ALL;

    // Clear interupt pending request
    EXTI->PR = EXTI_PR_PR0;
  }
}

Каждый раз, когда я нажимаю кнопку, он переключает светодиод на плате

Для state Переменное использование операции XOR. Это довольно полезно.

Чтобы ответить на этот вопрос, я использовал справочное руководство STM32L052 и файл STM32L052.h с веб-сайта ST. Просто найдите STM32CubeL0 скачать

0 голосов
/ 20 февраля 2020

EXTI IRQ с 4-15 довольно редко. Может быть, вы могли бы добавить используемый контроллер exakt?

Например, на STM32F415 это будет EXTI4_IRQHandler для обработчика IRQ.

...