STM32F030 GPIO прерывание

Попытка получить прерывание на A3, чтобы разбудить процессор из спящего режима на rx char, но это не стрельба.

Что определяет, какое прерывание будет активировать вывод GPIO? Я не могу найти его в справочном руководстве

static void EXTI0_1_IRQHandler_Config(void)
{
  GPIO_InitTypeDef   GPIO_InitStructure;

  /* Enable GPIOA clock */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  GPIO_InitStructure.Pin = GPIO_PIN_3;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Enable and set EXTI line 0 Interrupt to the lowest priority */
  HAL_NVIC_SetPriority(EXTI0_1_IRQn, 2, 0);
  HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);
}

1 ответ

Решение

Функции прерываний (кратко) описаны в главе 11 "Прерывания и события", раздел 11.1.3 "Векторы прерываний и исключений".

Итак, номер прерывания EXTI2_3_IRQnи вы должны определить EXTI2_3_IRQHandler() звонить HAL_GPIO_EXTI_IRQHandler(),

Некоторый фон

Есть несколько шагов, связанных с получением функции обратного вызова, вызываемой при возникновении запроса на прерывание.

Каждому запросу на прерывание присваивается номер прерывания, см. Запись позиции в таблице выше. Номер определяется оборудованием, символическое имя присваивается где-то в заголовках машины.

typedef enum {
   [...]
   EXTI0_1_IRQn                = 5,      /*!< EXTI Line 0 and 1 Interrupt */
   EXTI2_3_IRQn                = 6,      /*!< EXTI Line 2 and 3 Interrupt */
   [...]
} IRQn_Type;

В таблице векторов есть соответствующий указатель на функцию, который должен содержать адрес функции-обработчика. Эта векторная таблица заполняется в модуле запуска, который называется startup_stm32f030x8.s или что-то подобное, и файл конфигурации компоновщика гарантирует, что таблица заканчивается по правильному физическому адресу при программировании флэш-памяти.

g_pfnVectors:
  .word  _estack
  .word  Reset_Handler
  .word  NMI_Handler
  .word  HardFault_Handler
  .word  0
  .word  0
  .word  0
  .word  0
  .word  0
  .word  0
  .word  0
  .word  SVC_Handler
  .word  0
  .word  0
  .word  PendSV_Handler
  .word  SysTick_Handler
  .word  WWDG_IRQHandler                   /* Window WatchDog              */
  .word  0                                 /* Reserved                     */
  .word  RTC_IRQHandler                    /* RTC through the EXTI line    */
  .word  FLASH_IRQHandler                  /* FLASH                        */
  .word  RCC_IRQHandler                    /* RCC                          */
  .word  EXTI0_1_IRQHandler                /* EXTI Line 0 and 1            */
  .word  EXTI2_3_IRQHandler                /* EXTI Line 2 and 3            */
...

Записи в фиксированном порядке, так как оборудование заботится только о числовом адресе. Всякий раз, когда EXTI2 или же EXTI3 событие происходит, и IRQ6 включен, он переходит на адрес в 0x00000058, Таблица выше гарантирует, что адрес EXTI2_3_IRQHandler() входит в таблицу векторов в 0x00000058,

Копаясь дальше в модуле запуска, мы находим это

.weak      EXTI0_1_IRQHandler
.thumb_set EXTI0_1_IRQHandler,Default_Handler

.weak      EXTI2_3_IRQHandler
.thumb_set EXTI2_3_IRQHandler,Default_Handler

и это

Default_Handler:
Infinite_Loop:
  b Infinite_Loop

Это означает, что если нет определения для EXTI0_1_IRQHandler() или же EXTI2_3_IRQHandler()затем они вызывают бесконечный цикл, хороший для отладки, но не более того. Чтобы реально использовать его, вы должны переопределить этот символ в вашей программе. Если вы посмотрите на GPIO_EXTI Например, у него есть этот обработчик

void EXTI0_1_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(USER_BUTTON_PIN);
}

определяется в stm32f0xx_it.c звонить HAL_GPIO_EXTI_IRQHandler() когда EXTI0 прерывание происходит. Если вы хотите действовать на EXTI3то у вас должна быть похожая функция

void EXTI2_3_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(3);
}

звонить HAL_GPIO_EXTI_IRQHandler(),

Другие вопросы по тегам