Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Директивы языка программирования ASM-51Содержание книги
Поиск на нашем сайте
Любой ассемблер всегда включает в себя команды микроконтроллера, но ими не ограничивается набор операторов этого языка программирования. Дело в том, что нужно уметь управлять самим процессом трансляции программы. Первое, чем приходится по необходимости заниматься, если в программе используются только команды микроконтроллера — это вручную распределять память данных микроконтроллера. При таком распределении приходится помнить, какой вид данных находятся в каждой конкретной ячейке памяти и указывать значение адреса памяти в качестве операнда команд. При необходимости изменить местоположение данных в ячейках памяти приходится просматривать всю программу и изменять соответствующие команды. При чтении программы трудно отличить константы от переменных, ведь в командах они отличаются только видом адресации. Это приводит к увеличению времени написания программы, так как каждый раз приходится решать загадку: что же подразумевалось под конкретной цифрой — переменная, константа или маска? Преодолеть эту трудность можно при помощи идентификаторов. Можно назначить какой-либо ячейке памяти идентификатор и работать с ним, как с переменной. Более того! При необходимости изменить адрес переменной в памяти данных можно просто изменить значение идентификатора, а не просматривать всю программу, каждый раз решая, является ли найденное число адресом переменной, маской или константой! Директива equ позволяет назначать имена для констант и значения адресов для переменных. При использовании этой директивы можно назначить идентификатору переменной адрес в одном месте программы и пользоваться идентификатором этой переменной во всей программе. Правда за использование идентификатора именно в качестве переменной отвечает программист. Если он попытается использовать адрес переменной как константу, то транслятор не выдаст никакого сообщения об ошибке. Он спокойно оттранслирует оператор. При использовании назначения адресов переменных при помощи директивы equ, изменение адреса при необходимости можно сделать в одном месте программы, а не просматривать всю программу, судорожно пытаясь вспомнить, где же еще была использована эта ячейка памяти. Все необходимые изменения в машинном коде программы сделает сам транслятор! Пример назначения имен переменных с использованием директивы equ приведен в листинге 23.4. Листинг 23.4. Назначение имен констант и адресов переменных при помощи директивы equ FuncSet equ 0x20 _8bit equ 0x10
DispDat equ P0;Шина данных ЖКИ RDS equ P1_2;Чтение команды ЖКИ RW equ P1_1;Сигнал выбора записи/чтения E equ P1_0;Строб синхронизации ЖКИ
mov DispDat,#(FuncSet or _8bit);Выставить на шине данных setb E;команду установки функции clr E;и выдать стробирующий сигнал Как видно из приведенного примера, использование идентификаторов значительно повышает наглядность программы, так как в них отражается назначение соответствующих констант и переменных. При помощи директивы equ можно назначать не только переменные, но и константы. Как уже говорилось ранее, будет ли использован идентификатор как переменная или как константа зависит от команд и видов адресации, которые использует программист. И даже если адрес переменной и константа будут обладать одинаковым числовым значением, то лучше им назначить разные имена. В приведенном в листинге 23.4 примере имена FuncSet и _8bit являются константами, но это становится понятным только по использованию непосредственной адресации в команде mov. Один раз назначенный при помощи директивы equ идентификатор уже не может быть изменен, и при повторной попытке назначения точно такого же имени идентификатора транслятором будет выдано сообщение об ошибке. Директива set. Если требуется в различных местах программы назначать одному и тому же идентификатору различные значения, то нужно пользоваться директивой set. Она используется точно так же, как директива equ, поэтому иллюстрировать это примером не будем. Константы, назначаемые директивами equ или set, могут быть использованы только в качестве операндов команд микроконтроллера. В то же время достаточно часто требуется работа с таблицей констант, такой, как таблица перекодировки, таблицы элементарных функций или синдромы помехоустойчивых кодов. Такие константы используются не на этапе трансляции для формирования машинного кода инструкций, а при исполнении программы. Они заносятся в память программ микроконтроллера. Для помещения значений констант в память программ микроконтроллера используются директивы db и dw. Директива db используется для занесения в память программ однобайтных констант. Пример использования директивы db приведен в листинге 23.5. Листинг 23.5. Создание таблицы констант при помощи директивы db Decod: mov DPTR,#TabDecod movc A,@A+DPTR ret
TabDecod:;-abcdefg DB 01111110b;символ ‘0’ Расположение сегментов в DB 00110000b;символ ‘1’ семисегментном индикаторе DB 01101101b;символ ‘2’ a DB 01111001b;символ ‘3’ --- DB 00110011b;символ ‘4’ f| |b DB 01011011b;символ ‘5’ --- DB 01011111b;символ ‘6’ e| |c DB 01110000b;символ ‘7’ --- DB 01111111b;символ ‘8’ d DB 01111011b;символ ‘9’ В этом примере использована подпрограмма-функция, перекодирующая двоично-десятичное число в семисегментный код при помощи таблицы TabDecod. В эту функцию двоично-десятичный код передается через аккумулятор и через этот же регистр в вызывающую программу возвращается семисегментный код. В директиве db можно задавать сразу несколько констант, разделенных запятыми. Можно одновременно использовать все системы счисления, но обычно имеет смысл снабдить каждую константу комментарием, как это сделано в предыдущем примере. Так программа становится более понятной и ее легче отлаживать. Эта же директива позволяет легко размещать в памяти строки, которые в дальнейшем потребуется высвечивать на встроенном дисплее или экране дисплея универсального компьютера, подключенного к разрабатываемому устройству через какой либо интерфейс. Пример использования директивы db для занесения строк в память программ микроконтроллера приведен а листинге 23.6. Листинг 23.6. Применение директивы db для размещения строк в памяти программ микроконтроллера mov R7,#(EndNadp-NadpSvjazUst);Занести количество символов в строке mov DPTR,#NadpSvjazUst;Подготовиться к передаче первого символа
PrdSledSmv: clr A; movc A,@A+DPTR;Считать очередной символ надписи inc DPTR;
call PrdSmv;Передать очередной символ надписи и djnz R7,PrdSledSmv;если это был последний символ надписи ret;то выйти из подпрограммы
NadpSvjazUst: db ‘Связь установлена’,10,13 EndNadp: Директива dw позволяет заносить в память программ двухбайтные числа. В ней, как и в директиве db, можно записывать несколько чисел, разделенных запятой. Пример фрагмента программы приведен в листинге 23.7. Листинг 23.7. Применение директивы dw 0016 0001 264 dw 1,2,0abh,'a','QW' 0018 0002 001A 00AB 001C 0061 001E 5157 В листинге 23.7 фрагмент программы приведен для того, чтобы можно было проследить, какие байты заносятся в память программ микроконтроллера. В самой правой колонке листинга приведены адреса, в которые будут занесены числа, являющиеся операндами директивы dw. В следующей колонке приведены двухбайтовые числа, которые будут заноситься в память программ микроконтроллера. Обратите внимание: несмотря на то, что первые два операнда директивы dw состоят только из одной цифры, в память микроконтроллера заносятся четыре шестнадцатеричных цифры (двухбайтовое число). При трансляции исходного текста программ по умолчанию предполагается, что первая команда расположена по нулевому адресу. Адрес последующих команд зависит от длины и количества предыдущих команд. Пример начального участка программы приведен в листинге 23.8. Листинг. 23.8. Начальный участок программы LOC OBJ LINE SOURCE
0000 78FF 1 mov R0,#255;Обнулить 255 ячеек памяти 0002 E4 2 clr A 0003 3 ClrOZU: 0003 F6 4 mov @R0,A;Обнулить очередную ячейку памяти 0004 D8FD 5 djnz R0,ClrOZU;Если все ячейки обнулены 6;то продолжить выполнение программы Иногда нужно расположить команду по определенному адресу. Наиболее часто это требуется при использовании прерываний, когда первая команда подпрограммы-обработчика прерываний должна быть расположена точно в ячейке с определенным адресом (вектором), зависящем от источника прерывания. Векторы размещаются в начальных ячейках программной памяти и занимают 8 байтов каждый. Если эта область не используется целиком, то можно использовать команду nop для заполнения промежутков между векторами прерывания. Но лучше для назначения нужных адресов подпрограммам прерываний воспользоваться директивой org. Директива org предназначена для записи в счетчик адреса сегмента значения своего операнда. То есть при помощи этой директивы можно разместить команду (или данные) в памяти микроконтроллера по произвольному адресу. Пример использования директивы org для размещения подпрограмм обработки прерываний в нужных адресах показан в листинге 23.9. Листинг 23.9. Пример использования директивы org reset: ljmp main
;Перезагрузка таймера----------------------------------------- ORG AT 0bh;Вектор прерывания от таймера 0 IntT0: mov TL0, #LOW(-(F_ZQ/12)*10-2);Настроить таймер mov TH0, #HIGH(-(F_ZQ/12)*10-2);на период 10мс reti
;Начало основной программы микроконтроллера ------------------------- rseg _code main: mov SP,#VershSteka;Настроить указатель стека на вершину стека lcall init;Настроить микроконтроллер ;-------------------------------------------------------------------- Необходимо отметить, что при использовании этой директивы возможна ситуация, когда программист приказывает транслятору разместить новый код программы в уже занятом участке памяти, поэтому использование этой директивы допустимо только в крайних случаях. Обычно это размещение подпрограмм прерываний. Директива using. При использовании прерываний критичным является время выполнения подпрограммы-обработчика прерываний. Его можно значительно сократить, выделив для обработки прерываний отдельный банк регистров при помощи директивы using. Номер используемого банка регистров указывается в директиве в качестве операнда. При этом реальное включение банка регистров производится записью необходимой константы в регистр PSW. Пример использования директивы using для подпрограммы обслуживания прерываний от таймера 0 приведен в листинге 23.10. Листинг 23.10. Пример использования директивы using USING 2;Использовать второй банк регистров IntT0: push PSW;Сохранить содержимое слова состояния микроконтроллера push ACC;Сохранить содержимое аккумулятора mov PSW,#00010000B;Включить второй банк регистров
mov TL0, #LOW(-(F_ZQ/12)*10-2);Настроить таймер mov TH0, #HIGH(-(F_ZQ/12)*10-2);на период 10мс pop ACC;Восстановить содержимое аккумулятора pop PSW;Восстановить содержимое слова состояния микроконтроллера reti Остальные директивы ассемблера предназначены для управления сегментами памяти и будут рассмотрены позднее. УПРАВЛЯЮЩИЕ КОМАНДЫ Кроме директив, для управления процессом трансляции используются команды языка программирования. С их помощью можно управлять работой компилятора ASM-51. Команды могут задаваться как параметры в DOS-строке вызова компилятора, или как управляющие строки в исходном тексте файла. Если знак доллара ($) стоит в самом крайнем левом поле строки, то такая строка воспринимается компилятором как управляющая. Управляющие строки должны начинаться знаком доллара и могут содержать одну или более команд, разделенных пробелами. Примеры управляющих строк: $PRINT(A:\PROG.LST) OBJECT(PROG.OBJ) $LIST DEBUG XREF Так как целью книги является дать минимальные сведения, достаточные для того, чтобы начать работать с микроконтроллерами, то в данной книге будут рассмотрены только основные команды языка программирования ASM-51. Команда include. Это, пожалуй, наиболее часто используемая команда языка программирования ASM‑51. Она позволяет включать в состав программы участки текста из другого файла. Это удобно при многофайловом написании программы, например, для того, чтобы вынести описания внутренних регистров микроконтроллера в отдельный файл. Пример использования команды include для включения файла описания внутренних регистров микроконтроллера 89с51 выглядит следующим образом: $INCLUDE (REG51.INC) При использовании этой команды все содержимое включаемого файла помещается в выходной листинг программы, в результате чего становится трудно читать этот листинг. Поэтому в состав команд языка программирования ASM‑51 включены команды list/nolist. Команды list/nolist позволяют включать и выключать листинг исходного текста соответственно. При активной команде nolist в файл листинга будут помещаться только сообщения об ошибках. Пример запрета размещения содержимого включаемого файла в листинге программы будет выглядеть следующим образом: $NOLIST //Запретить создание листинга включаемого файла $INCLUDE (REG51.INC) $LIST //Разрешить создание листинга дальнейшего текста Команда debug/nodebug позволяет помещать в объектный модуль отладочную информацию (имена и местоположение переменных, меток и операторов) или запрещать размещение отладочной информации в объектном модуле. Команда pagelength(n) определяет максимальное число строк на странице файла листинга. Это число включает заголовок страницы. Количество строк в странице может изменяться в пределах от 10 до 65535 Команда pagewidth(n) определяет максимальное число символов в строке листинга. Количество символов в строке листинга может изменяться от 72 до 132.
|
||||
Последнее изменение этой страницы: 2017-02-07; просмотров: 410; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.124.204 (0.008 с.) |