Создадим произвольную таблицу, где каждая строка состоит из 8 ячеек и имеет свой порядковый номер, соответствующий одному регистру. Пусть наша таблица состоит из 128 ячеек или из 16 восьмибитных регистров. В микроконтроллере есть разные функциональные устройства это порты, таймеры, АЦП, устройства ШИМ, устройства последовательного приема и передачи данных, и много еще чего. Кроме этого функции конкретного устройства могут меняться, например, сначала принять информацию, а затем переключиться на передачу. Как же они работают? Все проще, чем кажется! Функции определенного устройства жестко привязывается к конкретным ячейкам памяти. Например, если нам нужно на какую-то ножку подать напряжение, мы устанавливаем конкретную ячейку в 1. Пусть, к примеру, за вывод положительного напряжения на 4 ножку отвечает ячейка 9h:3h. Значит, если мы пропишем в ячейку 9h:3h единицу, то на 4- ой ножке получим положительное напряжение. А как мы узнаем, что эта ячейка отвечает за эту функцию? Ячеек много и запомнить номер каждой ячейки очень сложно.Чтобы было легко работать, производители присвоили каждой строке с определенным порядковым номером, называемым адресом, свое имя, соответствующее устройству. Пусть у нас строка 9h, будет называться регистром PortB, строка 8h регистром PinB, а строка 7h регистром DdrB. Таким образом 7h, 8h, 9h это адреса регистров с названиями PortB, PinB, DdrB. Соответствующие регистры указываются в специальном файле с расширением .inc, в самом начале программы. Этот файл становится доступным с помощью директивы .includeНапример для attiny2313: .include "at2313def.inc"Для вас этот фрагмент статьи недоступен. В Ассемблере версии 2.1.9 директивы начинаются с точки, также как и директивы AVRASM.Директивы не транслируются непосредственно в машинный код. Они используются для указания компилятору положения кода в программной памяти, для инициализации памяти и для других целей..CSEGSIZE размер памяти программУстройства AT94K имеют раздел памяти, которую пользователь может присоединить к памяти программ AVR или памяти данных. Программа и данные SRAM подразделены на три блока: 10K x 16 память программ, 4K x 8 память данных и 6K x 16 или 12K x 8 перестраиваемой SRAM, которые могут быть распределены между программной памятью (до 4-х разделов по 2K x 16) и памятью данных (до 8-ми разделов по 4Kx8). Эта директива используется, чтобы определять размер программного блока памяти. Синтаксис:.CSEGSIZE = 10 | 12 | 14 | 16 Пример:.CSEGSIZE = 12PPPPPP; Определить размер памяти программ как 12K x 16. .DD определяет двойное слово(а) в памяти программ и EEPROM..DQ определяет четверное слово(а) в памяти программ и EEPROM.Эти директивы подобно директиве .DW определяют нужное количест-во слов 32-битных (двойные слова) и 64-битных (четверные слова) соот-ветственно.Синтаксис: МЕТКА: .DD списокPPвыраженийМЕТКА: .DQ списокPPвыраженийПример: .CSEG varlist:PP.DD 0, 0xfadebabe, -2147483648,PP1 << 30.ESEG eevarlst: .DQ 0,0xfadebabedeadbeef, 1 << 62 #define определить макрос препроцессораСинтаксис:1) #define имя [value]2) #define имя(arg.,...) [value]Описание:Определяет макрос препроцессора. Есть две формы макроса: (1) объект, который в основном определяет константу, и (2) функция, в которую делают подстановку параметра. Value величина (значение) может быть любой строкой, она не определена, пока макрос не будет распакован (расширен). Если величина не определена, она = 1.Форма (1) макроса может быть определена из командной строки использованием опции -D.Когда использована форма (2), макрос должен вызываться с тем же количеством аргументов, с которыми он определен. Любые arg. и value будут заменены соответствующими аргументами и значениями, когда макрос расширяется. Отметьте, что левые скобки должны идти сразу после имени (никаких пробелов между ними), в противном случае это будет интерпретировано как часть величины макроса формы (1).Примеры:Обратите внимание на размещение первой скобки '(' в примерах, приведенных ниже.#define EIGHT (1 << 3)#define SQR(X) ((X)*(X)).UNDEF отменить определение символьного имени регистраОписание:Отмена определения имени, которое прежде определялось директивой .DEF или #define. Это позволит избежать сообщений об ошибке при многократном использовании регистра. Если имя прежде не определено, директива .undef будет проигнорирована, это в соответствии со стандартом ANSI C. То же можно сделать из командной строки, используя опцию -U.Синтаксис: .UNDEF символПример: .DEF var1 = R16 ldi var1, 0x20...; сделает что-то с использованием var1..UNDEF var1.DEF var2 = R16; теперь использование R16 не будет вызывать предупреж-дения.#ifdef или .IFDEF директива условной компиляцииСинтаксис:#ifdef имяОписание:Сокращение от #if defined. Все следующие строки до соответствующего
Комментариев нет:
Отправить комментарий