Например TDA7294

Форум РадиоКот • Просмотр темы - Как определить какой вход сгенерировал прерывание?
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пт дек 19, 2025 13:15:14

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Ср июл 20, 2022 00:28:20 
Первый раз сказал Мяу!

Зарегистрирован: Сб мар 20, 2021 23:31:54
Сообщений: 35
Рейтинг сообщения: 0
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 
Друг Кота
Аватар пользователя

Карма: 26
Рейтинг сообщений: 819
Зарегистрирован: Сб янв 28, 2006 22:47:24
Сообщений: 5707
Рейтинг сообщения: 0
В обработчике прерываний смотреть какие флаги в регистрах поднялись? Не?

_________________
Астролябия-сама меряет, было бы что мерять!!!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Ср июл 20, 2022 10:00:22 
Собутыльник Кота
Аватар пользователя

Карма: -12
Рейтинг сообщений: -24
Зарегистрирован: Пт июл 12, 2019 22:52:01
Сообщений: 2516
Рейтинг сообщения: 0
Юрий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 по сути бывают нужны крайне редко (лично я уж забыл, пользовался ли ими когда-либо вообще!).

_________________
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Ср июл 20, 2022 22:04:24 
Первый раз сказал Мяу!

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


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Ср июл 20, 2022 22:10:35 
Собутыльник Кота
Аватар пользователя

Карма: -12
Рейтинг сообщений: -24
Зарегистрирован: Пт июл 12, 2019 22:52:01
Сообщений: 2516
Рейтинг сообщения: 0
Юрий48, ну написано же все в RM!

_________________
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Ср июл 20, 2022 22:22:30 
Первый раз сказал Мяу!

Зарегистрирован: Сб мар 20, 2021 23:31:54
Сообщений: 35
Рейтинг сообщения: 0
Eddy_Em, о каких RM идёт речь?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Чт июл 21, 2022 10:49:04 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 212
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1525
Рейтинг сообщения: 0
Reference manual на ваш контроллер, очевидно


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Чт июл 21, 2022 12:08:42 
Говорящий с текстолитом

Карма: -7
Рейтинг сообщений: 187
Зарегистрирован: Вт авг 15, 2017 10:51:13
Сообщений: 1655
Рейтинг сообщения: 0
Пользующиеся кубами как правило не знают что такое "Reference manual" и где его брать. :))


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Чт июл 21, 2022 13:24:26 
Вымогатель припоя
Аватар пользователя

Карма: 10
Рейтинг сообщений: 171
Зарегистрирован: Ср июн 29, 2022 16:25:45
Сообщений: 524
Рейтинг сообщения: 0
Юрий48, из какой то сетевой шпаргалки (кажется, для F103), но EXTI вроде везде +/- одинаков....
Спойлер
Код:
/*******************
 * EXTI
 *******************/
/*
   AFIO->EXTICR[0..3]
   ----------
      В контроллере EXTI есть 19 линий внешних прерываний.
      Первые 16 мультиплексируются на биты физических портов МК, два оставшихся - на прерывания от
         PVD (программируемый датчик напряжения питания), RTC Alarm event и USB Wakeup event.
      На линию EXTI0  мультиплексируется бит  0 портов A,B,C,D,E,F,G
      На линию EXTI1  мультиплексируется бит  1 портов A,B,C,D,E,F,G
      .......
      На линию EXTI15 мультиплексируется бит 15 портов A,B,C,D,E,F,G
      За мультиплексирование отвечают регистры EXTICR1, EXTICR2, EXTICR3, EXTICR4 домена AFIO.
      В CMSIS они сгруппированы в массив EXTICR[0..3], но битовые константы оперируют литералами EXTICR1..EXTICR4
      AFIO->EXTICR[0..3]
      Регистор EXTICR[0] отвечает за биты  0,  1,  2,  3
      Регистор EXTICR[1] отвечает за биты  4,  5,  6,  7
      Регистор EXTICR[2] отвечает за биты  8,  9, 10, 11
      Регистор EXTICR[3] отвечает за биты 12, 13, 14, 15
      Соответствено, что бы  настроить мультиплексирование соответствующего бита порта в контроллер EXTI, необходимо
      включить тактирование альтернативных функций AFIOEN:     RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
         EXTIx[3:0]: EXTI x configuration,
         где   x=0..3 для регистра AFIO_EXTICR1;
            x=4..7 для регистра AFIO_EXTICR2;
            x=8..11 для регистра AFIO_EXTICR3;
            x=12..15 для регистра AFIO_EXTICR4.
         Биты (битовые поля) модифицируются программно и используются для выбора источника сигнала для линии
         внешнего прерывания EXTIx, x=0..15. В зависимости от значения битового поля, используется вход одного
         из портов ввода/вывода микроконтроллера (GPIO):
         0000: PA[x] вывод микроконтроллера;
         0001: PB[x] вывод микроконтроллера;
         0010: PC[x] вывод микроконтроллера;
         0011: PD[x] вывод микроконтроллера;
         0100: PE[x] вывод микроконтроллера;
         0101: PF[x] вывод микроконтроллера;
         0110: PG[x] вывод микроконтроллера.

      В CMSIS уже есть готовые константы для битовых полей:
      AFIO_EXTICRx_EXTInn - маска битов для прерывания nn в регистре EXTICRx
      AFIO_EXTICRx_EXTInn_PA - v
      AFIO_EXTICRx_EXTInn_PB - v
      AFIO_EXTICRx_EXTInn_PC - v
      AFIO_EXTICRx_EXTInn_PD - v
      AFIO_EXTICRx_EXTInn_PE - v
      AFIO_EXTICRx_EXTInn_PF - v
      AFIO_EXTICRx_EXTInn_PG - готовые битовые маски для портов A..G
         (помним nn=0..3->x=1, nn=4..7->x=2, nn=8..11->x=3,nn=12..15->x=4)

   Регистры контроллера внешних прерываний EXTI

   EXTI->IMR       Interrupt mask register - Регистр маски прерываний
   ---------
   MR18   MR17   MR16
   MR15   MR14   MR13   MR12   MR11   MR10   MR9      MR8
   MR7      MR6      MR5      MR4      MR3      MR2      MR1      MR0
   ----------
   Разрешение или запрет контроллеру EXTI генерацию прерываний (для каждой линии имеется отдельный бит разрешения).
      MRx: Interrupt Mask on line x, x=0..17 - Бит, разрешающей генерацию прерываний от соответствующей линии EXTI:
         0: не формируются запросы на прерывание от соответствующей линии EXTIx;
         1: разрешается формировать запросы на прерывание от соответствующей линии EXTIx.

   EXTI->EMR       Event mask register - Регистр маски событий пробуждения
   ---------
   MR18 ..... MR0
   ----------
      Разрешение или запрет контроллеру EXTI генерацию событий (для каждой линии имеется отдельный бит разрешения).
      MRx: Event mask on line x, x=0..18 - Бит, разрешающей генерацию событий от соответствующей линии EXTI:
         0: не формируются сигналы события от соответствующей линии EXTIx;
         1: разрешается формировать сигналы события от соответствующей линии EXTIx

   EXTI->RTSR      Rising trigger selection register  - Регистр выбора линий EXTI, запускаемых нарастающим входным сигналом.
   EXTI->FTSR       Falling trigger selection register - Регистр выбора линий EXTI, запускаемых спадающим входным сигналом.
   ----------
   TR18 ..... TR0
   ----------
      TRx: Rising trigger event configuration bit of line x=0..18 - Бит определяет, что на входной линии x
         контроллера EXTI требуется обнаруживать нарастающий фронт сигнала:
         0: отключён запуск нарастающим фронтом (как для прерываний, так и для событий) для данной линии;
         1: включён запуск нарастающим фронтом (как для прерываний, так и для событий) для данной линии.
      TRx: Falling trigger event configuration bit of line x, x=0..18 - Бит определяет, что на входной линии x
         контроллера EXTI требуется обнаруживать спадающий фронт сигнала:
         0: отключён запуск спадающим фронтом (как для прерываний, так и для событий) для данной линии;
         1: включён запуск спадающим фронтом (как для прерываний, так и для событий) для данной линии.

   EXTI->SWIER      Software interrupt event register - Регистр для программной генерации прерываний и событий EXTI.
   ----------
   SWIER18   ..... SWIER0
   ----------
      SWIERx: Software interrupt on line x, x=0..17
         Запись 1 в этот бит, когда он содержит 0, приводит к установке соответствующего отложенного
         бита в регистре EXTI_PR (если разрешено регистром маски EXTI_IMR). Если прерывания для
         данной линии разрешены, генерируется запрос на прерывание.
         Бит сбрасывается при сбросе соответствующего бита в регистре EXTI_PR, который, в свою
         очередь, сбрасывается записью 1 в этот бит.

   EXTI->PR      Pending register - Регистр отложенных прерываний
   --------
   PR18 ..... PR0
   ----------
      PRx: Pending bit - Бит отложенного прерывания:
         0: не генерировалось запросов на прерывание;
         1: произошла генерация запроса на прерывание.
         Этот бит устанавливается при обнаружении отслеживаемого фронта входного сигнала на внешней линии.
         Бит сбрасывается путём записи 1 в этот бит.

   Вектора прерываний (описаны в startup_stm32f103xb.s):
   EXTI0_IRQHandler      Прерывание от линии 0 EXTI
   EXTI1_IRQHandler      Прерывание от линии 1 EXTI
   EXTI2_IRQHandler      Прерывание от линии 2 EXTI
   EXTI3_IRQHandler      Прерывание от линии 3 EXTI
   EXTI4_IRQHandler      Прерывание от линии 4 EXTI
   EXTI9_5_IRQHandler      Прерывание от линий [9:5] EXTI
   EXTI15_10_IRQHandler   Прерывание от линий [15:10] EXTI
      Внутри обработчика прерывания необходимо проверить, какая линия была виновником вызова прерывания.
      Это делается проверкой битов в регистре EXTI_PR.
      Так же необходимо сбросить бит прерывания, записав в этот бит 1.

   Кроме разрешения прерывания в регистрах контроллера EXTI еше необходимо разрешить соответствующие прерывания
   в контроллере NVIC: NVIC_EnableIRQ(nnn);
   Тут nnn - имя вектора прерываний (определены в stm32f103xb.h)
      PVD_IRQn              - PVD through EXTI Line detection Interrupt
      EXTI0_IRQn            - EXTI Line0 Interrupt
      EXTI1_IRQn            - EXTI Line1 Interrupt
      EXTI2_IRQn            - EXTI Line2 Interrupt
      EXTI3_IRQn            - EXTI Line3 Interrupt
      EXTI4_IRQn            - EXTI Line4 Interrupt
      EXTI9_5_IRQn          - External Line[9:5] Interrupts
      EXTI15_10_IRQn        - External Line[15:10] Interrupts
*/

// обработчик прерывания
void EXTI15_10_IRQHandler(void) {
   if (EXTI->PR & EXTI_PR_PIF12) {
      EXTI->PR |= EXTI_PR_PIF12;
   // нужное нам действие
   }
}

// настройка прерывания
   //GPIO_B12 - key
   RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;
   GPIOB->CRH &= ~(GPIO_CRH_MODE12_Msk | GPIO_CRH_CNF_Msk); // input
   GPIOB->CRH |= GPIO_CRH_CNF12_1;   // with pull resistor
   GPIOB->ODR |= GPIO_ODR_ODR12;   // pull to UP
   // EXTI
   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
   AFIO->EXTICR[3] &= ~AFIO_EXTICR4_EXTI12;      // мапим EXTI12
   AFIO->EXTICR[3] |=  AFIO_EXTICR4_EXTI12_PB;      // на порт B (GPIO_B_12)
   EXTI->IMR |= EXTI_IMR_IM12;      // прерывание от IO_B12
   EXTI->RTSR |= EXTI_RTSR_RT12;   // по нарастающему фронту (Rising)
   EXTI->FTSR |= EXTI_FTSR_FT12;   // по спадающему фронту (Falling)
   NVIC_EnableIRQ(EXTI15_10_IRQn);

_________________
Белая и Пушистая


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Вс июл 24, 2022 12:05:22 
Родился
Аватар пользователя

Зарегистрирован: Вс июл 24, 2022 11:42:22
Сообщений: 7
Рейтинг сообщения: 1
Отвечу на первоначальный вопрос, если конечно еще актуально.

В ваш код необходимо вставить функцию, которую будет вызывать 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 
Грызет канифоль

Карма: 3
Рейтинг сообщений: 10
Зарегистрирован: Пт мар 20, 2009 12:25:47
Сообщений: 289
Откуда: Ivanovo
Рейтинг сообщения: 0
Пользующиеся кубами как правило не знают что такое "Reference manual" и где его брать. :))

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


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Как определить какой вход сгенерировал прерывание?
СообщениеДобавлено: Ср сен 07, 2022 10:23:52 
Друг Кота
Аватар пользователя

Карма: 5
Рейтинг сообщений: 61
Зарегистрирован: Ср сен 30, 2020 16:51:47
Сообщений: 4625
Откуда: РФ
Рейтинг сообщения: 0
Пользующиеся кубами как правило не знают что такое "Reference manual"

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


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 12 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y