Смекни!
smekni.com

Микропроцессорная система управления предназначенная для использования на лесопильном заводе (стр. 4 из 6)

Листинг 5: тест фотоэлементов

; – – – проверка двух младших битов порта ФЭЛ на 0

TST_FEL IN A, (#0B) ; прочесть слово статуса ФЭЛ

AND 3 ; наложить на него маску 000000112

LD E, 3 ;

JP NZ, E_ROM ; если не ноль, то ошибка

… ; иначе продолжаем тесты

Инициализация программируемого контроллера прерываний

Для инициализации контроллера надо переслать ему два управляющих слова ICW1 и ICW2, первое по адресу 0CН (A0=0), второе – по адресу 0DН (A0=1).

Пересылаются следующие управляющие слова:

Рис. 6 Применяемые управляющие слова инициализации ПКП

Слово ICW1 установит одиночный (без каскадного соединения) режим работы ПКП (бит 1), 4-хбайтный интервал для начальных адресов обработчиков прерываний (бит 2).

Биты 5–7 слова ICW1 вместе со всем словом ICW2 сообщат контроллеру, что первый обработчик (запроса IR0) начинается с адреса 0020Н.

Контроллер накладывает определенные ограничения на расположение обработчиков в памяти. Первое из них в том, подпрограммы обработки прерываний должны располагаться по порядку, начиная с адреса обработчика запроса IR0, и с постоянным интервалом, т.е. образовывать в памяти таблицу. Интервал расположения может составлять 4 байта (если бит 2 ICW1 равен единице, как в нашем случае), или 8 байт (если бит 2 равен нулю). При постоянном интервале адреса всех обработчиков определятся расположением первого (IR0).

Адрес первого обработчика составляется из полного слова ICW2 (старший байт) и битов 7,6,5 слова ICW1 (старшие три бита младшего байта адреса).

В нашем случае старший байт равен 00Н, младший байт равен 0010 0000 = 20Н. Обработчики имеют начальные адреса: 0020H, 0024H, 0028H, 002CH, 0030H, 0034H (6 обработчиков).

Процедура INI_PIC инициализирует контроллер.

Листинг 6: инициализация программируемого контроллера прерываний

; – – – переслать 38H в порт 0CH и 0 в порт 0DH

INI_PIC LD A, #38 ;

OUT (#0C), A ;

XORA ;

OUT (#0D), A ;

Инициализация переменных системы

В системе за некоторыми ячейками памяти закреплена функция хранения переменных. Например, подсчитанный суммарный объем древесины VS в двоичном формате хранится в отдельных двух байтах памяти с адресами V_SUM, V_SUM+1.

Требуют инициализации только две переменные (инициализируются нулем):

VS (2 байта) – начальный адрес V_SUM;

Время (4 байта) – начальный адрес TIME.

Ясно, что эти имена (V_SUM и TIME) лишь условные обозначения (также, как, например, имена меток в листингах программ). При переводе в машинный код эти имена транслируются в двухбайтный адрес.

Листинг 7: инициализация ячеек суммарного объема и времени

; – – – начальное обнуление объема и времени

INI_VARXORA ;

LD (V_SUM), A ;

LD (V_SUM+1), A ;

LD (V_SUM+2), A ;

LD (TIME), A ;

LD (TIME+1), A ;

LD (TIME+2), A ;

LD (TIME+3), A ;

… ; следует продолжение переходит к основному циклу работы (описание см. в п.4.4).


Арифметические подпрограммы

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

Основным форматом чисел в МП системе является двухбайтный формат с фиксированной точкой вида 1байт , 1байт . Формат беззнаковый, предполагается, что числа положительны. Одно число умещается в одной регистровой паре. Минимальное представимое число – 0,01H=1/256=3,9×10-3, максимальное – FF,FFН=256,996.

Общие правила для всех вычислительных процедур:

- программист вызывающей программы сам следит, чтобы операнды и результат не выходили за пределы представления и чтобы при вычитании не образовалось отрицательных величин;

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

Сложение

В микропроцессоре Z80 есть команда сложения регистровых пар ADD HL, DE. Однако, чтобы сохранить единообразие, оформим ее все же как подпрограмму.

Листинг 8: подпрограмма PLUS

; – – – подпрограмма сложения

; HL+DE®HL

; сохраняет A, BC, DE

PLUS ADD HL, DE ;

RET ;

Вычитание

В Z80 есть команда вычитания регистровых пар с учетом переноса SBC HL, DE. Используем ее в подпрограмме вычитания, обнулив прежде флаг CY.

Листинг 9: подпрограмма MINUS

; – – – подпрограмма сложения

; HL–DE®HL

; сохраняет A, BC, DE

MINUS OR A ; A не меняется, но флаг CY=0

SBCHL, DE ;

RET ;

Умножение

При умножении первый множитель хранится в паре BC (скопируем его туда из HL в начале), второй множитель хранится в DE. Результат первоначально получается в четырехбайтном виде HL.DE, затем “обрезается” до H.L.

Результат произведения накапливается в HLDE. В течение 16 циклов сдвигов HLDE второй множитель DE постепенно выдвигаясь, уходит вправо и на его место приходит из HL готовые биты произведения. Они получаются при суммировании первого множителя (BC) и левой половины накопленной суммы HLDE (HL). Суммирование делается в случае, если перед этим при сдвиге HLDE вправо из DE был выдвинут единичный бит.

Листинг 10: подпрограмма MUL

; – – – подпрограмма умножения

; HL´DE®HL

; все регистры меняются

MUL LD B, H ; BC=1-й множитель

LD C, L ;

LD HL, 0 ; HL=0

LD A, 16 ; счетчикцикла

MUL2 SRL H ; сдвиг 0®HLDE®CY

RRL ;

RRD ;

RR E ;

JR NC, MUL1 ; если выдвинут 0, то на конец цикла

ADD HL, BC ; если выдвинута 1, то сложить

MUL1 DEC A ;

JR NZ, MUL2 ;

LD H, L ; получено произведение HL.DE

LD L, D ; которое “обрезаем” до L.D и переносим в H.L

RET

Деление

При делении делимое хранится в HL, делитель в DE. Результат получается в виде трех байт [стек.L] (где “стек” – содержимое вершины стека), в конце программы младший байт стека переносится в H и окончательный результат имеет формат H.L. Регистровая пара BC в начале обнуляется.

Деление производится в течение 24-х циклов. В каждом цикле делается сдвиг BC¬HL¬0, т.е. делимое HL выдвигается влево в пару BC. Затем BC сравнивается с DE (путем вычитания BC–DE и проверки флага переноса). Если BC>DE, то младший разряд HL устанавливается единицей, в противном случае он остается нулем. Это один из разрядов частного.

После 16 сдвигов в делимое HL полностью сдвинется влево и на его место придет частное целочисленного деления, в BC будет остаток деления, DE сохранит делитель. На этом этапе целая часть частного в HL заносится в стек, а HL обнуляется. В оставшихся 8-ми сдвигах BC¬HL в BC будут сдвигаться только нули. После всех 24-х циклов в регистре L будет дробная часть частного, а в стеке целая часть.

Листинг 11: подпрограмма DIV

; – – – подпрограмма деления

; HL/DE®HL

; сохраняет DE, использует стек (2 байта)

DIVLDBC, 0 ;

LD A, 24 ; А – счетчик циклов

DIV4 PUSH AF ; сохранить счетчик А в стеке

ADD HL, HL ; BC¬HL¬0

RL C ;

RL B ;


LD A, C ;

SUB E ;

LD C, A ;

LD A, B ;

SBC D ;

LD B, A ;

JR NC, DIV1 ; если BC>DE, топереход

LD A, C ;

ADD E ;

LD C, A ;

LD A, B ;

ADC D ;

LD B, A ;

JR DIV2 ;

DIV1 INC HL ; если BC>DE: установить последний бит

; частного в 1

DIV2 POP AF ; извлечь счетчик А из стека

CP #09 ; проверить, 16-й цикл идет или нет

JRNZ, DIV3 ;

PUSH HL ; если 16-й цикл, то в HL целая часть частного,

; сохранить ее в стеке, чтобы извлечь

; в конце программы

LD HL, 0 ;

DIV3 DECA ;

JR NZ, DIV4 ; конец цикла

POP BC ; извлекаем из стека целую часть частного

LD H, C ; получаем частное в H.L

RET ;

Косинус

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

, угол a изменяется от 0 до p/2. (6)

Эта формула дает косинус с максимальной погрешностью 8,9×10-4, это меньше, чем ошибка разрядности используемого формата [1].[1] дробных чисел.

(7)

Представление (7) формулы (6) гораздо удобнее для вычисления косинуса программно. Достаточно сделать процедуру для вычисления

, где n – целое число, b – дробное число. Перед обращением к этой процедуре (названной COS_A) операнды содержатся:

HL = a2;

DE = b;

BC = n в формате n.0 (B=n, C=0).

Результат – в HL

Эта подпрограмма использует предыдущие арифметические программы.

Листинг 12: подпрограмма COS_A

; – – – вспомогательная подпрограмма для косинуса

; операнды: HL, DE, BC

; изменяются все регистры

COS_A PUSH BC ; сохранить в стеке n перед вызовом MUL

CALL MUL ; HL=HL´DE

POP DE ; DE=n

CALL DIV ; HL=HL/DE

LD D, 1 ; DE=1.0

LD E, 0 ;

EX HL, DE ;

CALL MINUS ; HL=HL-DE

RET ;

Подпрограмма косинуса вычисляет косинус угла в паре HL.

Листинг 13: подпрограмма COS

; – – –подпрограмма косинуса

; операнд и результат в HL

; изменяются все регистры

COS LD D, H ;

LD E, L ;

CALL MUL ; HL=a2

PUSH HL ; a2встеке

LD D, 1 ; DE=1.0

LD E, 0 ;

LD B, #1E ; BC=1E.0H=30

LD C, 0 ;

CALL COS_A ; HL=1-a2/30

EX HL, DE ;

POP HL ; HL=a2

PUSH HL ; a2встеке

LD B, #0C ; BC=C.0H=12

LD C, 0 ;

CALL COS_A ; HL=1-a2/12(1-a2/30)

EX HL, DE ;

POP HL ; HL=a2

LD B, #02 ; BC=2.0

LD C, 0 ;

CALL COS_A ; HL=1-a2/2[1-a2/12(1-a2/30)]

RET ;


Преобразование двоичный®двоично-десятичный код

В управляющей программе надо переводить двухбайтные числа формата [12].[34] в двоично-десятичный код вида [123.45] размером в пять тетрад для последующего перевода в семисегментный код и индикации.

Для этого нужны две отдельных подпрограммы: одна (по имени B2D) для перевода целой части числа [12] и вторая (имя B2D_F) для перевода дробной части числа [34].