воскресенье, 9 августа 2020 г.

Прерывание по переполнению таймера на ассемблере для ATtiny2313

Таймеры/счетчики есть в большинстве современных микроконтроллеров. Они используются для множества разнообразных целей. Например для каких нибудь часов, широтно-импульсной модуляции (ШИМ), динамической индикации и ещё очень много для чего. В микроконтроллере ATtiny2313 их два. Один из них 8ми битный другой 16ти битный. Тот что 8ми битный может считать только до 255 т.к. для большего числа нужно большее количество бит. На основе 8ми битного счетчика можно делать что либо с малыми промежутками времени напр. ШИМ, динамическую индикацию, какие либо короткие импульсы напр. для каких нибудь протоколов связи по какому нибудь редкому интерфейсу или для чего нибудь ещё для чего нужны не долгие импульсы. На основе 16ти битного таймера счетчика можно делать длинные задержки (но короткие делать тоже можно). 16ти битный таймер/счетчик более универсальный поэтому его стоит изучить первым. На его основе можно сделать светодиодную мигалку

Рассмотрим ассемблерный код светодиодной мигалки на таймере:


Вначале подключаем специальный файл а также указываем директиву начала сегмента кода (об этом подробно написано в предыдущем уроке). Далее после директивы ORG с адресом с которого начинается выполнение программы ставим безусловный переход для того чтобы код изменения состояния светодиода (зажечь когда погашен или погасить когда зажжен) не выполнялся сразу после запуска микроконтроллера или после сброса. Далее инициализация стека (см. предыдущий урок). После инициализации стека идет инициализация таймера. Для настройки таймера есть некоторое количество регистров. В простейшем варианте (как сейчас) достаточно настроить два регистра TCCR1B - для запуска таймера и настройки его тактирования а также TIMSK - для разрешения прерывания. У разных микроконтроллеров регистры настраиваются по разному поэтому при переходе на другой микроконтроллер надо смотреть документацию и возможно устанавливать другие биты. В данном случае в регистре TCCR1B наиболее интересны первые 3 бита которыми устанавливается тактирование таймера. Если все три этих бита нули то раймер не тактируется и не работает. Если нулевой бит с единицей а остальные с нулем то таймер тактируется от того же генератора что и центрайльный процессор микроконтроллера и без предделителя. Если первый бит с единицей а остальные с нулями то тактирование также от генератора для центрального процессора но добавляется предделитель на 8. Более наглядно все опции представлены в таблице в документации:

Чтобы разрешить прерывание по переполнению 16ти битного таймера нужно в 7ой бит регистра TIMSK записать 1. Этот регистр в ATtiny2313 отличается от того же регистра в например ATmega8 т.е. TIMSK ATtiny2313 не TIMSK ATmega8 и настраивать их нужно по разному. 

Далее в коде пин со светодиодом настраивается на выход (об этом в предыдущих уроках). 

Командой SEI разрешаются все прерывания в том числе и то что было настроено для таймера.

Далее идет основной цикл в котором ничего интересного не происходит. Когда таймер досчитывает до максимального числа которое может поместиться во все его 16 бит, происходит переполнение этого таймера и прерывание по этому переполнению. Выполнение прогрвммы переноситься из основного цикла на ячейку флешь памяти с адресом обозначаемым как OVF1addr. А в этой ячейке организован безусловный переход на подпрограмму обработки этого прерывания. В этой подпрограмме меняется состояние светодиода (с погашенного на горящий или с горящего на погашенный). Команда RETI осуществляет выход из подпрограммы обработки прерывания. Выход происходит обратно в основной цикл где ничего интересного. Таймер опять считает до максимального значения и далее все повторяется.



Комментариев нет:

Отправить комментарий