Внешними прерываниями называются такие прерывания основного цикла программы которые возникают в результате воздействия на специальные пины, электрических сигналов определенного вида. Для attiny2313 есть 4 таких вида:
1) передний фронт импульса (переход напряжения от низкого уровня до высокого),
2) задний фронт импульса (или спад (переход напряжения от высокого уровня к низкому)),
3) и фронт и спад,
4) низкий уровень напряжения.
То какой из них будет вызывать прерывание настраивается регистром MCUCR данного микроконтроллера. Реакция микроконтроллера на внешние прерывания гораздо быстрее чем его реакция на опрос пина порта командами SBIS и SBIC в основном цикле т.к. прежде чем пин опросится этими командами должны будут выполнится команды в основном цикле а это как минимум безусловный переход который делает этот основной цикл. С внешними прерываниями программа может работать настолько быстро что даже сможет посчитать дребезг контактов кнопки подключенной к пину внешнего прерывания. У attiny2313 есть 2 пина внешних прерываний, на схеме они помечаются как INT0 и INT1:
Счетчик дребезга контактов - это интересное устройство которое можно использовать для примерной оценки того насколько проверяемые контакты плохи своим дребезгом. Схема счетчика дребезга контактов на attiny2313:
Самым простым способом показать колличество дребезга является светодиод. Светодиод может мигнуть столько раз сколько кнопка сделала паразитных переключений своим дребезгом. От программатора, при этом, микроконтроллер м.б. отсоединен. Теперь давайте рассмотрим код программы на ассемблере:
В начале, как всегда, подключается файл с константами и макросами для attiny2313, далее директивой .CSEG указывается начало сегмента кода а после директивы .ORG 0x0000 происходит "перепрыгивание" через фрагмент когда который перенаправляет выполнение программы на подпрограмму обработки прерывания. Это нужно чтобы эта подпрограмма не сработала сразу после старта. Когда после того как произошло внешнее прерывание INT0 происходит переход по метке i0 в самый низ этого кода где число в регистре R17 увеличивается на единицу т.е. инкрементируется, после чего в регистр r20 записывается число 250 для того чтобы после возврата в основной цикл, задержка начиналась заново. Команда RETI делает выход из подпрограммы обработки прерывания обратно в основной цикл. Перед основным циклом происходит инициализация стека для того чтобы прерывание срабатывало как при фронте так и при спаде в нулевой бит регистра MCUCR записывается единица. Такой вид внешнего прерывания выбран по тому что светодиод, в основном цикле, также будет менять свое состояния на каждой итерации основного цикла т.е. переходить в светящееся состояние если он не светиться и переходить в не светящееся состояние если он светиться т.о. надо инкрементировать счетчик дребезга два раза при одном импульсе для того чтобы был подсчет полных импульсов. Записью единицы в 6й бит регистра GIMSK происходит разрешение внешнего прерывания INT0. Далее пин к которому подключен светодиод настраивается на выход и командой SEI разрешаются прерывания вообще. После чего начинается основной цикл в котором имеется задержка, для того чтобы глаз человека успевал замечать мигания светодиода, после которой происходит переход в начало основного цикла если в регистре с количеством дребезга пусто. Если же там не пусто то в атомарном блоке (блоке между запретом прерываний CLI и их разрешением SEI) происходит изменение состояния светодиода вместе с декркментированием (уменьшением на единицу колличества дребезга) после этого атомарного блока происходит возврат на начало основного цикла. Программа простая и не без недостатков но тем не менее её написание является хорошей тренировкой по ассемблеру в образовательных целях и собранное устройство даже имеет некоторую практическую ценность т.к. используя его можно убедиться в наличии дребезга контактов а также примерно оценить насколько контакты плохи в плане наличия этого дребезга. Посмотреть как работает счетчик дребезга и послушать описание работы программы можно на видео: