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

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

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

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

В некоторых фильмах можно встретить сцены, где время останавливается, всё замирает, а один из персонажей может продолжать что-то делать, словно он или она находится в саду со статуями. А потом время снова начинает идти и никто ничего не замечает. Примерно то же самое происходит и в случае в прерываниями - основная программа "думает" что выполняется только она, а на самом деле в то же самое время процессор может остановить её выполнение, выполнить функцию прерывания, и снова продолжить выполнение основной программы.

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

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

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

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

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

Более того. Контроллер можно вообще перевести в один из так называемых спящих режимов, в котором он просто выключен и не выполняет никаких программ, и только некоторые устройства остаются активными и ждут, не наступит ли заданное событие. А когда такое событие наступает, устройство "будит" микроконтроллер и тот обрабатывает соответствующее прерывание, а затем продолжает работу - например, программа может предписать ему снова "уснуть".

Кроме прерываний, которые не могут прервать обработку прерывания, (так называемые маскируемые прерывания), существуют и прерывания, которые микроконтроллер не может игнорировать. Такие прерывания называется немаскируемыми прерываниями, и примером такого прерывания является например нажатие на кнопку сброс (Reset).