Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПСМПС (лаб)

.pdf
Скачиваний:
21
Добавлен:
10.06.2015
Размер:
1 Мб
Скачать
☆

81

Команда безусловного перехода с индексной адресацией позволяет изменять адрес перехода в соответствии с содержимым накопителя:

jmp @A+DPTR

Инструкции вызова подпрограмм или безусловного перехода с возвратом не используют короткую адресацию:

acall <addr11> lcall <addr16>

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

Для корректного возврата к вызывающей программе последней выполняемой командой подпрограммы должна быть инструкция RET (return).

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

Другая команда, работающая точно таким же образом, RETI (return from interrupt) – применяется для возврата к подпрограмме, выполнявшейся в момент аппаратного прерывания.

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

jz <rel>

;

переход

–

если

нуль

jnz <rel>

;

переход

–

если

не нуль

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

 

 

 

 

82

jс <rel>

;

переход

–

если перенос

jnс <rel>

;

переход

–

если отсутствует перенос

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

jb <flag>, <rel>

;

переход

–

если

бит

установлен

jnb <flag>, <rel>

;

переход

–

если

бит

сброшен

Команда передачи управления по равенству бита единице имеет вариант с последующей очисткой содержимого этого бита:

jbс <flag>, <rel> ; переход – если бит

; установлен и его сброс

Есть инструкции, которые сами осуществляют вычисления для получения условий передачи управления. Первая из этих инструкций − это команда CJNE (compare and jump if not equal). Это единственная команда контроллера, имеющая 3 операнда. Ее четыре разновидности отличаются способами адресации источника и приемника:

cjne A, <src>, <rel> cjne A, #<src>, <rel> cjne R<n>, #<src>, <rel cjne @R<i>, #<src>, <rel>

Команда вычисляет разность первого и второго операндов, но результат вычитания никуда не записывается, за исключением бита переноса. Передача управления по указанному адресу осуществляется при неравенстве операндов. При сравнении положительных чисел бит переноса устанавливается в 1, если первый операнд меньше второго. Если по адресу перехода записать команду передачи управления по содержимому бита переноса, то в результате одного сравнения можно выполнить три разные блока программы. Другая команда – DJNZ (decrement and jump if not zero) уменьшает содержимое первого операнда на единицу. Если операнд не равен 0, то управление передается по указанному адресу:

djnz R<n>, <rel>

83

djnz <dst>, <rel>

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

2.5. Общие представления об интегрированной среде разработки

Keil µVision2

Интегрированная среда разработки Keil µVision2® является программной платформой для разработчика встраиваемых приложений (embedding application) для микроконтроллеров семейств MCS-51/251. Эта среда разработки объединяет в себе такие развитые инструментальные средства, как редактор кода, менеджер проектов, компиляторы и компоновщики. Среда µVision2 поддерживает все необходимые инструменты от Keil Software для микроконтроллера MCS-51, включая Си-компилятор, высокоразвитый макроассемблер (A251/51), компоновщик, конвертор объектных файлов в файлы «прошивок» и другие многочисленные вспомогательные средства. Среда µVision2 позволяет существенно ускорить процесс разработки встраиваемых приложений, обеспечивая разработчика следующими свойствами:

•полнофункциональный редактор кода с подсветкой синтаксиса;

•интегрированный отладчик уровня исходного кода с высокоскоростными возможностями симуляции ЦПУ и периферийных устройств микроконтроллера;

•база данных микроконтроллеров для конфигурирования симулятора

иотладчика;

•менеджер проектов для создания и поддержки проекта;

•интегрированные средства сборки проекта для ассемблирования, компиляции и компоновки встраиваемых приложений;

•развитая диалоговая система для настройки инструментов среды разработки;

•развитый графический интерфейс пользователя.

Главное окно интегрированной среды разработки µVision2 (рис. 5.3) предоставляет разработчику наряду с главным меню (1) также палитру инструментов (2) для быстрого выбора команд, дочерние окна с редактором кода для редактирования исходных файлов (3), диалоговые окна и оконные информационные дисплеи такие, как менеджер проектов (4), диалоговые окна

84

периферийных устройств (5) и симуляторов (6), окно вывода сообщений (7), карта памяти (8), окно контроля за переменными (9). µVision2 позволяет одновременно открывать и просматривать все исходные файлы проекта используя многодокументный интерфейс.

1

2

5

4

5

3

2

 

6

7

9

8

Рис. 5.3 Внешний вид главного окна среды µVision2

2.6. Основные положения ассемблера A251/51

Для управления процессом компиляции, резервирования и инициализации данных, определения символьных имен, а также задания положения кода и данных в адресном пространстве ассемблер А251/51 имеет специальные управляющие, не транслируемые инструкции, называемые директивами. Директивы не нужно путать с инструкциями. Они не преобразуются в исполняемый код. Директивы призваны управлять состоянием компилятора и результирующим объектным файлом. В общем случае все директивы можно разделить на директивы сегментации, директивы определения символов пользователя, инициализации и резервирования памяти, директивы опреде-

85

ления процедур, управления сборкой модулей, управления счетчиком команд.

2.6.1. Представления о сегментации в ассемблере A251/51. Понятие адресного счетчика

Сегмент является блоком памяти с кодом иди данными, которые создаются компилятором ассемблера из кода и данных исходного ассемблерного файла. В отличие от архитектуры микропроцессоров х86, которые поддерживают сегментацию как внутренний базовый механизм адресации, микроконтроллер MCS-51 использует плоскую память, отдельную для команд и данных. Поэтому сегментация не является внутренним механизмом архитектуры, а только лишь способом логического разделения данных, команд, стека в исходном тексте программы, который поддерживается самим компилятором ассемблера А251/51.

Каждый сегмент программы соответствует определенной области памяти: внутренней памяти программ, памяти данных или внешней памяти. Такие сегменты называются логическими.

Ассемблер А251/51 поддерживает счетчик адресов для каждого такого логического сегмента. Счетчик адреса является указателем на адресное пространство активного сегмента и представляет собой смещение для общего сегмента (generic segment) или действительный адрес для абсолютного сегмента (absolute segment). При активизации сегмента счетчик адреса устанавливается в 0. Адресный счетчик изменяется после каждой инструкции на ее длину. Директивы инициализации и резервирования памяти (DS, DB, DW) также изменяют значение адресного счетчика при размещении данных. Основной директивой, управляющей адресным счетчиком, является директива ORG, которая устанавливает новое значение для адресного счетчика. При изменении активного сегмента и после возврата к предыдущему сегменту, адресный счетчик восстанавливает свое предыдущее значение.

Знак валюты $ указывает на значение текущего адресного счетчика в активном сегменте. При использовании символа $ его значение изменяется только после полного выполнения инструкции.

В ассемблере A251/51 различаются два вида сегментов: общие перемещаемые сегменты и абсолютные фиксированные сегменты.

Общие сегменты имеют имя и класс, а также другие атрибуты. Общие сегменты с одинаковыми именами, но находящиеся в различных объектных модулях, объединяются как части одного сегмента и называются частичны-

86

ми сегментами. Объединение этих сегментов происходит по время сборки объектных модулей компоновщиком.

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

<segment> SEGMENT <class> [<reloctype>] [<alloctype>]

Класс <class> сегмента определяет его принадлежность к определенному виду памяти. Этот параметр может иметь следующие значения: BIT (битовое пространство данных 20h … 2Fh), CODE (память программ), DATA (память данных и регистры специальных функций 0…7Fh), IDATA (стек). Для микроконтроллера MCS-251 определены дополнительные классы памяти. Тип настройки адресов <reloctype> определяет возможности перенастройки адресов компоновщиков во время сборки объектных модулей. Параметр размещения <alloctype> задает выравнивание сегмента.

Например:

MYSEG SEGMENT CODE AT 0000h

Эта директива определяет, но не создает кодовый сегмент с именем MYSEG, который начинается с адреса 0000h. Это означает, что данные в этом сегменте будут размещены в области памяти программ, т.е. в ПЗУ. Таким образом, определенный однажды сегмент должен быть после этого выделен (создан) с помощью директивы RSEG:

RSEG MYSEG

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

В архитектуре микроконтроллеров MCS-51 и MCS-251 используется аппаратно-управляемый стек для сохранения адресов возврата в инструкциях CALL, а также для временного хранения данных в инструкциях PUSH и POP. Приложения MCS-51, которые используют эти инструкции, должны устанавливать указатель стека на область памяти, не используемую другими переменными. Для микроконтроллера MCS-51сегмент стека должен определяться и резервироваться следующим образом:

87

STACK SEGMENT IDATA

. . .

 

 

RSEG STACK

 

 

DS

10h

; выделяем в стеке 16 байт

При инициализации контроллера, в подпрограмме обработки прерывания аппаратного сброса необходимо настроить указатель стека на соответствующую область памяти еще до его первого использования:

CSEG AT 0

; вектор инициализации

jmp STARTUP

;

переход к подпрограмме инициализации

. . . .

 

 

STARTUP:

;

код выполняющийся при инициализации

mov SP,#stack - 1 ;загрузка указателя стека

В свою очередь, абсолютные сегменты размещаются по фиксированным адресам памяти, и настройка их начальных адресов производится не компилятором, а непосредственно при программировании. Абсолютные сегменты создаются с использованием директив CSEG, DSEG, XSEG, ISEG, и BSEG. Эти директивы позволяют разместить код, данные или зарезервировать пространство памяти, зафиксировав их месторасположение в адресном пространстве. Абсолютные сегменты используются при необходимости доступа к фиксированным адресам памяти или если необходимо разместить данные по определенным адресам.

После аппаратного сброса MCS-51 начинает выполнение программы с инструкции, расположенной по адресу 0000h. В то же время микроконтроллер MCS-251 имеет стартовый адрес FF0000h. По этим адресам должны находится подпрограммы инициализации контроллеров.

2.6.2. Директивы символьного определения

Директивы данной группы позволяют создавать символьные имена, которые могут быть использованы для представления регистров, числовых констант и адресов памяти. Директивы EQU и SET назначают именам числовые значения или значение регистра. Символьные имена, заданные директивой EQU, не могут быть переназначены позднее. Напротив, директива SET по-

88

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

<symbol> EQU <expression> <symbol> EQU <register> <symbol> SET <expression> <symbol> SET <register>

Здесь <symbol> – имя, а <expression> – выражение, определяющее значение этого символьного имени, <register> – значение регистра, которое будет ассоциироваться с этим именем.

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

Ниже приведены примеры использования этих директив:

LIMIT EQU 1200

VALUE EQU LIMIT – 200 + 'A'

SERIAL EQU SBUF

ACCU EQU A

COUNT EQU R5

VALUE SET 100

VALUE SET VALUE / 2

COUNTER SET R1

TEMP SET COUNTER

TEMP SET VALUE * VALUE

Наряду с директивами символьного определения EQU и SET в ассемблере А251/51 имеются директивы адресного определения CODE, BIT, DATA, IDATA и XDATA. Они имеют следующий формат:

<symbol> BIT <bit_address> <symbol> CODE code_address> <symbol> DATA data_address> <symbol> IDATA idata_address> <symbol> XDATA xdata_address>

Например:

DATA_SEG SEGMENT BITADDRESSABLE

 

89

RSEG DATA_SEG

; побитово адресуемый сегмент

CTRL: DS 1

; однобайтная переменная

ALARM BIT CTRL.0

; нулевой бит в переменной

SHUT BIT ALARM+1

; следующий бит

ENABLE_FLAG BIT 60H

; абсолютно адресуемый бит

DONE_FLAG BIT 24H.2

; абсолютно адресуемый бит

P1_BIT2 EQU 90H.2

; бит SFR регистра

RESTART CODE 00H

 

INTVEC_0 CODE RESTART + 3

INTVEC_1 CODE RESTART + 0BH

INTVEC_2 CODE RESTART + 1BH

SERBUF DATA SBUF

; переопределение SBUF

RESULT DATA 40H

 

RESULT2 DATA RESULT + 2

 

PORT1 DATA 90H

; символ SFR

BUFFER IDATA 60H

 

BUF_LEN EQU 20H

 

BUF_END IDATA BUFFER + BUF_LEN – 1

XSEG1 SEGMENT XDATA

 

RSEG XSEG1

 

DTIM: DS 6

; резервируем 6 байт для DTIM

TIME XDATA DTIM + 0

 

DATE XDATA DTIM + 3

 

2.6.3. Директивы инициализации и резервирования памяти

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

Директива DB назначает начальное значение байту памяти. Директива имеет следующий формат:

<label>: DB <expression> , <expression> …

Здесь <label> – имя начального адреса инициируемой памяти, а <expression> – значения байтов, которые могут быть заданы с помощью чисел, символов или выражений. Директивы DW и DD инициализируют память в виде слов и двойных слов. Данные директивы могут располагаться только в сегменте кода или сегменте констант.

90

Директивы резервирования в отличие от директив инициализации памяти необходимы для резервирования ячеек (битовых, байтных и пословных) памяти, в которых могут размещаться изменяемые данные программы. К таким директивам относятся директивы DBIT и DS.

Директива DBIT резервирует бит памяти в битовом (BIT) сегменте или битовом сегменте внешней памяти (EBIT). Директива имеет следующий формат:

<label>: DBIT <expression>

Здесь <label> – имя начального адреса, а <expression> – число резервируемых битов.

ON_FLAG: DBIT 1 ; резервируем один бит

OFF_FLAG: DBIT 1

Аналогично директива DS используется для резервирования байтов памяти в сегментах данных или стека. Например:

GAP: DS (($ + 16) AND 0FFF0H) – $

DS 20

TIME: DS 8 ; резервируем 8 байт

2.6.4. Директивы связывания модулей

Эти директивы позволяют осуществлять раздельную компиляцию модулей и их последующую сборку посредством указания ссылок на имена внешних модулей. К таким директивам относятся директивы PUBLIC и EXTERN.

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

PUBLIC <symbol> , <symbol> …

В качестве параметров эта директива получает в качестве параметров имена экспортируемых символов, таких, как символьные имена, определенные в директивах подстановки, имена процедур, переменных, за исключением имен сегментов и регистров. Например: