КАРТА БЛОГА (содержание) , Online-построитель графиков .

понедельник, 3 августа 2020 г.

Настройка стека на ассемблере для ATtiny2313 и подключение .inc файла

При написании программ для микроконтроллеров на языке C от программистов обычно не требуется такое действие как настройка стека, однако если программа пишется на ассемблере то настраивать его нужно в большинстве случаев а также нужно понимать зачем он нужен и как используется. Стеком (применительно к микроконтроллерам AVR) можно считать некоторую область в оперативной памяти (ОЗУ) которая может заполняться и опустошаться (т.е. как бы менять свои размеры) в процессе работы программы. В 8ми битных микроконтроллерах AVR в стек может быть помещено 8 бит информации за один раз в конец стека, извлечено также 8 бит информации за один раз из его конца. Заполнять и извлекать информацию из стека можно только с его конца (т.е. брать можно только последний элемент) (хотя на самом деле это ограничение можно обойти но суть стека в том что можно трогать только последний его элемент). Данные микроконтроллеры работают так что стек заполняется не от начала ОЗУ до его конца а наоборот т.е. если первый элемент помещен по какому то адресу в ОЗУ то следующий элемент будет помещен по адресу который на единицу меньше чем предыдущий и т.д. Настройка стека заключается в том чтобы указать с какого адреса начинается стек, путем помещения этого адреса в соответствующие регистры (для микроконтроллеров у которых максимальный адрес ОЗУ не помещается в один байт) или регистр (как в данном случае для ATtiny2313 т.к. этот микроконтроллер имеет небольшой размер ОЗУ). Для ATtiny2313 этот регистр называется SPL и чаще всего в него помещается самый большой адрес из ОЗУ чтобы для стека было как можно больше места чтобы "разростись" и не перекрывать те области ОЗУ которые заполняются другими данными. Стек можно использовать по разному но в основном он нужен чтобы использовать подпрограммы в программе на ассемблере. Подпрограммы - это набор инструкций который может быть размещен где нибудь во флешь памяти и выполнятся по мере необходимости после вызовов из основной программы. Подпрограмма может вызываться много раз и использование их позволяет экономить место во флешь памяти не заполняя его повторными одинаковыми инструкциями. После вызова такой подпрограммы в стек помещается адрес того места на котором остановилось выполнение основной программы чтобы позже в это место вернуться. Также стек можно использовать чтобы просто хранить в нем какую либо информацию. В общем стек - вещь нужная и поэтому её нужно настраивать. Если взять программу из предыдущей статьи и дополнить её настройкой стека то получиться так:

Данная программа заработает если её откомпилировать и загрузить в ATtiny2313 методами описанными в предыдущих уроках. Однако можно заметить что обращения к регистрам микроконтроллера осуществляются по их адресам написанным в шеснадцатеричном виде хотя у регистров есть свои буквенные имена по которым обращение к ним было бы более удобным. Для того чтобы реализовать такое более удобное обращение существуют специальные .inc файлы которые можно подключить директивой .INCLUDE. К сожалению те файлы что скачиваются вместе с компилятором avra не подходят для этого компилятора т.к. содержат инструкции которые им не поддерживаются. Если эти инструкции удалить то можно получить урезанный но подходящий файл. Скачать такой можно по ссылке https://yadi.sk/d/QUFvZ5JgAwyYpw. Далее этот файл надо поместить в папку где располагается .asm файл с кодом:

и перед компиляцией в CMD перейти в папку с данными файлами. Сделать это можно командой CD. После этого компилятор не должен выдавать предупреждение о том что он не опознал микроконтроллер т.к. в подключенном файле находиться директива которая указывает ему для какого микроконтроллера написана эта программа. 
После подключения данного файла и замены шестнадцатеричных адресов регистров их названиями код программы стал более понятным и удобным! Хотя всё же есть ньюансы которые стоит разяснить. Например Low(RAMEND) - означает что из двухбайтового числа которое теперь называется RAMEND мы возьмем только ту часть которая расположена в младших разрядах (как бы низкую половину возьмем). Low - это такой макрос который берет и выделяет эту половину. Т.к. ATtiny2313 это 8ми битный микроконтроллер и регистры в нем 8ми битные то поместить мы в них можем только 8 бит а адрес м.б. больше 8 ми бит, хотя в данном случае это не так и можно было бы сразу записать это число но для других микроконтроллеров этот макрос пригодиться.