Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 24.02.2017, 15:08  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Обработчик внешних прерываний

stm32f10xx. Дано, 4 пина, на которые повесил EXTI. Прикол в том, что по условию, пины должны иметь возможность меняться. То есть в башке (h) файле, дефайнами задаются пины и порты. И поэтому например инициализация gpio выглядит так:

Код:
#define KEYB_COL1_PORT GPIOB
#define KEYB_COL2_PORT GPIOB
#define KEYB_COL3_PORT GPIOB
#define KEYB_COL4_PORT GPIOB

#define KEYB_COL_PIN1 11 
#define KEYB_COL_PIN2 12
#define KEYB_COL_PIN3 13
#define KEYB_COL_PIN4 14
Код:
#define GPIO_INI_PIN(PORT, PIN, MODE) (PIN › 7) ? \
		(PORT-›CRH = (PORT-›CRH & (~((uint32_t)0x0F ‹‹ (((PIN) & 0x07) ‹‹ 2)))) | (((uint32_t)(MODE) & 0x0F) ‹‹ (((PIN) & 0x07) ‹‹ 2))) : \
		(PORT-›CRL = (PORT-›CRL & (~((uint32_t)0x0F ‹‹ (((PIN) & 0x07) ‹‹ 2)))) | (((uint32_t)(MODE) & 0x0F) ‹‹ (((PIN) & 0x07) ‹‹ 2)))
Код:
GPIO_INI_PIN(KEYB_COL1_PORT, KEYB_COL_PIN1, GPIO_MODE_COLS); //Pin 11 Input mode with PushPull
GPIO_INI_PIN(KEYB_COL2_PORT, KEYB_COL_PIN2, GPIO_MODE_COLS); //Pin 12 Input mode with PushPull
GPIO_INI_PIN(KEYB_COL3_PORT, KEYB_COL_PIN3, GPIO_MODE_COLS); //Pin 13 Input mode with PushPull
GPIO_INI_PIN(KEYB_COL4_PORT, KEYB_COL_PIN4, GPIO_MODE_COLS); //Pin 14 Input mode with PushPull
KEYB_COL1_PORT-›BSRR = (1 ‹‹ KEYB_COL_PIN1); //PullUp 11, 12, 13
KEYB_COL2_PORT-›BSRR = (1 ‹‹ KEYB_COL_PIN2);
KEYB_COL3_PORT-›BSRR = (1 ‹‹ KEYB_COL_PIN3);
KEYB_COL4_PORT-›BSRR = (1 ‹‹ KEYB_COL_PIN4); //PullUp 14
И вот дошла очередь до обработчика прерываний. По идее я как бы знаю, вижу по коду, что я выбрал такие пины, что нэндлер будет таков :
Код:
void EXTI15_10_IRQHandler(void){

}
Но по условию, порты и пины могут быть любыми, тогда логично предположить, что можно написать все хэндлеры, с 0 по 4, потом объеденённый 9_5, ну и 15_10. Но а если другие хэндлеры используются совсем в другом месте программы...уже не катит...Так вот если ли способ, исходя из настройки пинов дефайнами прописать нужный хэндлер. То есть как бы вместо красного подставить нужное. Ну и конечно если пины будут 0, 4, 8, 15, то и сгенерить соответственно 4 обработчика.
Код:
void EXTI15_10_IRQHandler(void){
Реклама:
supercelt вне форума  
Непрочитано 24.02.2017, 19:56  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,503
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Хм... скажем так... На все случаи жизни универсального кода не напишешь. А как только захочется сменить серию МК с F1 на другую, то все ваши усилия полетят нафик - там другая структура GPIO. Да и клавиатура может быть другой. Не всегда же 4х4.
А создавая разувесистые макросы, теряется легкость чтения кода, текст непомерно разрастается, последующая адаптация его тоже усложняется.
Так же, нельзя дважды в разных местах текста написать один и тот же обработчик. При компиляции будет выдана ошибка.
Я тоже раньше пытался писать универсальные на все случаи жизни библиотеки. Потом понял - нафик надо. Универсальным может быть только общий, аппаратно независимый код, типа фукнции siprintf, она работает на любой архитектуре.
Применительно к клавиатуре - должно быть два уровня. Низший уровень - чисто аппаратнозависимый код, который работает с портами, прерываниями и прочей лабуденью. И тут быстрее руками поправить, чем писать замудренные макросы. Потому что сегодня вы используете внешние прерывания, а завтра вы встроите вызов клавиатуры по системному таймеру, и вам вообще не понадобятся эти навороты.

Кстати, интересно, вот чем думали конструкторы F1xx серии, выдумав такую неудобную структуру GPIO???
NewWriter вне форума  
Сказали "Спасибо" NewWriter
majorka65 (01.03.2017)
Непрочитано 24.02.2017, 20:09  
dgrishin
Почётный гражданин KAZUS.RU
 
Регистрация: 12.02.2013
Сообщений: 1,015
Сказал спасибо: 43
Сказали Спасибо 273 раз(а) в 214 сообщении(ях)
dgrishin на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Если я правильно понял вашу задачу, то можно создать некую универсальную функцию (универсальный обработчик всех EXTI прерываний).
И из всех EXTIXYZ_IRQHandler обработчиков вызывать эту универсальную функцию.
А в универсальном обработчике смотреть какие биты pending - и выполнять соотв. действия.

Последний раз редактировалось dgrishin; 24.02.2017 в 20:13.
dgrishin вне форума  
Непрочитано 24.02.2017, 21:41  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Один чел это реализовал
http://we.easyelectronics.ru/blog/STM32/3206.html
Но я не понимаю, как у него это работает...
supercelt вне форума  
Непрочитано 26.02.2017, 15:56  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Сообщение от NewWriter Посмотреть сообщение
Кстати, интересно, вот чем думали конструкторы F1xx серии, выдумав такую неудобную структуру GPIO???
Чем она неудобная?
supercelt вне форума  
Непрочитано 26.02.2017, 22:44  
bass1981
Гражданин KAZUS.RU
 
Регистрация: 01.09.2007
Сообщений: 898
Сказал спасибо: 278
Сказали Спасибо 57 раз(а) в 54 сообщении(ях)
bass1981 на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Да уже давно пора компиляторы с распознаванием речи делать... Говоришь ему хочу что бы у меня работало USB, а он тебе под любую линейку МК сразу код рабочий выдает... )))
Кому не удобно, есть много других линеек МК...
bass1981 вне форума  
Непрочитано 27.02.2017, 14:37  
NewWriter
Почётный гражданин KAZUS.RU
 
Аватар для NewWriter
 
Регистрация: 07.09.2014
Адрес: В Кремле!
Сообщений: 4,503
Сказал спасибо: 401
Сказали Спасибо 2,217 раз(а) в 1,315 сообщении(ях)
NewWriter на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Чем неудобная? Так вот как раз компоновкой регистров и неудобная. Я до сих пор в табличку подглядываю, как биты поставить.
Для сравнения посмотрите младший F0 или наоборот, более старшие.
NewWriter вне форума  
Непрочитано 27.02.2017, 20:46  
tanq
Гражданин KAZUS.RU
 
Регистрация: 12.10.2009
Сообщений: 576
Сказал спасибо: 30
Сказали Спасибо 138 раз(а) в 110 сообщении(ях)
tanq на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Сообщение от supercelt Посмотреть сообщение
Так вот если ли способ, исходя из настройки пинов дефайнами прописать нужный хэндлер.
Способ есть и достаточно очевидный:
#define EXTI_PIN_HANDLER EXTI15_10_IRQHandler
............
void EXTI_PIN_HANDLER(void){

Но если данный обработчик прерывания будет в программе еще где-то, то будет ошибка. В этом случае надо вынести обработку всех exti в одну общую функцию и там разбираться, что с ними делать.
tanq вне форума  
Непрочитано 08.01.2018, 08:06  
CERGEI1982
Почётный гражданин KAZUS.RU
 
Аватар для CERGEI1982
 
Регистрация: 03.01.2007
Адрес: Россия,Иркутская обл.
Сообщений: 2,579
Сказал спасибо: 351
Сказали Спасибо 315 раз(а) в 193 сообщении(ях)
CERGEI1982 на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Подскажите для чего Event mask и Pulse generator ? какое применение его при работе с внешними прерываниями 103 серии ?
Миниатюры:
Нажмите на изображение для увеличения
Название: 2018-01-08_11-52-59.png
Просмотров: 0
Размер:	52.0 Кб
ID:	123754   Нажмите на изображение для увеличения
Название: 2018-01-08_11-53-45.png
Просмотров: 0
Размер:	49.7 Кб
ID:	123755  
__________________
Глаза боятся,а руки делают.
CERGEI1982 вне форума  
Непрочитано 08.01.2018, 17:04  
-Alan-
Прописка
 
Аватар для -Alan-
 
Регистрация: 05.12.2008
Адрес: Россия, Омск
Сообщений: 145
Сказал спасибо: 39
Сказали Спасибо 29 раз(а) в 22 сообщении(ях)
-Alan- на пути к лучшему
По умолчанию Re: Обработчик внешних прерываний

Event / Событие - это почти прерывание.
Используется по большей части для перевода контроллера в режим энергосбережения, и выхода из него по событию без возникновения прерывания (инструкция WFE вместо WFI).

В чём разница.
Как мне удалось понять из референса - СОБЫТИЕ возникает всегда, если разрешено на уровне периферии. Событие - может вывести ядро контроллера из ожидания (WFE) и исполнение инструкций будет продолжено так, словно инструкция __WFE(); была пустой (asm("nop").
Прерывание - возникает независимо от входа в режим ожидания прерывания, но только если разрешено в NVIC и произошло СОБЫТИЕ, которое должно прервать работу программы и вызвать обработчик.

Простой пример:
Контроллер настраивает периферию на ожидание события с линии EXTI2. Допустим, по переднему фронту на пине PC2.
Контроллер разрешает работу периферии, но не разрешает прерывание от EXTI2
Контроллер вызывает инструкцию __WFE() и ядро засыпает.
Через какое-то время порт регистрирует передний фронт импульса на пине PC2 и ядро запускается, продолжая выполнение кода и, например, уходит в бесконечный цикл.
Новый фронт импульса на PC2 не вызовет новых изменений в работе ядра.

Теперь то же самое, но с прерыванием.
Контроллер настраивает EXTI2 и разрешает прерывание от него.
Контроллер вызывает инструкцию __WFI(); и уходит в сон.
Приходит передний фронт импульса на PC2. Возникает СОБЫТИЕ, которое переходит в прерывание и ядро просыпается и выполняет переход на обработчик прерывания. Затем - выходит из обработчика (предварительно очистив бит одидающего прерывания) и продолжает работу.
Приходит НОВЫЙ передний фронт импульса на PC2, и контроллер останавливает выполнение кода, записывает в стэк данные регистров, и снова вызывает обработчик прерывания.
Прерывание будет возникать по каждому переднему фронту (потому что в примере я выбрал передний фронт) импульса и только затем возвращаться к прерваной программе.

Надеюсь, описал ясно.

Грубое сравнение:
Событие: Прозвонил будильник. Можно просто на него забить (позвенит и выключится сам через минуту)
Прерывание: Будильник упал на лицо и игнорировать его сложно - нужно его выключить и поставить обратно на столик с которого он сверзился.
-Alan- вне форума  
Сказали "Спасибо" -Alan-
CERGEI1982 (09.01.2018)
 

Закладки
Опции темы

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ускорить компьютер 7Fantomas7 Ремонт оргтехники 111 08.08.2018 05:27
Вложенность прерываний в Cortex-M makser1 ARM 12 11.03.2014 04:59
Грабли с обработчиками прерываний в AVR _reckless Микроконтроллеры, АЦП, память и т.д 30 11.05.2010 00:36
Как очистить очередь прерываний в ATMega8535? greafuger Микроконтроллеры, АЦП, память и т.д 4 04.06.2008 23:03
Использование прерываний в ATMega8535 igor727 Микроконтроллеры, АЦП, память и т.д 2 28.04.2007 15:50


Часовой пояс GMT +4, время: 16:17.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot