Разработка устройств на основе цифровых сигнальных процессоров фирмы Analog Devices с использованием Visual DSP++ - Олег Вальпа 12 стр.


Переменные данных и буферов могут быть инициализированы с помощью семиразрядного ASCII кода. Следующий пример инициализирует один четырехразмерный буфер input кодами ASCII для букв A, E, F, Z. ASCII коды размещаются в семи младших разрядах 16-разрядной памяти данных или 24-разрядной памяти программ. Символы необходимо заключать в апострофы.

.INIT input: 'AEFZ'; {Инициализировать буфер символами ASCII}

Специальный синтаксис директивы INIT24, позволяет сохранять 24-х разрядные данные в памяти программ. Это дает возможность получить доступ к младшим 8-и разрядам каждого 24-х разрядного слова памяти программ при инициализации буферов данных или переменных в исходной программе.

Например, эта директива позволяет вычислить 16-разрядный адрес для переменной var:

.INIT var: ^buff + 17;

А следующая директива вычисляет 24-разрядный адрес для этой же переменной:

.INIT24 var: ^buff + 17;

Директива GLOBAL

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

.GLOBAL внутренний_символ 1, внутренний_символ 2,...;

Пример:

.VAR/PM/RAM buff[10]; {Создать буфер buff размерностью

10 элементов}

.GLOBAL buff; {Объявить буфер видимым из других модулей}

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

Директива ENTRY

Директива ENTRY позволяет обращаться к программным меткам в других модулях. Это позволяет использовать метку для вызова подпрограммы или межмодульных переходов. Директива ENTRY имеет формат:

.ENTRY метка 1, метка 2, ...;

Пример:

.ENTRY met; {Делает метку met доступной из других модулей}

С тех пор как метка объявлена директивой ENTRY, другие модули могут обращаться к ней, идентифицируя ее как внешнюю с помощью директивы EXTERNAL.

Директива EXTERNAL

Директива EXTERNAL позволяет программному модулю обращаться к глобальным структурам данных (переменным, буферам и портам) и программным меткам, объявленным в других модулях.

Структура должна быть определена до этого с помощью директивы GLOBAL или ENTRY в тех модулях, где она впервые объявлена. Другие модули должны использовать директиву EXTERNAL для открытия доступа к внешним структурам. Директива имеет формат:

.EXTERNAL структура 1, структура 2, ...;

Пример:

.EXTERNAL met; {Метка находится в другом модуле}

Директива INCLUDE

Директива INCLUDE используется для включения других исходных файлов в файл, предназначенный для ассемблирования. Ассемблер открывает, читает и ассемблирует указанный файл, когда он встречает строку оператора INCLUDE. Ассемблированный код объединяется в выходном файле с расширением obj. Когда ассемблер достигает конца включенного файла, он возвращается в первичный исходный файл и продолжает обработку. Директива INCLUDE имеет следующий формат:

.INCLUDE <имя_файла>;

Если файл, который должен быть включен директивой INCLUDE, находится в текущей директории вместе с программой, в угловых скобках требуется указать только имя файла. Если файл находится в другом каталоге, необходимо указать полный путь к этому каталогу и имя файла (или использовать переменную среды окружения ADII). Например, если файл, который должен быть включен, называется filter.dsp и расположен в директории C:\ADSP2181\PROG2\, тогда директива INCLUDE должна быть задана следующим образом:

.INCLUDE <C:\ADSP2181\PROG2\filter.dsp>;

Это позволит ассемблеру найти файл. Существует и другой способ указания пути к файлу. Так можно указать путь, используя переменную среды окружения ADII с помощью команды:

Set ADII=C:\ADSP2181\PROG2

Данная команда должна записываться в файле autoexec.bat операционной системы или в командном файле для трансляции программы. Установка ADII, равной пути к каталогу, позволит ассемблеру обнаружить файл. В этом случае можно задавать имя файла без указания полного пути. Файл, включенный директивой INCLUDE, может также содержать внутри себя директиву INCLUDE. Вложение файлов директивами INCLUDE ограничивается только размером свободной оперативной памяти.

Директива INCLUDE допускает использовать принцип модульного программирования. Например, во многих случаях она используется, чтобы развить библиотеку подпрограмм или макросов, которые применяются в различных программах. Вместо того чтобы каждый раз переписывать подпрограммы, можно присоединить макробиблиотеку в ассемблерный модуль, воспользовавшись директивой INCLUDE.

Пример:

.INCLUDE <библиотека_макросов>;

Директива MACRO

Директива MACRO создает в программе макрос (набор инструкций). Макрос используется для повторения часто используемых последовательностей инструкций в исходном тексте программы. Передачей аргументов макросу реализуется подобие подпрограммы, которая может быть использована в различных программах. Допускается делать вложение макросов. Макровложения ограничены только размером свободной оперативной памяти. Вложенные макросы должны быть объявлены в определенной последовательности. Первым объявляется внутренний макрос. Внешний макрос объявляется последним. Все константы, используемые в макросах, должны быть объявлены перед объявлением макросов. Макрос определяется двумя директивами. Первая директива имеет формат:

.MACRO имя_макроса (аргумент1, аргумент2, ...);

Завершает макрос директива окончания макроса:

.ENDMACRO;

Каждый оператор внутри макроса может быть инструкцией, директивой или макровключением. Макрос вызывается по своему имени. Чтобы выполнить макрос с именем mac1, необходимо вставить в текст программы команду mac1;. Макровызов не должен содержать дополнительных операторов в строке вызова (т.е. инструкций, директив препроцессора или других макровключений).

Аргументы макроса имеют форму записи:

%n, где n = 0, 1, 2, …, 9;

Следующий пример определяет макрос sum с тремя аргументами:

.MACRO sum(%0, %1, %2);

В коде макроса аргументы маркируются служебными символами %1, %2, %3, и т.д. При вызове макроса служебные символы замещаются величинами аргументов, переданных в макрос. При вызове макроса ему должно быть передано правильное число аргументов. Допустимые передаваемые аргументы и исключения для них приведены в табл. 11.4.

Таблица 11.4 Допустимые передаваемые в макрос аргументы и исключения для них

АргументИсключение
Константа или арифметическое выражениеНет
СимволыMACRO, ENDMACRO, CONST, INCLUDE
^буфер^%n
%буфер%%n

Операторы ^ и % не могут быть использованы с аргументами, замещающими служебные символы в макроопределении. Тем не менее, аргументы, переданные в макрос, могут использовать эти операторы. Например: read_data(^input);

Директива LOCAL

Директива LOCAL задает программные метки, используемые в макросе. Данная директива указывает ассемблеру создавать уникальную версию метки при каждом включении макроса. Это предотвращает ошибку дублирования меток в случае, когда макрос вызывается несколько раз в одном программном модуле. Директива имеет формат записи:

.LOCAL метка1, метка2, ...;

Ассемблер создает уникальные версии меток макроса, добавляя к ним номер. Это можно увидеть в файле листинга с расширением lst. Помните, что для раскрытия макросов в листинге необходимо при запуске программы компилятора asm21 добавить ключ -m.

Ниже приведен простейший пример макроса, позволяющий вставить в любое место программы несколько пустых команд пор.

.MACRO nops;

nop; nop; nop; nop; nop; nop;

.ENDMACRO;

Вызов данного макроса в программе осуществляется командой nops;. Следующий пример показывает, как создать макрос wait с одним параметром и одной локальной меткой.

MACRO wait(%0);

local loop;

cntr=%0;

do loop until ce;

loop: nop;

ENDMACRO;

Этот макрос позволяет организовать в программе функцию задержки на 100 циклов лаконичной записью:

wait(100);

Естественно, что вместо числа 100 можно вписывать любое число в разрешенном диапазоне для счетчика циклов.

Ниже приведен пример макроса, реализующий подпрограмму, которая переносит содержимое буфера данных из одной области памяти в другую.

.MACRO mem_trans (%0, %1, %2, %3, %4) {Использует 5 аргументов}

.LOCAL trans;

I4=%0; {Установить I4 как адрес источника}

I5=%1; {Установить I5 как адрес приемника}

M4=1 {Установить указатель на инкремент 1}

CNTR=%2 {Установить длину буфера}

DO trans UNTIL СЕ; {Перенос данных}

si=%3(I4, M4) {Перенос данных из типа %3 памяти}

trans: %4(I5, M4)=si; {В тип %4 памяти}

.ENDMACRO

Пример вызова этого макроса в программе может быть таким:

mem_trans (^tabl_coef, ^buf, %buf, PM, DM);

Здесь в качестве аргументов в макрос передаются адреса буферов tabl_coef и but, длина буфера but и тип памяти. Заметьте, что зарезервированные ключевые слова PM и DM переданы как аргументы.

Несколько следующих директив определяют формат файла листинга. Файл листинга с расширением lst позволяет представить результаты процесса ассемблирования. Ниже показан пример файла листинга простейшей программы. В этом файле используются следующие информационные поля:

addr - смещение от базового адреса модуля;

inst - код операции;

source line - номер строки исходного файла и код.

Release 5.11 Assembler Version 1.34s 9/19/95

D:\TEMA\IKS\PROG\TEST.DSP\DOS.dsp Mon Jun 21 17:07:36 2004 Page 1

addr inst source line

1 .module/RAM/ABS=0 example;

2 .PAGEWIDTH 70;

3 {Описание переменных}

4 .var/dm flag;

5

6 {Инициализация переменных}

7 .init flag: 0x000f;

8

9 again:

0000 02010F 10 toggle FL1; /* Инвертировать флаг */

0001 18000Fu 11 jump again; /* Зациклить */

12 .endmod;

Каждая строка в листинге этой программы имеет свой номер. При обнаружении ошибки в какой-либо строке программы компилятор выдает именно этот номер строки. Символ "u" в поле inst показывает, что код операции содержит адрес перехода.

Существует пять директив ассемблера для формирования выходного файла листинга.

Директива NEWPAGE

Директива NEWPAGE вставляет разделители страниц. После такой директивы листинг программы продолжится с новой страницы. Данная директива, как и последующие, применяется для выделения программных фрагментов и оформления листинга программы. Пример ее использования:

.NEWPAGE;

Директива PAGELENTH

Директива PAGELENTH регулярно вставляет разделитель страниц после указанного количества строк. Формат ее записи:

.PAGELENGTH число_строк;

Директива LEFTMARGIN

Директива LEFTMARGIN оставляет левое поле с указанным числом столбцов (знакомест символов). Формат ее записи:

.LEFTMARGIN число_столбцов;

Директива INDENT

Директива INDENT осуществляет отступ строк программы в исходном коде с указанным числом столбцов. Формат ее записи:

.INDENT число_столбцов;

Директива PAGEWIDTH

Директива PAGEWIDTH определяет ширину строк листинга с указанным числом столбцов. Формат ее записи:

.PAGEWIDTH число_столбцов;

Директивы NEWPAGE и PAGELENGTH могут быть использованы для нумерации страниц, в то время как директивы LEFTMARGIN, INDENT и PAGEWIDTH используются для того, чтобы сделать каждую страницу удобной для чтения. Эти директивы могут быть помещены в любом месте исходного файла.

Директива ENDMOD

Директива ENDMOD указывает на завершение программного модуля. Программа ассемблера останавливается, когда достигает директивы ENDMOD. Формат ее записи:

.ENDMOD;

Глава 12. Форматы данных

В этой главе говорится о форматах представления данных в сигнальном процессоре при выполнении вычислительных операций.

Сигнальные процессоры используются в основном для цифровой обработки сигналов. Поэтому в программах для них часто используются арифметические команды для математической обработки чисел. Поскольку все данные в процессоре представлены в двоичном формате, в нем используется двоичная арифметика. Для лучшего понимания операций, выполняемых над числами в двоичной арифметике, необходимо хорошо представлять форматы данных этих чисел и приемы, используемые в двоичной арифметике.

С форматом представления данных в процессоре тесно связаны такие понятия, как целочисленная и плавающая арифметика. Другими словами, арифметические операции, выполняемые процессором, могут производиться с целыми или с вещественными числами. Известно, что вещественные числа имеют целую и дробную части, отделяемые друг от друга запятой. Если запятая не меняет своего положения в формате представления чисел при выполнении арифметических операций, говорят, что данные представлены в формате с фиксированной запятой. Например: 7,4×0,5=3,7. Здесь положение запятой фиксировано как для операндов, так и для результата. Недостатком такого представления является небольшой диапазон обрабатываемых чисел, определяемый количеством разрядов шины данных. Другим форматом представления данных может служить формат с плавающей запятой, где используется показатель степени. Например: 1,8×10:2,0×10=9,0×10. Здесь существенно расширяется диапазон обрабатываемых чисел за счет введения показателя степени, но снижается точность результата.

Аппаратное обеспечение процессоров семейства ADSP-21XX поддерживает 16-разрядные данные с фиксированной точкой. Тем не менее, вычислительные устройства этих процессоров обладают особыми характеристиками, которые позволяют работать с другими форматами за счет соответствующего использования программных средств. Позже будет показано, как с помощью программных средств можно реализовать операции с блоками чисел в формате с плавающей точкой.

Вспомним форматы представления данных в двоичной арифметике. Формат представления двоичного числа обычно включает в себя знак, запятую и величину. Знак показывает, является число положительным или отрицательным. Запятая отделяет целую и дробную части числа.

Знак двоичного числа может быть представлен одним битом. Как правило, ноль указывает на положительное значение числа, а единица на отрицательное его значение. Знаковый бит обычно крайний левый бит (старший бит).

Как известно, в двоичной арифметике операция вычитания заменяется сложением чисел, представленных в дополнительном коде. Положительные числа не требуется переводить в дополнительный код. Отрицательные числа в дополнительном коде изменяют свою запись.

Существует несколько форматов представления отрицательных чисел в дополнительном коде. Наиболее распространенным методом является дополнение до двух, который используется в семействе процессоров ADSP-21XX.

Назад Дальше