Прерывания arduino: Аппаратные прерывания

Vanyamba uses Linux — Прерывания Arduino

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

Соответственно, разные модели микроконтроллеров имеют разные наборы прерываний и разные таблицы векторов прерываний.

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

Таким образом для каждого типа прерывания программист может определить отдельную функцию, которая будет по данному прерыванию вызываться. Что очень удобно. Например, прерывание по таймеру 1 — одна функция, по таймеру 2 — другая функция, при приёме очередного байта по последовательному интерфейсу — третья функция, и т.д. Это позволяет в каждой такой функции-обработчике прерывания разместить только тот код, который относится к данному событию, и недобавлять в неё ничего, что к данному вектору прерывания не относится.

Микроконтроллеры ATmega168 и ATmega328p, на основе которых сделан Arduino, отличаются друг от друга только размером памяти, и поэтому имеют одинаковый набор векторов прерываний. Единственная несовместимость между ними состоит в том, что таблица прерываний при использовании загрузчика располагается не в начале памяти программ, а в начале памяти загрузчика, и поскольку память загрузчика расположена в конце памяти программ, то этот адрес у них разный из-за разного размера этой самой памяти.

Прерывания этих микроконтроллеров определены в заголовочных файлах <iom328p.h> и <iom168. h> и выглядит это определение следующим образом:

/* Interrupt Vectors */
/* Interrupt Vector 0 is the reset vector. */
#define INT0_vect         _VECTOR(1)   /* External Interrupt Request 0 */
#define INT1_vect         _VECTOR(2)   /* External Interrupt Request 1 */
#define PCINT0_vect       _VECTOR(3)   /* Pin Change Interrupt Request 0 */
#define PCINT1_vect       _VECTOR(4)   /* Pin Change Interrupt Request 0 */
#define PCINT2_vect       _VECTOR(5)   /* Pin Change Interrupt Request 1 */
#define WDT_vect          _VECTOR(6)   /* Watchdog Time-out Interrupt */
#define TIMER2_COMPA_vect _VECTOR(7)   /* Timer/Counter2 Compare Match A */
#define TIMER2_COMPB_vect _VECTOR(8)   /* Timer/Counter2 Compare Match A */
#define TIMER2_OVF_vect   _VECTOR(9)   /* Timer/Counter2 Overflow */
#define TIMER1_CAPT_vect  _VECTOR(10)  /* Timer/Counter1 Capture Event */
#define TIMER1_COMPA_vect _VECTOR(11)  /* Timer/Counter1 Compare Match A */
#define TIMER1_COMPB_vect _VECTOR(12)  /* Timer/Counter1 Compare Match B */ 
#define TIMER1_OVF_vect   _VECTOR(13)  /* Timer/Counter1 Overflow */
#define TIMER0_COMPA_vect _VECTOR(14)  /* TimerCounter0 Compare Match A */
#define TIMER0_COMPB_vect _VECTOR(15)  /* TimerCounter0 Compare Match B */
#define TIMER0_OVF_vect   _VECTOR(16)  /* Timer/Couner0 Overflow */
#define SPI_STC_vect      _VECTOR(17)  /* SPI Serial Transfer Complete */
#define USART_RX_vect     _VECTOR(18)  /* USART Rx Complete */
#define USART_UDRE_vect   _VECTOR(19)  /* USART, Data Register Empty */
#define USART_TX_vect     _VECTOR(20)  /* USART Tx Complete */
#define ADC_vect          _VECTOR(21)  /* ADC Conversion Complete */
#define EE_READY_vect     _VECTOR(22)  /* EEPROM Ready */
#define ANALOG_COMP_vect  _VECTOR(23)  /* Analog Comparator */
#define TWI_vect          _VECTOR(24)  /* Two-wire Serial Interface */
#define SPM_READY_vect    _VECTOR(25)  /* Store Program Memory Read */
#define _VECTORS_SIZE (26 * 4)

Всего, как можно увидеть из значения определения _VECTORS_SIZE, векторов прерываний 26, и на каждый отводится 4 байта. Вектор прерывания 0 — это на самом деле вектор прерывания по нажатию кнопки сброс.

Для того, чтобы было удобнее, ниже приведена таблица с комментариями:

Использование прерываний с Arduino • AranaCorp

Теги: Arduino, Real Time

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

Материал

  • Arduino UNO
  • Кнопка (или другой датчик)
  • Кабель USB A/USB B

Схема

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

Reminder of the digital pins compatible with the interrupts

903025 Nano BLE, Nano 33 BLE Sense
Uno, Nano, Mini, other 328-based 2, 3
Uno WiFi Rev. 2, Nano Every all digital pins
Мега, Мега2560, МегаАДК 2, 3, 18, 19, 20, 21
Micro, Leonardo, Other 32U4 0, 1, 2, 3, 7
Zero . , 1, 4, 5, 6, 7, 8, 9, A1, A2
Nano 33 IoT 2, 3, 9, 10, 11, 13, 15, A5, A7
все контакты
Due все цифровые контакты
101 все цифровые контакты (только контакты 2, 5, 7, 8, 10, 11, 12, 13 работают с CHANGE )

Код управления прерыванием :

 attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) 

With pin, используемый контакт, ISR, функция для активации при обнаружении события и mode, используемый режим обнаружения.

  • НИЗКИЙ, чтобы включить обнаружение, когда шпиндель находится в НИЗКОМ состоянии
  • ИЗМЕНЕНИЕ для включения обнаружения при изменении состояния шпинделя
  • ПОДЪЕМ для включения обнаружения при изменении состояния вывода с НИЗКОГО на ВЫСОКИЙ
  • ПАДЕНИЕ для включения обнаружения при изменении состояния вывода с ВЫСОКОГО на НИЗКИЙ
 const byte ledPin = 13;
константный байт interruptPin = 2;
состояние изменчивого байта = LOW;
недействительная установка () {
 
Серийный номер
. begin(9600); pinMode(ledPin, ВЫХОД); pinMode (interruptPin, INPUT_PULLUP); attachInterrupt (digitalPinToInterrupt (interruptPin), onEvent, CHANGE); Серийный номер .println(F("Инициализация системы")); } недействительный цикл () { digitalWrite(ledPin, состояние); } недействительным onEvent () { состояние = !состояние; Серийный номер .print(F("Светодиодный индикатор 13: ")); если (состояние) { Серийный номер .println(F("ON")); }еще{ Серийный номер .println(F("ВЫКЛ")); } }

Предупреждение: В функции onEvent() не будут работать функции millis() и delay(), зависящие от прерываний.

Функции, которые необходимо знать, чтобы идти дальше в управлении прерываниями

  • Attrainterrupts
  • Снижение разрыва (DigitalPintointerrupt (PIN)) Отключить указанное прерывание
  • NOENTERRUPTS () . код загружается, если вы нажмете кнопку, светодиод на Arduino должен загореться и погаснуть.

    Источники

    • Ссылка Arduino на прерывания
    • Управление нажатием кнопки

    Учебные пособия и другие примеры по автоматическому коду генератора
    Программное обеспечение

    Насколько полезен был этот пост?

    Нажмите на звездочку, чтобы оценить!

    Средняя оценка 5 / 5. Количество голосов: 1

    Голосов пока нет! Будьте первым, кто оценит этот пост.

    Сожалеем, что этот пост не был вам полезен!

    Давайте улучшим этот пост!

    Расскажите, как мы можем улучшить этот пост?

    Понимание внутренней работы Arduino: прерывания

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

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

     

     

     

     

    В любое время, когда вы хотите настроить прерывание, вы должны убедиться, что следующие три вещи выполняются для того, чтобы прерывание было включено: Global 0s

  • 3 3 (в AVR это достигается с помощью функции sei() ).
    Обратите внимание, что глобальные прерывания включены в Arduino по умолчанию.
  • Отдельное прерывание должно быть разрешено (обычно путем установки бита в определенном регистре, связанном с этим прерыванием).
  • Должно быть выполнено условие прерывания (например, спадающий фронт на определенном контакте).
  • Если выполняются все три условия, произойдет прерывание. Процессор прекратит выполнение своей основной программы, переменные состояния будут сохранены в памяти, а выполнение перейдет к таблице векторов прерываний (IVT). IVT сообщает процессору, куда двигаться дальше, в зависимости от того, какое прерывание произошло (это называется «вектором прерывания»). Внешнее прерывание, возникающее на выводе 2 порта D (PD2), известно под меткой INT0.

    IVT находится в верхней части памяти программ. Процессор переходит к адресу INT0, который обычно содержит одну инструкцию, указывающую процессору снова перейти в другое место в памяти. Это следующее место содержит подпрограмму обслуживания прерывания (ISR), которая может содержать любое количество инструкций для процессора, которые должны выполняться дальше.

    После завершения выполнения ISR процессор возвращается к тому месту, где он остановился в основной программе.

    Чтобы ваш процессор не находился в ISR в течение длительного периода времени (и чтобы избежать пропуска важных вычислений или других прерываний), рекомендуется, чтобы ISR были как можно короче.

    Что касается таймеров, ATmega328P имеет три таймера, с которыми вы можете работать. Их можно использовать для запуска ISR с различными интервалами (выборка датчика, вычисление нового значения и т. д.) или переключения/установки вывода без необходимости вызова ISR (полезно для настройки широтно-импульсной модуляции по принципу «запустил и забыл»). .

    Имя Размер Возможные прерывания Использование в Arduino
    Таймер0 8 бит
    (0–255)
    Сравнить Совпадение
    Переполнение
    задержка(), миллис(), микрос()
    AnalogWrite() контакты 5, 6
    Таймер 1 16 бит
    (0–65 535)
    Сравнение совпадений
    Переполнение
    Захват ввода
    Сервофункции
    AnalogWrite() контакты 9, 10
    Таймер2 8 бит
    (0–255)
    Сравнить Совпадение
    Переполнение
    тон()
    AnalogWrite() контакты 3, 11

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

    • Сравнение совпадений — Когда значение таймера достигает определенного значения (хранящегося в соответствующем регистре сравнения выходов), будет сгенерировано прерывание.
      Это может быть полезно для создания сигналов широтно-импульсной модуляции (ШИМ) на выводах или выборки датчика через определенные промежутки времени.
    • Переполнение — Когда таймер переходит от максимального значения (например, 65 535) к 0, генерируется прерывание. Прерывания переполнения также используются для ШИМ-сигналов и запуска фрагментов кода через определенные промежутки времени.
    • Захват входных данных — Когда определенный вывод изменяет значение (например, ICP1), текущее значение таймера сохраняется в другом регистре (ICR1), который можно получить позже, чтобы увидеть точное время, когда произошло это событие. Этот тип прерывания хорош для измерения времени между импульсами.

     

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

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

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