Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Как определить какой вход сгенерировал прерывание?

Ср июл 20, 2022 00:28:20

STM32CubeMX создал такой код:
Код:
void EXTI15_10_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI15_10_IRQn 0 */
 
  /* USER CODE END EXTI15_10_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
  /* USER CODE BEGIN EXTI15_10_IRQn 1 */

  /* USER CODE END EXTI15_10_IRQn 1 */
}

Как определить какой из входов сгенерировал прерывание?

Re: Как определить какой вход сгенерировал прерывание?

Ср июл 20, 2022 03:59:13

В обработчике прерываний смотреть какие флаги в регистрах поднялись? Не?

Re: Как определить какой вход сгенерировал прерывание?

Ср июл 20, 2022 10:00:22

Юрий48, а вот не нужно калом пользоваться. Достаточно документацию почитать. Если у вас F103, то есть регистры EXTI_EMR и EXTI_IMR, дающие возможность маскировать прерывания и события. Есть регистры EXTI_RTSR и EXTI_FTRS, позволяющие задать, на какой фронт реагировать: восходящий или нисходящий. А в EXTI_PR будут установлены в 1 те биты, которые события сработали.
Кроме того, прерывания на каждый бит этих регистров мультиплексируются от разных групп ног (скажем, PA0, PB0 и т.п. управляются младшим битом). Чтобы узнать, от какого порта GPIO сработало прерывание, можно воспользоваться регистром AFIO_EXTICRx (тоже, между прочим, в документации все есть).
За биты 10..15 отвечают регистры с x=3 и 4. Регистр GPIO обозначается группой из четырех бит. Т.е. если сработало EXTI_15_10, смотрим, что там у нас в EXTI_PR: ага, установлен бит 12 → прерывание сработало от 12-го пина какого-то регистра GPIO. Смотрим, что там в младшем квартете AFIO_EXTICR4, ага, там 0x2 → сработало прерывание от PC12. Вуаля!

Ну, точней несколько наоборот: чтобы задать, что вы в обработчике прерывания ждете события от PC12, вы должны в младший октет AFIO_EXTICR4 занести двойку. К сожалению, нет возможности настроить прерывания, скажем, сразу на PA12, PB12, PC12… Надо выбрать что-то одно. Правда, у STM32 достаточно богатая периферия, так что EXTI по сути бывают нужны крайне редко (лично я уж забыл, пользовался ли ими когда-либо вообще!).

Re: Как определить какой вход сгенерировал прерывание?

Ср июл 20, 2022 22:04:24

Eddy_Em, спасибо за разъяснения. В отладчике кейла пробую посмотреть, что делается в EXTI_PR при нажатии кнопок и ничего не увидел там меняющегося, хотя в регистре GPIOB_IDR реакция на нажатие кнопок адекватная. Решил поиграться с этим регистром в программе. Но не могу к нему обратиться, просто не знаю, как правильно сделать запись (не смешно). Сразу хочу спросить: а можно ли где посмотреть этот синтаксис, какая логика составление этих записей. Вообще то надо определять время нажатия кнопок, поэтому прерывание настроено на срабатывание по обоим фронтам. То есть надо не только определить какая кнопка сработала, но и что было - нажатие или отпускание - фронт. Понятно, что надо опрашивать регистр в цикле. Учитывая мой уровень знаний, лучшим вариантом было бы привести конкретный код, например, определения срабатывания конкретной кнопки.

Re: Как определить какой вход сгенерировал прерывание?

Ср июл 20, 2022 22:10:35

Юрий48, ну написано же все в RM!

Re: Как определить какой вход сгенерировал прерывание?

Ср июл 20, 2022 22:22:30

Eddy_Em, о каких RM идёт речь?

Re: Как определить какой вход сгенерировал прерывание?

Чт июл 21, 2022 10:49:04

Reference manual на ваш контроллер, очевидно

Re: Как определить какой вход сгенерировал прерывание?

Чт июл 21, 2022 12:08:42

Пользующиеся кубами как правило не знают что такое "Reference manual" и где его брать. :))

Re: Как определить какой вход сгенерировал прерывание?

Чт июл 21, 2022 13:24:26

Юрий48, из какой то сетевой шпаргалки (кажется, для F103), но EXTI вроде везде +/- одинаков....

Re: Как определить какой вход сгенерировал прерывание?

Вс июл 24, 2022 12:05:22

Отвечу на первоначальный вопрос, если конечно еще актуально.

В ваш код необходимо вставить функцию, которую будет вызывать HAL при срабатывании прерывании по GPIO:
Код:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  if (GPIO_Pin == GPIO_PIN_13) {
     // Сработало прерывание на 13 пине.
     // Aналогичные проверки можно сделать и для остальных пинов.
  }
}

где, GPIO_Pin - пин на котором сработало прерывание.

Re: Как определить какой вход сгенерировал прерывание?

Ср сен 07, 2022 10:12:09

Пользующиеся кубами как правило не знают что такое "Reference manual" и где его брать. :))

Я пользуюсь STM32CubeIDE и прекрасно знаю что такое RM.
И не пользуюсь всякими халами и прочим, только CMSIS.
Дело не в Кубе, а в ардуриноподходе.

Re: Как определить какой вход сгенерировал прерывание?

Ср сен 07, 2022 10:23:52

Пользующиеся кубами как правило не знают что такое "Reference manual"

А при чём здесь собственно "куб"? IDE появились только в этом веке. В прошлом веке для МК вообще всё на ассемблерах писалось. Но RM тогда существовали. Просто их кто-то изучал, а кто-то нет, а кто-то и вовсе не знал о их существовании.
Ответить