Введение

Использование MPASM для создания перемещаемых объектов

WHILE - Цикл While

5.61.1 Синтаксис

while <expr>

endw

5.61.2 Описание

Выполняется программа между директивами WHILE и ENDW, пока значение <ехрг> истинно. Значение <ехрг> равное нулю рассматривается как ЛОЖЬ. Любое другое значение <ехрг> рассматривается как ИСТИНА. Логическая ИСТИНА гарантирует не нулевой результат выражения, а логическая ЛОЖЬ нулевой результат. Длина цикла не может быть более 100 строк программы. Максимальное число повторов программы внутри цикла 256.

5.61.3 Пример

test_mac macro count

variable i i = 0

while i < count

movlw i i += 1

endw

endm start

test_mac 5

end

5.61.4 См. также ENDW, IF


Начиная с версии MPASM v2.00 и MPLINK v1.00, пользователи имеют возможность выполнять связь объектных модулей для генерации HEX кода программы. Написание исходного текста программы, который будет компилирован в объектный файл, несколько отличается от создания программы с непосредственной компиляцией в HEX файл. Подпрограммы, разработанные для компиляции непосредственно в HEX файл, потребуют незначительных изменений для получения корректного перемещаемого объектного модуля.

6.2 Основные части раздела

Файлы сценария Память программ Операнды инструкций Распределение ОЗУ Биты конфигурации и ID Обращение к меткам других модулей Работа с банками ОЗУ Недопустимые директивы Формирование объектного файла Пример программы

6.3 Файлы сценария

Microchip разработал стандартные файлы сценария (например p17c756.inc), которые должны использоваться при получении объектного кода. Данные файлы определяют параметры и набор регистров специального назначения конкретного микроконтроллера.

6.4 Память программ

Тексту программы должна предшествовать директива CODE, определяющая секцию перемещаемого кода.

6.4.1 Абсолютный код

Start CLRW

OPTION

6.4.2 Перемещаемый код

CODE Start CLRW

OPTION

Если более чем одна секция CODE определена в исходном файле, то каждая секция должна иметь свое уникальное имя. Если имя секции не определено, то данной секции присваивается имя .code.

Каждая секция памяти программ должна быть смежна в пределах исходного текста. Секции нельзя разбивать на части. Физический адрес кода в памяти программ может быть установлен, указав необязательный параметр директивы CODE <ROM address>.

Указание физического адреса может быть необходимо в следующих случаях:

определение вектора прерывания;

для расположения кода программы в пределах страницы памяти программ.

6.4.3 Пример перемещаемого кода

Reset CODE H'OIFF' GOTO Start

Main CODE CLRW OPTION


6.5 Операнды инструкций

Существуют некоторые ограничения по использованию операндов в инструкциях. Операнды в инструкциях должны иметь следующую форму:

[HIGH|LOW|UPPER] (relocatable symbol> + <constant offset>)

Где:

relocatable symbol > - любая метка, которая определяет адрес в памяти программ или данных;

<constant offset> - выражение, которое разрешено и имеющее значение в пределах от-32768 до +32767.

Значение relocatable symbol>или <constant offset>может быть пропущено.

Операнды формы:

<relocatable symbol> - <relocatable symbol>

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

Для обозначения изменяемых битов в выражении используются дополнительные указатели:

LOW - изменяются биты 0-7;

HIGH - изменяются биты 8-15;

UPPER - изменяются биты 16-21.

6.6 Распределение ОЗУ

Распределение ОЗУ должно быть выполнено в секции данных. Существует пять типов секций данных:

UDATA - Неинициализированные данные. Это наиболее общий тип размещения данных. Ячейки, зарезервированные в этой секции, не инициализируются, а обращение к данным производится за счет меток или косвенно.

UDATA_ACS - Неинициализированные данные доступа. Эта секция данных используется для переменных, которые будут помещены в память быстрого доступа микроконтроллеров семейства Р1С18СХХХ. Для обращения к памяти быстрого доступа используются специальные команды.

UDATA_OVR - Неинициализированные временные данные. Используется для переменных, которые могут иметь одинаковый адрес в этом же или других связываемых объектных модулях. Типичное использование данной секции -временные переменные.

UDATA_SHR - Неинициализированные разделяемые данные. Данные этой секции будут размещены в ячейках ОЗУ, которые доступны из всех банков памяти данных.

IDATA - Инициализированные данные. Линкер сформирует таблицу поиска, которая позволит присвоить переменным указанные в этой секции значения. Обращение к данным выполняется только с использованием меток или косвенной адресацией.

В примерах показаны варианты определения переменных.

6.6.1 Абсолютный код

CBLOCK 0х20

inputGain, OutputGain ; Управление циклами HistoryVector ; Должно равняться нулю Tempi, Temp2, ТетрЗ ; Используются в вычислениях

ENDC

6.6.2 Перемещаемый код

IDATA HistoryVector DB О

UDATA InputGain RES I OutputGain RES 1

UDATA_OVR Tempi RES 1 Temp2 RES 1 ТетрЗ RES 1

Адрес инициализации данных в памяти можно установить, указав необязательный параметр <RAM address>. Если в программе используется тип секции данных больше одного раза, то для каждой секции необходимо указать уникальное имя. Если название секции не указано, то им присваиваются имена: .idata, .udata, .udata_acs, .udata_ovr, .udata_shr.

При инициализации данных в секции IDATA директивы DB, DW и DATA могут использоваться для определения данных. DB определяют последовательность байт в памяти. DW и DATA определяют последовательности слов данных (младший байт, старший байт).


В следующем примере показано как будут инициализированы данные:

6.6.3 Перемещаемый код

00001 LIST p=17C44

00002 IDATA 0000 01 02 03 00003 Bytes DB 1,2,3 0003 34 12 78 56 00004 Words DW H'1234',H'5678' 0007 41 42 43 00 00005 String DB "ABC", 0

6.7 Биты конфигурации и ID

Для определения битов конфигурации и ID битов применяйте директивы _ _CONFIG и _ _IDLOCS. Только в одном объектном модуле проекта можно использовать указанные директивы до секции CODE. После использования данных директив текущая секция не определена.

6.8 Обращение к меткам других модулей

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

Модули, использующие эти метки, должны объявить их директивой EXTERN. Пример использования директив GLOBAL и EXTERN.

6.8.1 Подключаемый модуль

UDATA InputGain RES 1 OutputGain RES 1

GLOBAL InputGain, OutputGain

CODE Filter

GLOBAL Filter

6.8.2 Основной модуль

EXTERN InputGain, OutputGain, Filter

UDATA Reading RES 1

CODE

MOVLW GAIN1 MOVWF InputGain MOVLW GAIN2 MOVWF OutputGain MOVF Reading,W CALL Filter

6.9 Работа с банками и страницами памяти

В большинстве случаев используются несколько банков ОЗУ и страниц памяти программ микроконтроллера. При этом необходимо настраивать нужный рабочий банк или страницу памяти программ для обращения к метке. Т.к. при формировании объектного файла предварительно не известно размещение переменных и меток в памяти программ были разработаны две директивы BANKSEL и PAGESEL. Данные директивы указывают линкеру сгенерировать код выбора нужного банка данных или страницы памяти программ.

Примеры использования указанных директив показаны ниже.

6.9.1 Абсолютный код

LIST Р=12С509 ftinclude "P12C509.INC"

Varl EQU H' 10' Var2 EQU H'30'

MOVLW InitialValue

BCF FSR, 5

MOVWF Varl

BSF FSR, 5

MOVWF Var2

BSF STATUS, PAO

CALL Subroutine

Subroutine CLRW ;In Page 1 RETLW 0


6.9.2 Перемещаемый код

LIST P=12C509 ftinclude "P12C509.INC"

UDATA Varl RES 1 Var2 RES 1

CODE

MOVLW InitialValue BANKSEL Varl MOVWF Varl BANKSEL Var2 MOVWF Var2

PAGESEL Subroutine CALL Subroutine

Subroutine CLRW RETLW 0