interrupts()
interrupts() возобновляет обработку прерываний после noInterrupts() — вызывайте её сразу после критического участка, иначе Serial, millis() и delay() перестанут работать корректно.
Полная статья
Описание
Прерывания в Arduino работают по умолчанию: они позволяют микроконтроллеру реагировать на внешние события и выполнять фоновые задачи — например, отслеживать входящие данные по UART или обновлять счётчики таймеров. Иногда нужно временно отключить прерывания, чтобы защитить критический участок кода от нежелательного вмешательства. Именно для этого существует пара функций noInterrupts() и interrupts().
Функция interrupts() возобновляет обработку прерываний после того, как они были заблокированы noInterrupts(). Пока прерывания отключены, некоторые функции работают некорректно: данные по Serial могут теряться, показания millis() перестают обновляться, а внешние события — игнорироваться. Поэтому важно держать «защищённый» участок как можно короче и сразу после него вызывать interrupts().
Синтаксис
Чтобы снова разрешить прерывания, вызовите:
interrupts()
Параметры
Функция не принимает параметров.
Возвращает
Эта функция ничего не возвращает.
Пример кода
Пример показывает типичный шаблон: прерывания отключаются на время работы с критическими данными, а затем сразу включаются снова.
void setup() {}
void loop() {
noInterrupts();
// критический, чувствительный ко времени код
interrupts();
// остальной код
}
Где применяется
- Чтение многобайтовых переменных, которые могут обновляться в обработчике прерывания: без блокировки прерываний есть риск прочитать «половину» старого и «половину» нового значения.
- Точное измерение временны́х интервалов: если несколько микросекунд важны, прерывания на этот промежуток отключают, а сразу после измерения включают обратно.
- Работа с аппаратными регистрами, где последовательность операций должна быть атомарной и не прерываться между шагами.
Практические замечания
- Всегда вызывайте
interrupts()послеnoInterrupts()— забытый вызов приведёт к тому, что Serial перестанет работать,delay()зависнет, а внешние события будут пропускаться. - Держите «закрытый» участок максимально коротким: в идеале — несколько строк, не более нескольких десятков микросекунд.
- Функция
interrupts()безопасна для вызова, даже если прерывания уже включены — повторный вызов не вызывает ошибок. - Если ваш скетч использует библиотеки, которые работают с прерываниями (например, Servo или Wire), убедитесь, что вы не блокируете прерывания на слишком долгое время — это может нарушить их работу.
- При отладке через Serial Monitor помните: если прерывания отключены и вы пытаетесь что-то вывести в Serial, символы могут теряться или вывод зависнет.