Популярные статьи

BMW 3-series Coupe (Бмв ) 2006-2009: описание, характеристики, фото, обзоры и тесты

С сентября 2006 года серийно выпускается БМВ 3-й серии купе (Е92). Невзирая на свое техническое родство с седаном и Touring, купе БМВ 3-й серии имеет

Длительный тест Range Rover Sport: часть вторая

Аш длительный тест Range Rover Sport Supercharged подошел к концу. Первая хорошая новость: машину не угнали! Вторая: несмотря на соблазн, за

Audi E-tron (Ауди ) 2010: описание, характеристики, фото, обзоры и тесты

Audi E-tron, представленный на автосалоне в Детройте в январе 2010 года, совсем не то же самое, что E-tron, который выставлялся осенью на IAA 2009 во

Принципы ухода за АКБ зимой

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

SEAT Toledo (Сиат Толедо) 1998-2004: описание, характеристики, фото, обзоры и тесты

Эта модель расширяет присутствие компании SEAT в сегменте рынка престижных автомобилей. Toledo - первый автомобиль компании дизайн которого выполнен

В 2000 г. семейство японских Corolla лишь обновилось. Спрос на эти машины падал и классическая Corolla уже не устраивала японских покупателей. Как

Skoda Octavia (Шкода Октавия) 1996-1999: описание, характеристики, фото, обзоры и тесты

Skoda Octavia - это современный переднеприводной автомобиль с поперечным расположением двигателя. На нём может стоять один из пяти моторов концерна

Chrysler PT Cruiser (Крайслер Пт крузер) 1999-2010: описание, характеристики, фото, обзоры и тесты

Дебют серийной модели PT Cruiser состоялся в 1999 году в Детройте. Компании Chrysler удалось зацепить ностальгическую струну в душе каждого простого

Примеряем Audi A6 Allroad и A8 Hybrid к нашим дорогам

Компания сыграла на контрасте, представив одновременно две модели, совершенно противоположные по идеологии: сверхэкономичный лимузин-гибрид А8 и

Toyota Tundra Crew Max (Тойота Тундра Crew Max) 2006-2009: описание, характеристики, фото, обзоры и тесты

Toyota Tundra (Тойота Тундра) проектировался как грузовик. Мощный двигатель, основательная рама и большая грузоподъемность... вот что отличает этот

Архив сайта
Облако тегов
Календарь

Прерывания.

Опубликовано: 05.09.2018

видео Прерывания.

#6. Что такое регистры и прерывания / 2. Введение в ассемблер / Программирование с нуля

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



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

while ( 1 ) { PORTB.0 = 1 ; delay_ms ( 500 ) ; PORTB.0 = 0 ; delay_ms ( 500 ) ; }

Что если в эту программу добавить обработку нажатия кнопки?


Лекция 8: Прерывания

while ( 1 ) { if ( PINB.1 == 0 ) { PORTD.0 = 1 ; } PORTB.0 = 1 ; delay_ms ( 500 ) ; PORTB.0 = 0 ; delay_ms ( 500 ) ; }

Допустим пользователь нажал кнопку в момент, когда программа выполняет строчку PORTB.0=1, т.е. до того как будет проверено наше условие if(PINB.1==0), должны выполниться две строчки с задержкой по 500ms. Получается пользователь должен держать кнопку больше секунды, чтобы она сработала, это жутко не удобно.

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

Думаю идея понятна, подобных ситуаций может быть множество. Решение подобных проблем, когда нужно совместить выполнение основной программы, с некоторой более неотложной задачей, возлагается на прерывание. Прерывание это и есть кусок вашего важного кода.

Например, выполняется ваш цикл мигалки, при этом происходит некоторое событие, программа останавливается, допустим на строчке PORTB.0=0 и перескакивает на строчку if(PINB.1==0). После выполнения этой строчки, программа вернется к основному циклу на строчку delay_ms и будет крутить основной цикл, до тех пор пока снова не будет вызвано следующее прерывание.

interrupt [ номер вектора ] void имя функции обработчика прерывания ( void ) { if ( PINB.1 == 0 ) { PORTD.0 = 1 ; } } void main ( void ) { while ( 1 ) { PORTB.0 = 1 ; delay_ms ( 500 ) ; PORTB.0 = 0 ; delay_ms ( 500 ) ; } ; }

Так что же это за такие события, способные остановить выполнения основной программы. Например, переполнение таймера. Допустим, вы настроили таймер, который умеет считать до 255 и у него есть прерывание по переполнению. Это значит, что он досчитает до 255, и вызовет, тот самый важный кусок кода.

interrupt [ TIM0_OVF ] void timer0_ovf_isr ( void ) { }

Еще одним вариантом прерывания таймера, является прерывание по совпадению. Представьте себе, что таймер тикает 1 раз в секунду, мне нужно чтобы он дотикал до 60 и прибавил в переменную минута единичку. Для этого в регистр сравнения таймера нужно запихать 60, дальше он сам по себе будет проверять равно ли текущее количество тиков заданному. Когда это произойдет, программа автоматически прыгнет и выполнит требуемый код.

interrupt [ TIM1_COMPA ] void timer1_compa_isr ( void ) { min ++; }

Обратите внимание название функций содержат названия таймеров, в первом случае TIM0 уже понятно что прерывание относится к таймеру0, во втором TIM1 — таймер1. Также из названия функции понятно по какому событию происходит прерывание COMPA — compare — сравнение, OVF — overflow, переполнение.

Кроме того, существуют прерывания, которые не связаны с таймерами, например внешнее прерывание. У микроконтроллеров есть ножки отведенные под внешнее прерывание и при воздействии на эту ножку извне программа выполняет код указанный в прерывании. Можно настроить так, чтобы прерывание возникало при низком уровне на ножке, нарастании/спаду фронта  или по любому изменению. Об этом уже говорилось в статье про частотомер.

interrupt [ EXT_INT0 ] void ext_int0_isr ( void ) { }

Также, прерывание может возникать, при приеме или передаче данных по UART, для этого достаточно настроить соответствующее прерывание.

Кстати, иногда по тексту программы требуется отключить/включить прерывания.

// Разрешить глобальные прерывания #asm("sei") // Запретить глобальные прерывания #asm("cli")

Как же узнать, какие прерывания есть у используемого микроконтроллера? Либо читать документацию (даташит) на него, либо посмотреть в codewizard список доступных прерываний. В визарде обычно прерывания включается галочкой interrupt. Настоятельно советую разобраться с визардом, он сэкономит кучу времени.

Update. По просьбам трудящихся. Как пользоваться CodeWizard

Запускаем визард.

Смотрим на имеющуюся периферию

Сразу нужно понять, что это относится к самому камню, микроконтроллер не знает что такое кнопка, у него есть ножка и все манипуляции производятся именно с ней. Для манипуляций с ножкой имеется внешнее прерывание. Как им пользоваться описано в 13 уроке AVR.

Для прерываний по таймеру, заходим в раздел Timers/Counter, основное прерывание по таймеру это по совпадению — аналог будильника, т.е. когда выставленное значение совпало с количеством тиков. Про этот режим читаем 5 урок.

Может так оказаться что у таймера нет режима по совпадению, но наверняка есть по переполнению, т.е. если таймер 8 битный, то его максимум 2^8, когда он дотикает до этого значения он обнулится, заодно вызовет прерывание.

rss