pcint arduino что это

Аппаратные прерывания

pcint arduino что это. Смотреть фото pcint arduino что это. Смотреть картинку pcint arduino что это. Картинка про pcint arduino что это. Фото pcint arduino что этоЗабавную картинку к этому уроку я найти не смог, нашёл только какую-то лекцию по программированию, и вот самое начало этой лекции отлично объясняет нам, что такое прерывание. Прерывание в Ардуино можно описать абсолютно точно так же: микроконтроллер “всё бросает”, переключается на выполнение блока функций в обработчике прерывания, выполняет их, а затем возвращается ровно к тому месту основного кода, в котором остановился.

Прерывания бывают разные, то есть не сами прерывания, а их причины: прерывание может вызвать аналогово-цифровой преобразователь, таймер-счётчик или буквально пин микроконтроллера. Такие прерывания называются внешними аппаратными, и именно о них мы сегодня поговорим. External hardware interrupt – это прерывание, вызванное изменением напряжения на пине микроконтроллера. Основная суть состоит в том, что микроконтроллер (системное ядро) не занимается опросом пина и не тратит на это время. Как только напряжение на пине изменяется (имеется в виду цифровой сигнал, +5 подали/+5 убрали) – микроконтроллер получает сигнал, бросает все дела, обрабатывает прерывание, и возвращается к работе. Зачем это нужно? Чаще всего прерывания используются для детектирования коротких событий – импульсов, или даже для подсчёта их количества, не нагружая основной код. Аппаратное прерывание может поймать короткое нажатие кнопки или срабатывание датчика во время сложных долгих вычислений или задержек в коде, т.е. грубо говоря – пин опрашивается параллельно основному коду. Также прерывания могут будить микроконтроллер из режимов энергосбережения, когда вообще практически вся периферия отключена. Посмотрим, как работать с аппаратными прерываниями в среде Arduino IDE.

Прерывания в Arduino

В этом уроке речь пойдёт об обычных прерываниях, которые называются INT, потому что стандартный фреймворк Ардуино умеет работать только с ними. Таких прерываний и соответствующих им пинов очень мало (таблица ниже), но у самого микроконтроллера есть возможность получать прерывания с любого пина, такие прерывания называются PCINT и работать с ними можно только при помощи сторонних библиотек (вот отличная), либо вручную (читай у меня вот тут). В этом уроке мы рассмотрим базовые возможности и INT прерывания:

МК / номер прерыванияINT 0INT 1INT 2INT 3INT 4INT 5
ATmega 328/168 (Nano, UNO, Mini)D2D3
ATmega 32U4 (Leonardo, Micro)D3D2D0D1D7
ATmega 2560 (Mega)D2D3D21D20D19D18

Ловим событие

Если прерывание отлавливает какое-то событие, которое необязательно обрабатывать сразу, то лучше использовать следующий алгоритм работы с прерыванием:

Следующий возможный сценарий: нам надо поймать сигнал с “датчика” и сразу на него отреагировать однократно до появления следующего сигнала. Если датчик – кнопка, нас поджидает дребезг контактов. С дребезгом лучше бороться аппаратно, но можно решить проблему программно: запомнить время нажатия и игнорировать последующие срабатывания. Рассмотрим пример, в котором прерывание будет настроено на изменение ( CHANGE ).

Вы скажете: но ведь millis() Не меняет значение в прерывании! Да, не меняет, но он меняется между прерываниями! Это в принципе всё, что нужно знать о прерываниях, более конкретные случаи мы разберём в продвинутых уроках.

Видео

Источник

Pcint arduino что это

pcint arduino что это. Смотреть фото pcint arduino что это. Смотреть картинку pcint arduino что это. Картинка про pcint arduino что это. Фото pcint arduino что это

Я уже касался темы прерываний в статье Многозадачность и прерывания на Arduino. Сегодня я постараюсь раскрыть тему прерываний более подробно.

Большинство микроконтроллеров имеют прерывания. Прерывания позволяют реагировать на «внешние» события пока выполняется еще что-то. Например, если вы готовите ужин, то вы можете положить картофель вариться на 20 минут. Вместо того, чтобы смотреть на часы непрерывно в течение 20 минут, вы можете установить таймер, а затем пойти посмотреть телевизор. Когда таймер подаст звуковой сигнал, вы «прерываете» просмотр вашего телевизора, для того, чтобы сделать что-то с картофелем.

Что такое прерывание, ISR и вектор прерывания?

Что не является прерыванием?

Прерывания — это не просто когда вы передумываете и делаете что-то другое. Например:

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

Пример прерывания

Этот пример показывает, что, несмотря на то, что в основном цикле loop не выполняется никаких действий, вы можете включать и выключать светодиод на 13 пине, нажимая кнопку, подключенную к D2.

Чтобы проверить это, просто нажмите кнопку, подключенную между 2 выводом и землей. Внутренний подтягивающий резистор (подключается в функции setup) в нормальном состоянии (когда нет внешнего сигнала) поддерживает этот вывод в состоянии HIGH. Когда вы замыкаете его на замлю, он переходит в состояние LOW. Изменение состояния пина определяется при помощи прерывания CHANGE, которое является причиной вызова функции обработки прерывания.

В более сложном примере, основной цикл loop может делать что-то делать полезное, например, снимать показания температуры и позволять обработчику прерывания обнаруживать нажатие кнопки.

Доступные прерывания

Ниже приведен список прерываний для микроконтроллера ATmega328 в порядке их приоритетности

Пр.ПрерываниеОбработчик
1СбросRESET_vect
2Внешнее прерывание 0 (вывод D2)INT0_vect
3Внешнее прерывание 1 (вывод D3)INT1_vect
4Изменение состояния вывода 1 (выводы с D8 по D13)PCINT0_vect
5Изменение состояния вывода 2 (выводы с A0 по A5)PCINT1_vect
6Изменение состояния вывода 3 (выводы с D0 по D7)PCINT2_vect
7Переполнение сторожевого таймераWDT_vect
8Прерывание по сравнению, канал A таймера/счетчика 2TIMER2_COMPA_vect
9Прерывание по сравнению, канал B таймера/счетчика 2TIMER2_COMPB_vect
10Переполнение таймера/счетчика 2TIMER2_OVF_vect
11Прерывание таймера/счетчика 1 по захвату событияTIMER1_CAPT_vect
12Прерывание по сравнению, канал A таймера/счетчика 1TIMER1_COMPA_vect
13Прерывание по сравнению, канал A таймера/счетчика 1TIMER1_COMPB_vect
14Переполнение таймера/счетчика 2TIMER1_OVF_vect
15Прерывание по сравнению, канал A таймера/счетчика 0TIMER0_COMPA_vect
16Прерывание по сравнению, канал B таймера/счетчика 0TIMER0_COMPB_vect
17Переполнение таймера/счетчика 0TIMER0_OVF_vect
18Завершение передачи по SPISPI_STC_vect
19Завершение приема по каналу USARTUSART_RX_vect
20Регистр данных USART пустUSART_UDRE_vect
21Завершение передачи по каналу USARTUSART_TX_vect
22Преобразование АЦП завершеноADC_vect
23EEPROM готоваEE_READY_vect
24Аналоговый компаратор переключилсяANALOG_COMP_vect
25Событие двухпроводного интерфейса (I 2 C)TWI_vect
26Готовность флеш-памятиSPM_READY_vect

Встроенные названия обработчика, которые вы можете использовать для обратных вызовов ISR указаны в третьем столбце под названием Обработчик.

Основные причины по которым вы можете использовать прерывания:

Различные варианты для передачи данных используются, чтобы позволить программу делать что-то еще пока данные будут отправляться или получаться через Serial- порт, SPI или I 2 C.

Вывод процессора из спящего режима

Внешние прерывания, прерывания по изменению состояния пинов и прерывание сторожевого таймера также могут быть использованы для пробуждения процессора. Это может быть очень удобно, так как в спящем режиме процессор может быть настроен на меньшее энергопотребление (около 10 мкА). Прерывания по фронту, спаду или низкому уровню сигнала могут использоваться, чтобы разбудить гаджет. Например, если вы нажмете кнопку на нем, или же можно будить его периодически, используя прерывание сторожевого таймера, чтобы, к примеру, проверить время или температуру.

Прерывания по изменению состояния пинов могут использоваться для пробуждения процессора при нажатии кнопки на клавиатуре или чем-то похожим.

Процессор также может быть выведен из спящего режима прерыванием таймера при достижении определенного значения или переполнения и некоторыми другими событиями, такими как входящее сообщение I 2 C.

Разрешение и запрещение прерываний

Прерывание RESET не может быть запрещено, но другие прерывания могут временно запрещаться сбросом флага прерывания.

Вы можете разрешить прерывания, испольуя функции interrupts или sei:

Если вам нужно запретить прерывания, можно воспользоваться функцией noInterrupts или сбросить флаг прерывания:

И тот и другой метод дают один и тот же результат. Использование функций interrupts и noInterrupts немного проще запомнить.

По умолчанию, прерывания в Arduino разрешены. Не запрещайте их надолго, иначе такие вещи как таймеры, например, не будут работать корректно.

Зачем запрещать прерывания?

Могут быть критичные ко времени участки кода, выполнение которых вам не хотелось бы прерывать, например, прерыванием таймера.

Кроме того, если многобайтовые поля обновляются с помощью обработчика прерывания, то вам, возможно, потребуется отключить прерывания, так чтобы вы могли получить данные «неделимыми». В противном случае один байт может быть обновлен обработчиком, пока вы читаете другой.

Временное отключение прерываний гарантирует, что isrCounter (счетчик внутри обработчика прерывания) не изменится, пока мы получаем его значение.

Если вы не уверены в том, что прерывания уже включены или нет, вам нужно сохранить текущее состояние и восстановить его впоследствии.

Например, это то, что делает код внутри функции millis:

Обратите внимание на строки 4 и 10, где сохраняется текущий статусный регистр SREG, который включает флаг прерывания. После того, как мы получаем значение таймера (длиной 4 байта) мы возвращаем статусный регистр таким же каким он и был.

Что такое приоритет прерывания?

Поскольку существует 25 прерываний (за исключением RESET), возможно что произойдет одновременно больше, чем одно прерывание или же прерывание произойдет раньше, сем будет обработано другое. Также событие прерывания может произойти в момент, когда прерывания запрещены.

Приоритетный порядок является последовательностью, в которой процессор следит за событиями прерываний. Более высокая позиция в списке означает более высокий приоритет. Так, например, внешнее прерывание 0 (пин D2) будет обработано перед внешним прерыванием 1 (пин D3).

Может прерывание произойти пока прерывания запрещены?

События прерываний (именно события) могут произойти в любое время и большинство из них запоминается, установкой флага interrupt event внутри процессора. Если прерывания запрещены, то это прерывание может быть обработано, когда вновь станет разрешено в порядке приоритетности.

Что такое переменные volatile?

Переменные, к которым имеют доступ функции обработки прерываний и обычные функции должны быть объявлены как volatile. Такое объявление сообщит компилятору, что эти переменные могут измениться в любой момент и поэтому компилятор должен перезагрузить переменную каждый раз, когда вы ссылаетесь на нее, а не полагаться на копию, которая может храниться в регистре процессора.

Как использовать прерывания

Написание функции обработки прерывания

Процедуры обработки прерываний являются функциями без аргументов. В некоторых библиотеках Arduino используется вызов своих собственных функций, так что вы просто подставляете обычную функцию (как в приведенных выше примерах).

Однако, если в библиотеке нет своего «крючка» к функции обработки прерывания, то вы можете сделать свой собственный:

В этом случае, вы используете предопределенную функцию ISR и подставляете имя соответствующего вектора прерывания. В этом примере, процедура обработки прерывания обрабатывает завершение передачи по SPI (ранее, вместо ISR использовалась функция SIGNAL, но теперь она упразднена).

Соединение обработчика с прерыванием

Для прерываний, уже обрабатываемых библиотеками, вы просто используете документированный интерфейс. Например:

В этом случае, библиотека I 2 C разработана таким образом, чтобы обрабатывать входящие байты по I 2 C внутри себя, и затем вызывать предназначенную для пользователя функцию в конце входящего потока данных. В этом случае, receiveEvent не является чистой процедурой обработки прерывания (она имеет аргумент), но она называется встроенной ISR.

Другой пример представляет внешнее прерывание на пине:

В этом случае, функция attachInterrupt добавляет функцию pinChange во внутреннюю таблицу и, кроме того, конфигурирует соответствующие флаги прерываний в процессоре.

Конфигурирование процессора для обработки прерывания

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

В качестве примера, для внешнего прерывания 0 (пин D2), можно сделать что-то типа такого:

3 ; // сбрасываем существующие флаги

В более читабельном варианте используются предопределенные имена:

( bit ( ISC00 ) | bit ( ISC01 ) ) ; // сбрасываем существующие флаги

EICRA (External Interrupt Control Register A) должен быть установлен в соответствии с таблицей из технического руководства ATmega328 (см. на стр.71). Это значение определяет точный тип желаемого прерывания:

EIMSK (External Interrupt Mask Register), на самом деле, разрешает прерывание.

К счастью, нет необходимости запоминать эти цифры, потому что attachInterrupt сделает это за вас. Однако это то, что происходит на самом деле, и для других прерываний вам, возможно, придется «вручную» установить флаги.

Может ли обработчик прерывания быть прерван?

Если коротко — то нет, если вы хотите, чтобы прерывания были.

Когда производится вход в обработчик прерывания, то прерывания запрещаются. Естественно, что они должны были быть включены в первую очередь, в противном случае в обработчик прерывания не попасть. Однако, чтобы избежать то, что сама процеда обработуи прерывания прерывается, процессор запрещает прерывания.

При выходе из обработчика, прерывания вновь разрешаются. Компилятор также генерирует код внутри обработчика прерываний для сохранения регистроф и статусных флагов для того, что бы все что вы делали до возникновения прерывания не было затронуто.

Тем не менее, вы можете включить прерывания внутри обработчика прерываний, если посчитаете, что вам это жизненно необходимо. Например:

Как правило, у вас должен быть серьезный повод, чтобы сделать это, так как другое прерывание может вызвать рекурсивный вызов pinChange и, вполне возможно, приведет к нежеланному результату.

Как долго может выполняться обработчик прерывания?

В соответствии с техническим руководством, минимально требуемое время для обработки прерывания составляет 4 такта (для помещения текущего программного счетчика в стек), затем выполняется код, размещенный по вектору прерывания. Как правило, там содержится переход на процедуру обработки прерывания, что занимает еще 3 такта.

Затем функция ISR делает что-то вроде этого:

Это еще 16 тактов (указаны в круглых скобках). Итак, с момента, как произошло прерывание до того, как будет выполнена первая строка кода пройдет 16+7=23 такта, по 62 нс на такт, итого 1.4375 мкс. Это для частоты 16 МГц.

При выходе из обработчика прерывания, мы имеем следующий код:

Это еще 19 тактов (1.1875 мкс). Таким образом, процедура обработки прерывания, используя предопределенную функцию ISR займет 2.626 мкс плюс код, который будет внутри.

Однако, внешние прерывания (где используется attachInterrupts) выполняются немного дольше:

Я насчитал здесь 82 такта (итого 5.125 мкс на 16 Мгц) и плюс еще время, которое требуется указанной функции обработчика, то есть 2.9375 мкс перед входом в обработчик и 2.1875 при возвращении.

Сколько времени проходит до того, как процессор начинает входить в обработчик?

Тут могут быть различные варианты. Приведенные выше цифры являются идеальными для случая, когда прерывание обрабатывалось немедленно. Некоторые факторы могут привнести задержку:

Производительность

Прерывания могут повысить производительность во многих ситуациях потому, что позволяют реализовать основную программу без постоянного отслеживания, например, нажатия кнопки. Однако, cлужебные процедуры, обслуживающие прерывания, как уже сказано выше, будут выполняться дольше, чем циклический опрос входного порта. Если вам совершенно необходимо, отреагировать на события, скажем, за микросекунды, то прерывание для этого будет слишком медленным. В этом случае вы можете отключить прерывания (например, таймеры) и просто следить в цикле за изменением состояния пина.

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

Существует два типа прерываний:

Те, которые устанавливают флаг, могут рассматриваться как помещаемые в очередь. Флаг прерывания остается установленным до тех пор, пора не будет осуществлен вход в процедуру обработки прерывания, после чего флаг сбрасывается процессором. Так как существует только один флаг, то если то же самое условие для возникновения прерывания создастся вновь до того, как первое будет обработано, обработка не будет произведена дважды.

Что-то в программе должно знать, что эти флаги должны быть установлены до того, как вы подключите обработчик прерывания. Например, для прерывания по фронту или спаду на выводе D2 можно установить соответствующий флаг и, как только, вы вызовете функцию attachInterrupt прерывание возникает немедленно, даже если событие произошло час назад. Чтобы избежать этого, вы можете вручную сбросить флаг. Например:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *