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

Методическое пособие 491

.pdf
Скачиваний:
3
Добавлен:
30.04.2022
Размер:
1.84 Mб
Скачать

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

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

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

MOVLW

B'01010101'

; Загрузить константу 01010101

 

 

; в регистр WREG

MOVLW

DATAPORT

; Записать содержимое регистра

; WREG в регистр DATAPORT (определенный ранее как порт В)

GOTO

$ ; Бесконечный цикл (вечный; цикл для

; проверки программы в динамическом режиме). Выход только по преры-

ванию.

 

END

; Конец трансляции и окончание

; программы

 

 

3.4. Структура рабочей программы

Рабочая программа для ОMK PIC 16/17 состоит из трех основных секций:

1)секция заголовка;

2)рабочая секция;

3)секция окончания.

В секции заголовка определяются логические имена для всех импользуемых в программе ресурсов: портов, битовых и байтовых переменных, регистров. Это начальная часть исходной программы до строки с выражением ORG 0 (для PIC 16С84). Для других типов микроконтроллеров семейств PIC 16/17 адрес начала следующей секции (сегмента) рабочей программы может быть другим.

29

Рабочая секция программы начинается с выражения ORG 0 (для

PIC 16С84), которое является указателем для Ассемблера о том, что код следующий за этим выражением начинается с нулевого адреса памяти программ. Пример этого фрагмента рабочей программы для

PIC 16С84 приведен ниже:

;Рабочая секция

;Начало исполняемой части рабочей программы

ORG 0H

;Следующая команда будет расположена в памяти программ по

;адресу 0h

GOTO

BEGIN

; Первая команда, которая будет выполнена процессором

ORG 100h

;Следующая команда будет расположена по адресу 100h BEGIN

;Инициализация микроконтроллера

;(Конфигурация портов ввода/вывода, TMRO, WDT и т.п.)

Секция окончания в простейшем случае содержит только псевдокоманду END.

3.5. Пример программы на PIC16C84

Теперь перейдем непосредственно к написанию программы на ассемблере. В качестве примера будет создана и подробно разобрана короткая программа.

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

30

выражением ORG 0), в которой учитываются особенности ее дальнейшего применения. Обычно в секции заголовка определяются логические имена для всех используемых в проекте ресурсов – портов, битовых и байтовых переменных и регистров.

Для того чтобы поставить в соответствие логическому имени,

какое либо числовое значение используется директива определения константы ассемблера EQU. Эту директиву применяют в секции заголовка, она имеет следующий синтаксис: <имя> EQU <значение>.

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

В секции заголовка нашего примера будут заданы значения слов инициализации для портов ввода/вывода. Фактически слово инициализации – это константа при помощи которой мы установим разряды порта на выход.

Ниже приведен пример секции инициализации.

; Секция заголовка

;

; описание операционных регистров

TMR0

EQU

01h

PC

EQU

02h

STATUS

EQU

03h

FSR

EQU

04h

; регистры ввода/вывода

CNTRLPORTEQU

05h

DATAPORT EQU

06h

; ячейки ОЗУ

 

 

SCRATCH

EQU

0Ch

DIGIT

EQU

0Dh

; биты регистра STATUS

31

C

 

EQU

0h

DC

EQU

1h

 

Z

 

EQU

2h

PD

EQU

3h

 

TO

EQU

4h

 

RP

EQU

5h

 

; управляющие регистры

 

TRISA

EQU

85h

 

TRISB

EQU

86h

 

; слова инициализации для портов ввода/вывода

INITA

EQU

B'00000000'

INITB

EQU

B'00000000'

Разберем подробно каждую строку кода. Во-первых, все строки,

начинающиеся со знака ";", воспринимаются ассемблером как комментарии. Перейдем к выражению TMR0. Эта строка дает команду ассемблеру, каждый раз, когда встретится слово TMR0

заменить его на значение 01h (01 шестнадцатеричное). Таким образом, символьному имени TMR0 было присвоено значение 1h. Как видно из табл. 5, регистр TMR0 действительно имеет адрес 1h.

Можно использовать 01h каждый раз, когда есть необходимость адресовать регистр TMR0, но это неудобно, поскольку нужно будете все время помнить, что означает 01h. Кроме того, могут существовать и данные, равные 01h. Использование символьных имен устраняет двусмысленность и позволяет облегчить чтение исходного текста.

В секции заголовка примера также можно видеть выражения для определения регистров PC, STATUS и FSR. Имя PC соответствует регистру с адресом 02h, имя STATUS соответствует регистру с адресом 03h, имя FSR – регистру с адресом 04h и так далее.

Аналогично заданы имена для портов ввода/вывода, CNTRLPORT

(05h) и DATAPORT (06h).

32

Ячейки ОЗУ также могут иметь имена. В примере были выбраны имена "SCRATCH" для ячейки с адресом 0Ch и "DIGIT" для ячейки с адресом 0Dh.

Можно определять имена и потом не использовать их. В этом нет ошибки, работа ассемблера как раз и заключается в проверке текста на соблюдение всех правил.

Можно именовать не только регистры, но и отдельные биты внутри регистров. Обратите внимание на секцию, задающую регистр

STATUS. Символу С присвоено значение 0h, поскольку C или

CARRY, это нулевой бит слова состояния STATUS.

Теперь стало ясно, как описываются регистры, и мы можем перейти к исполняемому коду. Перед тем, как начать исполняемый код, нужно задать директиву ORG, устанавливающую адрес программы.

ORG 0 – это указатель для ассемблера, что код, следующий за этим выражением, начинается с нулевого адреса ПЗУ. Директива

ORG используется для размещения сегментов кода по различным адресам в пределах размеров ПЗУ. Еще одно выражение ORG

находится перед меткой BEGIN, имеющей адрес 100h, как задано выражением ORG 100h.

Исполняемый код должен заканчиваться директивой END,

означающей, что за этой директивой отсутствуют исполняемые команды.

;Рабочая секция

;начало исполняемого кода

ORG 0 GOTO BEGIN

ORG 100h BEGIN

33

; Инициализация порта А

 

BCF

STATUS,RP ; Выбор банка 0

CLRF

CNTRLPORT; Очистить регистр

MOVLW INITA

; Загрузить B'00000000' в регистр WREG

BSF

STATUS,RP ; Выбор банка 1

MOVWF TRISA

; Все разряды порта A установить как выходы

; Инициализация порта В

 

BCF

STATUS,RP ; Выбор банка 0

CLRF

DATAPORT ; Очистить регистр DATAPORT

MOVLW INITB

; Загрузить B'00000000' в регистр WREG

BSF

STATUS,RP ; Выбор банка 1

MOVWF TRISB

; Все разряды порта В установить как выходы

;

 

 

BCF

STATUS,RP ; Выбор банка 0

;

 

 

;Здесь будет расположена основная программа

;

;

END

При включении питания PIC16С84 переходит на адрес 000h.

Первая инструкция, которая будет выполнена процессором, это команда GOTO BEGIN, она передаст управление на адрес 100h и

дальнейшая работа продолжится с этого адреса. BEGIN – это выбираемое пользователем имя метки (метки всегда должны начинаться с первой позиции строки), которое ассемблер использует в качестве адресной ссылки. В процессе работы ассемблер определяет расположение метки BEGIN и запоминает, что если это имя будет встречено еще раз, вместо него будет подставлен адрес метки.

Команды CALL и GOTO используют метки для ссылок в исходном тексте.

Теперь рассмотрим команды, используемые для инициализации

34

портов. Команда MOVLW INITA загружает в рабочий регистр W

значение, присвоенное имени INITA. Это значение задано в заголовке и равно B'00000000', то есть 00h. Символы B' означают, что данные заданы в двоичном формате. Можно было бы написать в этом же месте 0 (десятичный) или 0h (шестнадцатеричный) и получить тот же самый результат. Двоичное представление удобнее использовать в тех случаях, когда предполагается операция с битами в регистре.

Следующая команда MOVWF TRISA загружает значение из рабочего регистра W в регистр управления конфигурацией порта A,

TRISA. Задание нуля в разряде этого регистра определяет, что соответствующий разряд порта A является выходом. В нашем случае все разряды порта A устанавливаются выходами. Обратите внимание,

что порт A имеет только 5 разрядов, и старшие 3 бита значения,

записываемого в регистр TRISA, также имеющего 5 разрядов, не используются. Если бы мы захотели, например, установить младший разряд порта A как вход, мы бы задали в секции описания регистров значение INITA равным B'00000001'. Если по ходу работы программы нам потребуется переопределять назначение отдельных разрядов портов, например, при двунаправленной передаче, то удобнее всего задать все необходимые слова конфигурации в секции описания, как это было сделано для INITA и INITB.

Следующие две команды MOVLW INITB и MOVWF TRISB

определяют конфигурацию порта B. Можно было не писать команду

MOVLW INITB, поскольку в нашем случае INITB также равен 0h.

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

35

этапе оптимизации кода, такие повторы можно удалять.

Команды BCF STATUS,RP и BSF STATUS,RP нужны для переключения между банками памяти. Дело в том, что вся память данных микроконтроллера разбита на два банка. Банку 0

соответствуют адреса 00h..7F, банку 1 -8F..FF. Выбор банка определяется состоянием бита 5 в регистре STATUS. Когда этот бит установлен в 1, выбран банк 1, иначе – банк 0.

В качестве примера напишем простую программу для нее нам хватит всего трех команд:

MOVLW k

MOVWF f

GOTO l

Эти команды уже использовались в заголовке базового кода.

Команда MOVLW загружает байтовый литерал или константу в рабочий регистр WREG. Следующая команда MOVWF пересылает байт из рабочего регистра WREG в заданный регистр f. Команда

GOTO передает управление на адрес l. Следующая программа записывает в рабочий регистр WREG значение 01010101 и затем выдает его содержимое на PortB.

MOVLW

B'01010101'

; загрузить 01010101 в регистр WREG

MOVWF

DATAPORT

;записать WREG в поpт B (DATAPORT)

GOTO

$

;зациклиться навсегда

Директива ассемблера "$" означает текущее значение программного счетчика (PC). Поэтому команда GOTO $ означает переход туда, где мы в данный момент находимся. Такой цикл бесконечен, поскольку не существует способа (кроме прерывания)

выйти из него. Команда GOTO $ часто применяется для остановки кода при отладке.

36

Ниже полностью приведена рассмотренная в качестве примера

программа.

; Пример программы

;Секция заголовка

; описание операционных регистров

TMR0

EQU

01h

PC

EQU

02h

STATUS

EQU

03h

FSR

EQU

04h

; регистры ввода/вывода

 

CNTRLPORTEQU

05h

DATAPORT EQU

06h

; ячейки ОЗУ

 

 

SCRATCH

EQU

0Ch

DIGIT

EQU

0Dh

; биты регистра STATUS

 

C

EQU

0h

DC

EQU

1h

Z

EQU

2h

PD

EQU

3h

TO

EQU

4h

RP

EQU

5h

; управляющие регистры

 

TRISA

EQU

85h

TRISB

EQU

86h

; слова инициализации для портов ввода/вывода

INITA

EQU

B'00000000'

INITB

EQU

B'00000000'

;Рабочая секция

;начало исполняемого кода

ORG 0 GOTO BEGIN

37

ORG

100h

 

BEGIN

 

 

; Инициализация порта А

 

BCF

STATUS,RP

; Выбор банка 0

CLRF

CNTRLPORT ; Очистить регистр

MOVLW INITA

; Загрузить B'00000000' в регистр WREG

BSF

STATUS,RP

; Выбор банка 1

MOVWF TRISA

; Все разряды порта A установить как выходы

; Инициализация порта В

 

BCF

STATUS,RP

; Выбор банка 0

CLRF

DATAPORT

; Очистить регистр DATAPORT

MOVLW INITB

; Загрузить B'00000000' в регистр WREG

BSF

STATUS,RP

; Выбор банка 1

MOVWF TRISB

; Все разряды порта В установить как выходы

BCF

STATUS,RP

; Выбор банка 0

; Основная программа

 

MOVLW B'01010101'

; загрузить 01010101 в регистр WREG

MOVWF DATAPORT

; записать WREG в поpт B (DATAPORT)

GOTO

$

; зациклиться навсегда

;

END

4. МЕТОДИЧЕСКИЕ УКАЗАНИЯ ПО ВЫПОЛНЕНИЮ

ЛАБОРАТОРНОЙ РАБОТЫ

При выполнении лабораторной работы необходимо:

изучить основные команды ассемблера среднего семейства

PICmicro, руководствуясь теоретическим введением;

ознакомиться с организацией регистров общего и специаль-

ного назначения;

создать проект и подключить к нему файл подкачки и проте-

стировать программу приведенную в качестве примера, а затем рас-

38