Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Применение директивы .macro мы рассмотрим в главе 7. Рассматривать другие директивы мы здесь не будем, т. к. без них в подавляющем большинстве случаев молено обойтись (интересующихся отсылаю к фирменному описанию AVR-ассемблера). Стоит только упомянуть, что, как и любой другой серьезный язык программирования, AVR-ассемблер предполагает возможность условной компиляции (директивы if, endif, else, ifdef и им подобные), что в совокупности с директивой device позволяет писать программы, например, сразу для ряда моделей процессоров.

Кроме директив компилятора, AVR-ассемблер располагает несколькими стандартными функциями. Из алгебраических доступны две: Ехр2<аргумент> возвращает 2 в степени <аргумент>, а Ьод2<аргумент> — целую часть двоичного логарифма от <аргумент> (где <аргумент>, естественно— константа). Области действия этих функций в 8-разрядном контроллере по понятным причинам сильно ограничены. Все остальные доступные функции предназначены для выделения отдельных байтов из констант или результатов вычислений, если эти результаты размером более одного байта. Наиболее часто из них употребляются функции Low (выделяет младший байт из многобайтового числа) и High (выделяет второй байт; если число двухбайтовое, то он же старший). Например, загрузка значения 62 500 в регистры сравнения таймера-счетчика Timer 1 может происходить так: ldi temp,high(62500) out OCRlAH,temp ldi temp, low(62500) out OCRlAL,temp

Общая структура AVR-программы
Как вы уже знаете, при работе МК последовательно выполняет команды программы, имеющейся в памяти. Программист может менять порядок выполнения команд, организуя циклы и различные переходы. Одно из самых мощных средств программирования — вызов подпрограмм или процедур (в данном случае это одно и то же), т. е. кусков кода, которые могут использоваться неоднократно. Во всех ассемблерах вызов процедур предусмотрен обязательно.

Примечание

В Pascal и других классических алголоподобных языках подпрограммы делятся на процедуры и функции, а в языке С и во всех остальных, основанных на его синтаксисе, есть только функции. В ассемблере, строго говоря, существуют только подпрограммы, но в принципе это все одно и то же.
Естественно, программу сначала нужно записать в память МК, причем так, чтобы МК "знал", откуда начинать при включении питания или после подачи импульса на вывод /RESET. Это его "знание" в случае современных МК AVR также программируется, однако для простоты будем считать, что программа всегда начинает читаться с самой первой ячейки памяти программ — т. е. с нулевого адреса (как указано в главе 2, в современных моделях AVR адрес этот можно изменять, но мы этим здесь заниматься не будем). Исходя из этих обстоятельств, программа должна иметь определенную структуру.

По этому начальному (нулевому) адресу всегда располагается одна и та же команда безусловного перехода (по-английски jump— "прыжок"), которая записывается так:
rjmp RESET
или
jmp RESET

Форма написания (jmp или rjmp) зависит от выбранного контроллера— если в нем объем памяти программ меньше или равен 8 кбайт, то всегда (и не только в этом случае) используется команда rjmp (relative jump, т. е. "относительный безусловный переход"). Она занимает в памяти два байта— как и практически все остальные команды AVR. Код самой команды в этих двух байтах занимает старшую тетраду старшего байта — т. е. четыре бита, остальные 12 битов представляют собой адрес, куда переходить— в данном случае компилятор подставит адрес команды, следующей сразу за меткой RESET, с которой и начнется собственно выполнение программы. Метка с этим именем, естественно, всегда должна присутствовать, но может быть расположена уже в любом другом удобном месте программы, за исключением еще нескольких первых адресов, о назначении которых далее. Метка, естественно, может называться и не RESET, а любым другим именем (например, Main), просто так принято для удобства чтения (хотите найти в любой программе ее начало — ищите метку RESET).

Вернемся к форме записи команды. 12 битов адреса могут представлять 4096 различных адресов. Так как единицей объема памяти программ служит слово из двух байтов, то общий объем адресуемой таким образом памяти и составит 8 кбайт. А вот если памяти больше, то приходится прибегнуть к команде jmp (абсолютный безусловный переход) — она состоит из четырех байтов, в которых адрес займет 22 бита, и потому может адресовать до 4 М слов (до 8 Мбайт) памяти.
Те же соображения относятся к другим командам, адресующим память программ — к паре rcaii и call (а также, с некоторыми нюансами, lpm и eipm). В примерах в этой книге старшие модели семейства Mega мы не будем использовать, и потому ограничимся командами rjmp, lpm и rcaii. Заметим, что в системе команд AVR семейства Mega есть еще команды icaii и ijmp (косвенный вызов и косвенный переход), которые по определению могут адресовать 64 К слов (до 128 кбайт) памяти— для этих команд адрес задается 16-битовым регистром z (о нем см. далее). Однако их употребляют нечасто (только в старших Mega), а в начале программы (в таблице прерываний, см. далее) их вообще указывать нельзя чисто технически (нужно заранее задавать значение z, а до начала программы это сделать невозможно).

Подведем некоторый итог: мы уже узнали многое о структуре типовой программы для AVR: текст должен начинаться с директивы include, ссылающейся на файл с определениями имен для конкретного процессора, далее обычно идут пользовательские определения переменных (директива def) и констант (директива equ), а программа должна начинаться с безусловного перехода на метку RESET. Начало собственно программы будет располагаться сразу после этой метки где-то в другом месте программы. А почему так странно—: нельзя ли начать прямо сразу с нулевого адреса, строка за строкой, зачем нужны какие-то переходы? Можно, отвечают нам авторы описаний AVR. Простейшая программа может начинаться с нулевого адреса, и никаких переходов не потребуется, но только в одном случае: если мы обязываемся отказаться от прерываний. А без них контроллер теряет 90% своей функциональности. Мы позднее попробуем придумать пример программы, которая бы делала что-нибудь полезное, но при этом не использовала прерываний совсем. Но на практике дополнительные прерывания необходимы только тогда, когда штатных прерываний не хватает (например, для отслеживания состояния множества кнопок), или когда они попросту неудобны и без них программа получается компактнее (такие случаи мы еще встретим).



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru