4.06.1. Лабораторная работа №4.6.1.md
Мгновенная реакция
Тема работы
Вспомните наши прошлые программы, если в коде есть команда delay(3000)
, то на целые три секунды микроконтроллер полностью «замирает» и не может реагировать ни на какие нажатия кнопок. Это большая проблема для интерактивных устройств. В этой лабораторной работе мы решим её с помощью аппаратных прерываний. Мы напишем программу, в которой один светодиод будет медленно мигать, блокируя основной цикл, а второй будет мгновенно менять своё состояние по нажатию кнопки, «обгоняя» все задержки.
Цель
- На практике освоить использование аппаратных прерываний с помощью
attachInterrupt()
. - Понять разницу между опросом (
polling
) вloop()
и обработкой событий через прерывания. - Научиться писать простые, но эффективные функции-обработчики прерываний (
ISR
).
Оборудование и материалы
- Отладочная плата
Рудирон
. - USB-кабель для подключения
Рудирона
к компьютеру. - Компьютер с настроенной средой
Arduino IDE
.
Ход работы
-
Подготовка платы и перемычек
Для этого эксперимента нам понадобятся только встроенные компоненты:
- Кнопка
B1
, которая подключена к пину 35. Этот пин поддерживает аппаратные прерывания. - Светодиоды
L1
(пин 5) иL2
(пин 7).
Критически важный шаг На плате
Рудирон
есть специальная перемычкаIRQ
. По умолчанию она может быть установлена, так как используется для работы с радиомодулем. Чтобы мы могли свободно использовать прерывания на других кнопках (B1
иB3
) и избежать конфликтов, эту перемычку необходимо снять.- Установите перемычку
PRG | RUN
в положениеPRG
. - Подключите плату к компьютеру и настройте
Arduino IDE
(платаRudiron_Buterbrod_R10_20MHz
и правильный COM-порт).
- Кнопка
-
Написание и загрузка кода
-
В
Arduino IDE
создайте новый скетч и введите следующий код:// Используем переменные для хранения состояния светодиодов // Ключевое слово "volatile" ОБЯЗАТЕЛЬНО для переменных, // которые изменяются внутри прерывания. volatile bool led1State = LOW; bool led2State = LOW; void setup() { pinMode(LED_BUILTIN_1, OUTPUT); pinMode(LED_BUILTIN_2, OUTPUT); pinMode(BUTTON_BUILTIN_1, INPUT_PULLDOWN); // Настраиваем прерывание на кнопке B1 attachInterrupt(digitalPinToInterrupt(BUTTON_BUILTIN_1), toggleLed1, RISING); } // Обработчик прерывания (ISR) void toggleLed1() { // Меняем состояние переменной led1State = !led1State; // И СРАЗУ ЖЕ управляем светодиодом прямо из прерывания digitalWrite(LED_BUILTIN_1, led1State); } void loop() { // --- Основной цикл, который "тормозит" --- // Меняем состояние второго светодиода led2State = !led2State; digitalWrite(LED_BUILTIN_2, led2State); // Длинная, блокирующая пауза delay(3000); }
- Нажмите кнопку «Upload», чтобы загрузить код на плату.
-
-
Проверка работы
- Сразу после загрузки светодиод
L2
начнёт медленно мигать (включится на 3 секунды, затем выключится на 3 секунды и т.д.). - Теперь самое главное - в любой момент, даже когда
L2
горит и программа, казалось бы, «зависла» вdelay()
, нажмите на кнопкуB1
. - Вы увидите, что светодиод
L1
мгновенно меняет своё состояние (включается или выключается), не дожидаясь, покаdelay()
закончит свою работу.
- Сразу после загрузки светодиод
Результаты
Вы создали по-настоящему многозадачную программу! Вы увидели, как аппаратное прерывание позволяет микроконтроллеру выполнять одно действие (реагировать на кнопку) параллельно другому (медленно мигать светодиодом).
Анализ результатов
attachInterrupt(...)
. Эта команда «вооружила» пин 35. Теперь микроконтроллер аппаратно следит за ним.void toggleLed1()
. Это наша ISR (Interrupt Service Routine). Когда вы нажимаете кнопку, процессор немедленно приостанавливает выполнениеdelay()
вloop()
, «прыгает» в эту функцию, выполняет её и возвращается обратно вdelay()
.digitalWrite()
внутри ISR. Ключевой момент этой программы. Мы вызываемdigitalWrite(LED_BUILTIN_1, led1State)
непосредственно внутри обработчика прерывания. Именно поэтому светодиодL1
меняет своё состояние мгновенно, не дожидаясь завершенияdelay()
в основном цикле. Это наглядно демонстрирует мощь прерываний.volatile
. Это ключевое слово говорит компилятору: «Не пытайся оптимизировать эту переменную, её значение может измениться в любой, самый неожиданный момент!». Хотя в данном примереloop()
не используетled1State
, это остаётся хорошей практикой для всех переменных, разделяемых междуloop()
иISR
.
Выводы
В этой лабораторной работе вы освоили один из самых мощных инструментов в арсенале программиста микроконтроллеров — аппаратные прерывания. Вы научились создавать отзывчивые программы, которые могут мгновенно реагировать на важные события, не прерывая выполнение других задач. Этот подход является основой для построения сложных и надёжных систем.
Вопросы для самопроверки
- Что такое аппаратное прерывание и чем оно отличается от простого опроса в
loop()
? - Какая команда используется для настройки прерывания?
- Почему для этой лабораторной работы было важно снять перемычку
IRQ
? - Почему переменная, используемая в
ISR
, должна быть объявлена какvolatile
? - Какие действия нельзя выполнять внутри функции-обработчика прерывания (
ISR
)? - Как изменить код, чтобы светодиод
L1
реагировал не на нажатие, а на отпускание кнопки?
Поздравляем с освоением прерываний! Теперь ваши проекты могут стать по-настояшему быстрыми и эффективными. В следующем параграфе мы изучим ещё один способ заставить Рудирон
делать несколько дел одновременно, но уже чисто программным методом, без использования delay()
.
- Страницы
- 1. Введение
- 1.01. Лабораторная работа №1.1
- 1.02. Лабораторная работа №1.2
- 1.03. Лабораторная работа №1.3
- 1.04. Лабораторная работа №1.4
- 1.05. Лабораторная работа №1.5
- 2. Основы электроники
- 2.01. Электрический ток и параметры цепи
- 2.01.1. Лабораторная работа №2.1.1
- 2.01.2. Лабораторная работа №2.1.2
- 2.02. Сопротивление в цепи
- 2.02.1. Лабораторная работа №2.2.1
- 2.02.2. Лабораторная работа №2.2.2
- 2.03. Полупроводники
- 2.03.1. Лабораторная работа №2.3.1
- 2.03.2. Лабораторная работа №2.3.2
- 3. Основы программирование на C++
- 3.01. Типы данных и переменные
- 3.01.1. Практикум
- 3.02. Операторы в C++
- 3.02.1. Практикум
- 3.03. Структуры ветвления
- 3.03.1. Практикум
- 3.04. Структуры повторения
- 3.04.1. Практикум
- 3.05. Массивы
- 3.05.1. Практикум
- 3.06. Функции
- 3.06.1. Практикум
- 3.07. Решения задач
- 4. Программирование микроконтроллеров
- 4.01. Цифровые сигналы и GPIO
- 4.01.1. Лабораторная работа №4.1.1
- 4.01.2. Лабораторная работа №4.1.2
- 4.01.3. Лабораторная работа №4.1.3
- 4.01.4. Лабораторная работа №4.1.4
- 4.01.5. Лабораторная работа №4.1.5
- 4.01.6. Лабораторная работа №4.1.6
- 4.01.7. Лабораторная работа №4.1.7
- 4.01.8. Лабораторная работа №4.1.8
- 4.02. Аналоговые сигналы и ШИМ
- 4.02.1. Лабораторная работа №4.2.1
- 4.02.2. Лабораторная работа №4.2.2
- 4.02.3. Лабораторная работа №4.2.3
- 4.02.4. Лабораторная работа №4.2.4
- 4.02.5. Лабораторная работа №4.2.5
- 4.03. Аналоговый сигнал и АЦП
- 4.03.1. Лабораторная работа №4.3.1
- 4.03.2. Лабораторная работа №4.3.2
- 4.03.3. Лабораторная работа №4.3.3
- 4.03.4. Лабораторная работа №4.3.4
- 4.03.5. Лабораторная работа №4.3.5
- 4.04. Аналоговый сигнал и ЦАП
- 4.04.1. Лабораторная работа №4.4.1
- 4.04.2. Лабораторная работа №4.4.2
- 4.05. Генерация и измерение импульсов
- 4.05.1. Лабораторная работа №4.5.1
- 4.05.2. Лабораторная работа №4.5.2
- 4.06. Аппаратные прерывания
- 4.06.1. Лабораторная работа №4.6.1
- 4.06.2. Лабораторная работа №4.6.2
- 4.07. Псевдопараллелизм
- 4.07.1. Лабораторная работа №4.7.1
- 4.07.2. Лабораторная работа №4.7.2
- 4.08. Интерфейсы связи - UART
- 4.08.1. Лабораторная работа №4.8.1
- 4.09. Интерфейсы связи - I2C
- 4.09.1. Лабораторная работа №4.9.1
- 4.10. Интерфейсы связи - SPI
- 4.10.1. Лабораторная работа №4.10.1
- home
-
imgs
- 1. Введение
- 1.01. Лабораторная работа №1.1
- 1.02. Лабораторная работа №1.2
- 1.03. Лабораторная работа №1.3
- 1.04. Лабораторная работа №1.4
- 1.05. Лабораторная работа №1.5
- 2. Основы электроники
- 2.01. Электрический ток и параметры цепи
- 2.01.1. Лабораторная работа №2.1.1
- 2.01.2. Лабораторная работа №2.1.2
- 2.02. Сопротивление в цепи
- 2.02.1. Лабораторная работа №2.2.1
- 2.02.2. Лабораторная работа №2.2.2
- 2.03. Полупроводники
- 2.03.1. Лабораторная работа №2.3.1
- 2.03.2. Лабораторная работа №2.3.2
- 3. Основы программирование на C++
- 3.01. Типы данных и переменные
- 3.01.1. Практикум
- 3.02. Операторы в C++
- 3.02.1. Практикум
- 3.03. Структуры ветвления
- 3.03.1. Практикум
- 3.04. Структуры повторения
- 3.04.1. Практикум
- 3.05. Массивы
- 3.05.1. Практикум
- 3.06. Функции
- 3.06.1. Практикум
- 3.07. Решения задач
- 4. Программирование микроконтроллеров
- 4.01. Цифровые сигналы и GPIO
- 4.01.1. Лабораторная работа №4.1.1
- 4.01.2. Лабораторная работа №4.1.2
- 4.01.3. Лабораторная работа №4.1.3
- 4.01.4. Лабораторная работа №4.1.4
- 4.01.5. Лабораторная работа №4.1.5
- 4.01.6. Лабораторная работа №4.1.6
- 4.01.7. Лабораторная работа №4.1.7
- 4.01.8. Лабораторная работа №4.1.8
- 4.02. Аналоговые сигналы и ШИМ
- 4.02.1. Лабораторная работа №4.2.1
- 4.02.2. Лабораторная работа №4.2.2
- 4.02.3. Лабораторная работа №4.2.3
- 4.02.4. Лабораторная работа №4.2.4
- 4.02.5. Лабораторная работа №4.2.5
- 4.03. Аналоговый сигнал и АЦП
- 4.03.1. Лабораторная работа №4.3.1
- 4.03.2. Лабораторная работа №4.3.2
- 4.03.3. Лабораторная работа №4.3.3
- 4.03.4. Лабораторная работа №4.3.4
- 4.03.5. Лабораторная работа №4.3.5
- 4.04. Аналоговый сигнал и ЦАП
- 4.04.1. Лабораторная работа №4.4.1
- 4.04.2. Лабораторная работа №4.4.2
- 4.05. Генерация и измерение импульсов
- 4.05.1. Лабораторная работа №4.5.1
- 4.05.2. Лабораторная работа №4.5.2
- 4.06. Аппаратные прерывания
- 4.06.1. Лабораторная работа №4.6.1
- 4.06.2. Лабораторная работа №4.6.2
- 4.07. Псевдопараллелизм
- 4.07.1. Лабораторная работа №4.7.1
- 4.07.2. Лабораторная работа №4.7.2
- 4.08. Интерфейсы связи - UART
- 4.08.1. Лабораторная работа №4.8.1
- 4.09. Интерфейсы связи - I2C
- 4.09.1. Лабораторная работа №4.9.1
- 4.10. Интерфейсы связи - SPI
- 4.10.1. Лабораторная работа №4.10.1
- home