Микропроцессорная система замера и индикации температуры на индикаторе

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    75,43 Кб
  • Опубликовано:
    2012-09-30
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Микропроцессорная система замера и индикации температуры на индикаторе

Введение

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

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

В данной работе решается определенная задача с использованием однокристальной ЭВМ МК51, получившей широкое распространение. Это 8-ми битное устройство, содержащее 4 программируемых порта ввода-вывода, 2 таймера/счетчика, поддерживающее обмен по последовательному каналу (RS232), с возможностью подключения внешней памяти программ и данных.

В данной курсовой работе была реализована микропроцессорная система замера и индикации температуры на индикаторе. Для получения данных о температуре был использован датчик с ШИМ - сигналом на выходе. Данные с этого датчика обрабатываются программой микроконтроллера, преобразуются в необходимый формат и выводятся на индикацию. Одновременно идет проверка на вхождение текущей температуры в предложенный задании диапазон. В случае выхода температуры за его пределы начинается генерация звукового сигнала определенной частоты. Также проверяется факт прихода данных с датчика. Для этого измеряется промежуток времени с момента последнего поступления данных и если он превышает определенное значение, то контроллер решает, что датчик вышел из строя и также делает предупреждение об этом.

Описание программы

В данной курсовой работе необходимо обеспечить вывод текущего значения температуры на индикацию. Для реализации этого задания, необходимо иметь устройство, сообщающее о текущей температуре в том или ином месте. В качестве такого устройства выбран датчик температуры TMP03, который выдает ШИМ сигнал, временные параметры которого позволяют судить о температуре.

И по соотношению T1 и T2, определяют значение измеряемой температуры.

В документации по данному датчику для выполнения последнего действия предлагается следующая формула:


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

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

Такой принцип и реализован в данной работе. Ниже приведены блок-схемы алгоритмов работы обработчиков прерываний INT1 и INT0 (рис. 1).

Описание алгоритма обработчиков прерываний

Запуск таймера производится при приходу импульса (INT0), с этого момента начинается измерение длины импульса. После запуска таймера в обработчике INT0 устанавливается специальный флаг начала измерения. Далее, когда импульс кончается, вызывается INT1, в начале которого анализируется флаг начала измерения (begread). И в случае, если измерение началось таймер останавливается на короткое время, в течении которого данные из его регистров пересылаются в специальные ячейки памяти. После этого таймер снова запускается. Эта приостановка необходима по той причине, что во время чтение, которое осуществляется побайтно в регистре может возникнуть переполнение младшего байта и он обнулится, зато увеличится старший байт и если допустим прочитать сначала младший байт, который близок к переполнению, а затем старший байт, то естественно старший байт будет уже больше, чем нужно и прочитанные данные неверны. Прочитанное в INT1 содержимое регистров таймера представляет собой длительность импульса. Далее снова приходит прерывание INT0. В начале его обработчика также анализируется флаг начала измерения и если он не установлен программа начинает последнее, а иначе -заканчивает. Для этого останавливается таймер и из его регистров читается временной интервал который представляет из себя суммарную длительность импульса и паузы.

Далее вычитая из этой длительности длительность импульса легко найти длительность паузы (T2). Одновременно по окончании тракта измерения устанавливается флаг готовности данных, который ожидается в основной программе для начала обработки.

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

Описание основной программы

Основная программа (рис. 2) начинается со стандартных процедур инициализации флагов, используемых в программе (fready, begread, errtemp). Также настраиваются прерывания. Внешние прерывания устанавливаются по фронту и получают наивысший приоритет для повышения точности измерения температуры.

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

После установления этого флага начинается обработка пришедших данных, но сначала он сбрасывается для организации следующего цикла ожидания. Далее вызывается процедура вычисления температуры по выше приведенной формуле (она (процедура) будет рассмотрена несколько ниже). Абсолютное значение температуры, вычисленное данной процедурой возвращается в аккумуляторе, а знак температуры можно узнать анализируя специализированный флаг знака pos, который устанавливается если знак температуры положительный. На следующем этапе проверяется вхождение текущей температуры в предложенный в задании промежуток. Для этого вызывается специализированная процедура testlimit, которая осуществляет данную операцию.

Внутри этой процедуры может сбросится или установится флаг errtemp, который и предупреждает о выходе температуры за заданные пределы. Последствия этого события будут выяснены позже

Далее абсолютное значение температуры, записанное в аккумуляторе необходимо перевести в BCD-код. Для реализации этой операции воспользуемся командой деления с остатком и разделим acc на 10. В результате в аккумуляторе окажется число десятков, а остаток будет представлять собой число единиц делимого (в данном случае подразумевается, что число двухзначное). Далее:

·   меняются тетрады в acc и в старшей тетраде оказываются десятки производится операция “ИЛИ” аккумулятора с остатком и в результате в acc оказывается абсолютное значение температуры в BCD-коде. Этот BCD-код на следующем этапе преобразуется в код семисегментного индикатора. Этот процесс производится по специальной таблице кодов, записанной в ПЗУ. В данном случае это инверсные коды, поскольку светодиоды индикатора будут управляться нулем.

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

Динамическая индикация

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

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

В самом начале обработчика происходит проверка исправности датчика. Для этого используется ранее упоминаемая переменная control. Она содержит количество интервалов по 10ms (период возникновения переполнения таймера) прошедших с момента последнего прихода данных. Если содержимое этой переменной достигает 50, то возникает подозрение, что с датчиком случилось несчастье и выставляется флаг аварии датчика, в данном случае это пользовательский флаг 0V и в специальную область памяти для индикации загружаются коды слова “ERR”, которое с этого момента и выводится на индикатор свидетельствуя об аварии.

В случае, если данные приходят нормально производится вывод численного значения температуры. За один раз выводится один разряд.

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

Индикация начинается с процесса записи управляющего слова в P1(напр. 11011111).

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

На следующем шаге программа переходит в блок генерации звуковых сигналов. В начале проверяется наличие флага аварии датчика и если он есть производится переход на генерацию меандра 1000Гц. В случае если аварии не произошло проверяется флаг выхода температуры за пределы Errtemp, который ранее упоминался и если он установлен производится переход, на генерацию меандра 500Гц, т.е. инверсия бита в порту производится через раз, для этого используется специальный флаг delaybit, который инвертируется при каждом возникновении прерывания, а инверсия бита в порту производится только в случае его единичного значения. Далее в конце проверяется промежуток времени который прошел с момента начала генерации (переменная soundgen), если это время равно 5 с., то происходит запрещение генерации на 5 мин., которые тоже контролируются с помощью этой переменной.

Описание процедуры вычисления температуры

Температура вычисляется по следующей формуле:


Входящие в нее переменные были упомянуты ранее.

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

T1 и T2-временные интервалы импульса и паузы. Поскольку таймер модифицируется один раз в машинный цикл, то эти величины составляют порядка нескольких тысяч, а величина T2, всегда или практически всегда больше T1. Поэтому если начать расчет с операции деления, то велика вероятность, что мы получим нулевой результат и какой-то остаток, что недопустимо, поэтому сначала реализуется операция умножения 400*T1, а уже потом полученное число делится на T2. Применение деления с остатком не позволяет выводить температуру с большой точностью и поэтому погрешность при данном методе составляет около 1oC. Нетрудно догадаться, что после умножения T1 на 400 (двухбайтного числа на двухбайтное) ответ явно будем превышать двухбайтные числа, что требует наличия трехбайтной арифметики.

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

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

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

Описание процедуры проверки пределов

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

Алгоритм процедуры достаточно прост:

1. сбрасывается флаг ошибки.

2. Определяется знак температуры (флаг pos) и в зависимости от него в регистр B загружается либо отрицательный, либо положительный предел температуры.

3. Регистр Acc, в котором записана текущая температура сравнивается с B, и если последний оказывается больше, то это говорит о нормальных температурных условиях и происходит выход из подпрограммы, и естественно флаг ошибки остается обнуленным. В противном случае устанавливается флаг ошибки и начинается генерация меандра. Это реализуется, как ранее объяснялось обработчиком от таймера T1.

Описание процедур арифметических операций

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

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

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

Процедура сложения трехбайтных чисел

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

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

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

Ниже продемонстрирован фрагмент этой процедуры.

;Предварительная очистка флага CcR7,#3 ;число байт в числе

;Сложение числа побайтно с использованием флага переноса

ADD:a,@R0a,@R1@R0,aR0R1

djnz r7,ADD

Процедура вычитания трехбайтных чисел

Данная процедура реализуется по тому же принципу, что и сложение, т.е. с использованием флага переноса, только вместо команды сложения фигурирует команда SUBB-вычитание с заемом.

;Предварительное обнуление флага переноса clr c mov r7,#3  ;Реализация вычитания SUB: mov a,@R0 subb a,@R1 mov @R0,a  inc r0 inc r1 djnz r7,SUB

Процедуры сдвига (RRC_3B, RLC_3B)

Это однотипные процедуры, реализация которых осуществляется уже имеющимися командами сдвига микропроцессора RRC и RLC. Сдвиг также осуществляется в цикле.

Первым обрабатывается: при сдвиге влево - младший байт, при сдвиге вправо -старший байт и далее через флаг переноса биты переходят от байта к байту.

Пример реализации сдвига влево представлен ниже.

;Сдвиг числа побайтно от старшего к младшему mov r7,#3 RR: mov a,@r0 rrc a  mov @r0,a dec r0 djnz r7,RR

Процедура умножения (MUL_3B)

Рассмотрим основной принцип реализации команды умножения.


X-множимое

Y-множитель

В более развернутой форме Y выглядит следующим образом:



С учетом этого произведение можно представить в следующем виде:


Анализируя данное выражение можно увидеть алгоритм.

-частичное произведение.

Нетрудно понять, что оно может равняться либо 0, либо X, на этом свойстве и основан данный принцип умножения.

Операция умножения реализуется в цикле:

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

1. Сдвиг множимого влево.

Текст процедуры написан в листинге.

Блок-схема алгоритма умножения

Процедура реализации операции деления DIV_3B

Данная процедура также имеет циклический алгоритм (рис. 7).

Рис 8. Принципиальная схема

Принципиальная схема микропроцессорной системы представлена на рис. 8.

Здесь использован индикатор BA/BC56 - 1 с общим анодом. Минимальный ток свечения составляет порядка 5мА. Управление сегментами индикатора осуществляется нулем, подаваемым от буферного усилителя , на вход которого поступают сигналы от контроллера. Особенностью серии 1554 являются достаточно большие выходные токи, высокое быстродействие, малую потребляемую мощность, что позволяет микросхемы этой серии подключать к светодиодным индикаторам. Ниже приведены некоторые статические параметры элементов этой серии:

U1H=3.15В

U1L=1.35В

U0H=3.86В

U0L=0.3В

Iвх=0.1мкА

I0L=86мА

I1L=75мА

Инвертор, применяемый в схеме также взят из данной серии (К1554ЛН1 Icc=4мкА).

Транзисторы VT2, VT3, VT4 служат ключами при динамической индикации при подаче нулевого уровня на из затвор они открываются и подключают питание к соответствующему разряду индикатора. В данном случае выбраны низко пороговые элементы КП402А (c каналом p - типа).

Uпор=0.8В

Uси=200В

Uзи=200В

IC=150мА

P=800мВт

T=-60..+70oC

На следующем этапе рассчитаем значение сопротивления ограничивающих резисторов.

Через сегмент индикатора будем пропускать ток 7мА.

(C2 - 14 0.25Вт 383Ом)

Транзистор VT1 служит усилителем звуковых сигналов, поступающих с выхода процессора. Нагрузка в данном случае полагается равной 4Ом.

Для реализации этой задачи выбран биполярный составной транзистор 2N6038.

UКЭ нас=0.8В

UК=60В

IК=4А

P=40Вт

T=+200oC

f=4МГц

Рассчитаем ток коллектора в открытом режиме при нагрузке 4Ом.


Далее рассчитаем ток базы этого транзистора способный вывести его в режим насыщения.


Примем этот ток равным 600мкА, для увеличения коэффициента насыщения.

Рассчитаем сопротивление базового резистора.

 (С2 - 14 0.25Вт 383Ом )

Ниже приведен перечень применяемых элементов.

Поз. Обознач.

Наименование.

Кол.

Примечания.


Резисторы.



R1

C2 -14 0.125Вт 8870Ом1



R2 - R22

C2 -14 0.125Вт 8870Ом21




Микросхемы.



DD1

TMP03

1


DD2

К1554ЛН1

1


DD3

AT89C51 - 24AC

1


DD4


1


HG1

BA/BC56 - 1

1



Транзисторы.



VT1

2N6038

1


VT2 - VT4

КП402А

3



Конденсаторы.



C1,C2


2


C3


1


ZQ1


1



Листинг программы

May 8 2012 11:24 Page 1 2500 A.D. 8051 Macro Assembler - Version 4.02a Input Filename : E:\ASM51\KURS\KURS.ASM Output Filename : KURS.obj 1 0077

notsound: equ 119 ;флаг перерыва 5 мин. в генерации звука 2 0078

fready: equ 120 ;флаг готовности результата 3 0079

begread: equ 121 ;флаг начала чтения данных с датчика 4 007A

pos: equ 122 ;знак температуры 5 007B

inden: equ 123 ;разрешение динамической индикации  6 007C

errtemp: equ 124 ;разрешение генерации звука при выходе температуры за 7

;заданные границы  8

9 F830

indfreq: equ -2000 ;частота индикации (1 маш. цикл 0.5uS) 10 0000

 11 0040

ph: equ 40h 12 0041

pl: equ 41h 13 0000

 14 0042

ih: equ 42h 15 0043

il: equ 43h 16 0000

 17 0044

indicat: equ 44h ;информация, выводимая на индикацию (3 байта) 18 0047

rcount: equ 47h ;указатель активного разряда при индикации  19 0048

soundgenl: equ 48h ;переменная для хранения промежутка времени 20 0049

soundgenh: equ 49h ;в течение которого генерируется звук 21 0000

 22 0050

Temper: equ 50h ;текущее значение температуры 23 0000

 24 0052

pulse: equ 52h ;длина импульса (3 байта) 25 0055

pause: equ 55h ;длина паузы (3 байта) 26 0058

mem: equ 58h  27 0061

control: equ 61h ;контрольное время в интервалах по 10mS, 28

;которое прошло с момента последнего прихода данных с датчика. 29

;Если данное число превышает 250 (250mS), то это говорит о том, 30

;что с датчиком произошло несчастье (напр. нарушение соединения  31

;с контроллером или выход из строя самого датчика)  32 0000

 33 0062

minutes: equ 62h ;счетчик минут в перерыве генерации звука 34 0032

tempmax: equ 50 ;максимальное положительное значение температуры 35 0028

tempmin: equ 40 ;минимальное отрицательное значение температуры 36 0000

 37 0000 80 2E

sjmp start  38 0002

 39

;Обработчик INT0 (импульс) 40 0003

org 0003h 41 0003 02 00 C9

jmp int_0 42 0006

 43

;Обработчик INT1 (пауза) 44 0013

org 0013h 45 0013 02 00 EE

jmp int_1 46 0016

 47 001B

org 001bh 48 001B 02 00 FF

jmp dynind ;динамическая индикация 49 001E

 50 0030

org 30h 51 0030

 52

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

start: 54

;Настройка таймера 55 0030 75 89 11

mov tmod,#00010001b ;T0-режим 01 T1-режим 01 56 0033

 57

;Загрузка таймера динамической индикации 58 0033 75 8D F8

mov th1,#>indfreq 59 0036 75 8B 30

mov tl1,#<indfreq 60 0039

 61

;Разрешение прерываний 62 0039 75 A8 8D

mov ie,#10001101b ;разрешить int0,int1 и T1 63 003C 43 88 05

orl tcon,#00000101b ;внешние прерывания по фронту 64 003F

 65

;Расстановка приоритетов 66 003F 75 B8 05

mov ip,#00000101b ;INT1 и INT2-наивысшие приоритеты 67 0042

 68

;Инициализация флагов и переменных  69 0042 C2 78

clr fready ;инициализация флага готовности 70 0044 C2 79

clr begread ;инициализация флага начала чтения 71 0046 C2 7C

clr errtemp ;генерация сигнала запрещена 72 0048 C2 77

clr notsound 73 004A

 74 004A 75 61 00

mov control,#0 75 004D 75 47 44

mov rcount,#indicat ;указатель на данные для индикации 76 0050 90 03 4E

mov dptr,#seg7ind ;адрес массива кодов индикатора 77 0053

 78

;Обнуление временных счетчиков 79 0053 75 48 00

mov soundgenl,#0 80 0056 75 49 00

mov soundgenh,#0 81 0059 75 62 00

mov minutes,#0 82 005C

 83 005C 75 90 EF

mov p1,#11101111b ;инициализация порта, управляющего включением 84

;определенных разрядов индикатора  85 005F

 86

;Запуск таймера динамической индикации 87 005F D2 8E

setb tr1 88 0061

 89 0061

waitnew: 90 0061 D2 7B

setb inden ;динамическая индикация разрешена 91

92 0063 30 78 FD

jnb fready,$ ;ожидание новых данных с датчика 93 0066 C2 78

clr fready ;сброс флага готовности до следующего раза 94 0068

 95

;Определение длины паузы 96

;ih,il-длина импульса 97

;ph,pl-длина импульса+длина паузы 98 0068

 99

;Перепишем в первую очередь данные из спец ячеек в регистры, чтобы не 100

;потерять их (данные) 101 0068 AC 42

mov r4,ih 102 006A AD 43

mov r5,il 103 006C AE 40

mov r6,ph 104 006E AF 41

mov r7,pl 105 0070

 106

;Найдем длину паузы 107 0070 C3

clr c  108 0071

 109 0071 ED

mov a,r5 110 0072 9F

subb a,r7 111 0073 FF

mov r7,a 112 0074

 113 0074 EE

mov a,r6 114 0075 9C

subb a,r4 115 0076 FE

mov r6,a ;r6,r7-длина паузы 116

117

;Пересылка длины импульса и паузы в специальные трехбайтные переменные 118 0077 78 52

mov r0,#pulse 119 0079 ED

mov a,r5 120 007A F6

mov @r0,a 121 007B 08

inc r0 122 007C EC

mov a,r4 123 007D F6

mov @r0,a 124 007E 08

inc r0 125 007F 76 00

mov @r0,#0 126 0081

 127 0081 78 55

mov r0,#pause 128 0083 EF

mov a,r7 129 0084 F6

mov @r0,a 130 0085 08

inc r0 131 0086 EE

mov a,r6 132 0087 F6

mov @r0,a 133 0088 08

inc r0 134 0089 76 00

mov @r0,#0 135

136

;Подсчитаем численное значение температуры 137 008B 12 01 AD

call Calc_Temp  138 008E F5 50

mov Temper,a 139 0090

 140 0090 12 02 27

call testlimit ;проверить вхождение текущего значения температуры 141

;в заданные пределы 142 0093

 143

;Перевод десятичного числа в BCD-код  144 0093 75 F0 0A

mov b,#10 145 0096 84

div ab 146 0097 C4

swap a 147 0098 45 F0

orl a,b 148 009A

 149

;Переведем BCD-число в код семисегментного индикатора 150 009A

seg7code: 151 009A 78 44

mov r0,#indicat ;адрес переменной для динамической индикации 152 009C

 153

;Для дальнейшего использования сохраним в стеке температуру в BCD-коде 154 009C C0 E0

push acc 155

156 009E 54 0F

anl a,#00001111b 157 00A0

 158

;Приостановим динамическую индикацию 159 00A0 C2 7B

clr inden 160 00A2

 161

;Выборка из массива кода, по смещению соотв. кодируемому числу  162 00A2 93

movc a,@a+dptr 163 00A3 F6

mov @r0,a 164 00A4 08

inc r0 ;младший разряд 165 00A5

 166

;Кодируем таким же образом старший разряд 167 00A5 D0 E0

pop acc 168 00A7 54 F0

anl a,#11110000b 169 00A9 C4

swap a  170 00AA

 171

;Поскольку это старший разряд числа, то имеет смысл гашение нуля 172 00AA B4 00 04

cjne a,#0,notguish 173 00AD 74 FF

mov a,#ffh ;гашение разряда 174 00AF 80 01

sjmp outind 175 00B1

 176

;Разряд не нулевой - гашение не нужно 177 00B1

notguish: 178 00B1 93

movc a,@a+dptr 179 00B2

 180 00B2

outind: 181 00B2 F6

mov @r0,a 182

;Выведем знак числа 184 00B3

 185

;Подготовим байт для знакового разряда 186 00B3 A2 7A

mov c,pos  187 00B5 75 F0 FF

mov b,#ffh  188 00B8 92 F6

mov b.6,c ;(диод G)  189 00BA

 190

;Имеется трехразрядный индикатор(общий анод, активный-0) 191 00BA

 192

;Если старший разряд числа погашен, то знак выводится в него, иначе... 193 00BA B4 FF 07

cjne a,#ffh,notnull 194 00BD

 195 00BD A6 F0

mov @r0,b ;вывод знака в старший разряд (2-й слева)  196 00BF

 197

;Погасим самый старший разряд 198 00BF 08

inc r0 199 00C0 76 FF

mov @r0,#ffh 200 00C2 01 61

jmp waitnew  201 00C4

 202

;Разряд не нулевой 203 00C4

notnull:  204 00C4 08

inc r0 205 00C5 A6 F0

mov @r0,b ;(диод G)  206 00C7 01 61

jmp waitnew 207 00C9

 208 00C9

 209

; 210

;INT0-вызывается по приходу импульса 211 00C9

int_0: 212 00C9 20 79 0A

jb begread,rpause 213 00CC

 214 00CC 75 61 00

mov control,#0 215 00CF D2 8C

setb tr0 ;запуск таймера 216 00D1 D2 79

setb begread ;установка флага начала нового процесса тения 217 00D3 C2 78

clr fready ;данные не готовы 218 00D5 32

reti 219 00D6

 220

;Чтение данных о общей длине (импульс+пауза) 221 00D6

rpause: 222 00D6 C2 8C

clr tr0 ;останов таймера 223 00D8 85 8C 40

mov ph,th0 224 00DB 85 8A 41

mov pl,tl0 225 00DE

 226

;Обнуление таймера 227 00DE 75 8C 00

mov th0,#0 228 00E1 75 8A 00

mov tl0,#0 229 00E4

 230 00E4 C2 79

clr begread ;ожидание нового импульса для начала измерения 231 00E6 D2 78

setb fready ;данные прочитаны  232 00E8 75 61 00

mov control,#0 ;обнулен контрольный счетчик времени задержки прихода 233

;данных 234 00EB C2 D2

clr f0 ;данные пришли-следовательно датчик исправен 235 00ED 32

reti 236

; 237 00EE

 238

239

; 240

;INT1-вызывается при наступлении паузы 241 00EE

int_1: 242 00EE 30 79 0D

jnb begread,end_I1 243 00F1

 244

;Сохранение данных о длине импульса 245 00F1 C2 8C

clr tr0  246 00F3 85 8C 42

mov ih,th0 247 00F6 85 8A 43

mov il,tl0 248 00F9 D2 8C

setb tr0 ;дальнейший подсчет 249 00FB 75 61 00

mov control,#0 250 00FE

 251 00FE

end_I1: 252 00FE 32

reti 253

; 254 00FF

 255

256

; 257

;DYNIND-прерывание от T1 для динамической индикации и выдачи сигналов 258 00FF

dynind: 259 00FF C0 E0

push acc 260

;Сохранение флага переноса 261 0101 65 E0

xrl a,a 262 0103 13

rrc a 263 0104 C0 E0

push acc 264 0106 C0 01

push 1 265

266 0108 05 61

inc control ;прошел еще один интервал 10mS с момента последнего 267

;прихода данных с датчика 268 010A E5 61

mov a,control 269 010C

 270

;Проверка исправности датчика 271

;Датчик считается неисправным, если данные с него не поступают 500mS 272

273

;Если флаг уже установлен, то дальнейший контроль является бесмысленным 274 010C 20 D2 19

jb f0,display 275 010F B4 FA 16

cjne a,#250,display 276

;Авария датчика (данные подозрительно долго не приходят) 277 0112 D2 D2

setb f0 ;установка флага неисправности датчика 278 0114

 279

;Загрузка слова ERR в переменную динамической индикации 280 0114 79 44

mov r1,#indicat ;адрес переменной 281 0116 77 08

mov @r1,#08h ;R 282 0118 09

inc r1  283 0119 77 08

mov @r1,#08h ;R 284 011B 09

inc r1  285 011C 77 46

mov @r1,#46h ;E 286

;С этого момента индикатор будет отображать слово ERR, говорящее об 287

;аварии датчика 288 011E

 289

;Досрочный звуковой сигнал в любом случае 290 011E 75 48 00

mov soundgenl,#0 291 0121 75 49 00

mov soundgenh,#0 292 0124 C2 77

clr notsound 293 0126 80 08

sjmp newind  294 0128

 295

;Данные приходят нормально 296 0128

display: 297 0128 30 7B 21

jnb inden,bell ;проверка наличия разрешающего флага индикации 298 012B

 299

;Флаг установлен 300 012B E5 90

mov a,p1 301 012D 33

rlc a 302 012E 40 05

jc indicts  303

304 0130

newind: 305

;Подготовка для повторной индикации 306 0130 75 47 44

mov rcount,#indicat 307 0133 74 DF

mov a,#11011111b ;инициализация порта, управляющего включением 308

;индикаторов 309 0135

indicts: 310

;Данные выведены не полностью 311

;Открыть соответствующий разряд 312 0135 F5 90

mov p1,a 313 0137 A9 47

mov r1,rcount ;адрес информации для текущего активного разряда 314

315

;Вывести очередной разряд в порт 316 0139 E7

mov a,@r1 317 013A F5 80

mov p0,a 318 013C 05 47

inc rcount 319 013E

 320

;Выход из прерывания динамической индикации 321 013E

exit_ind: 322 013E

 323

;Перезагрузить таймер 324 013E 75 8D F8

mov th1,#>indfreq 325 0141 75 8B 30

mov tl1,#<indfreq 326 0144

 327

;Если не установлен ни один и флагов ошибок то переход на генерацию не 328

;происходит 329 0144 20 D2 05

jb f0,bell 330 0147 20 7C 02

jb errtemp,bell 331 014A 80 59

sjmp exitin 332 014C

 333

;Генерация звуковых сигналов в критических ситуациях 334 014C

bell:  335 014C 20 77 11

jb notsound,endbell ;идет пауза в 5 мин или нет 336 014F

 337

;Проверка флага аварии датчика  338 014F 30 D2 04

jnb f0,LimitErr  339 0152

 340

;Предупреждающий сигнал об ошибке датчика 341 0152

SensorErr: 342

;Генерация меандра (1000Гц), в случае если данные долго не приходят данные 343 0152 B2 A0

cpl p2.0 344 0154 80 0A

sjmp endbell ;генерация меандра в случае аварии имеет высший приоритет  345 0156

 346

;Сигнал выхода температуры за заданные пределы 347 007D

delaybit: equ 125 ;вспомогательный бит 348 0156

 349 0156

LimitErr: 350 0156 30 7C 4C

jnb errtemp,exitin 351

;Генерация меандра 500Гц. Инверсия бита в порту производится через раз 352 0159 B2 7D

cpl delaybit 353 015B 30 7D 47

jnb delaybit,exitin  354 015E B2 A0

cpl p2.0 355 0160

 356 0160

 357 0160

endbell: 358 0160 C3

clr c 359 0161 05 48

inc soundgenl 360 0163

 361 0163 E5 49

mov a,soundgenh 362 0165 34 00

addc a,#0 363 0167 F5 49

mov soundgenh,a 364 0169

 365 0169 30 77 1E

jnb notsound,p3_second 366 016C

 367

;Проверка на истечение 5 минут 368 016C

p5_minutes: 369 016C C3

clr c 370 016D E5 48

mov a,soundgenl 371 016F 94 70

subb a,#<6000 372 0171 70 32

jnz exitin 373 0173

 374 0173 E5 49

mov a,soundgenh 375 0175 94 17

subb a,#>6000 376 0177 70 2C

jnz exitin 377 0179

 378

;Обнулить счетчик миллисекунд 379 0179 75 48 00

mov soundgenl,#0 380 017C 75 49 00

mov soundgenh,#0 381 017F

 382

;Добавить к счетчику минут 1 383 017F 05 62

inc minutes 384 0181 E5 62

mov a,minutes 385 0183 B4 05 1F

cjne a,#5,exitin 386 0186

 387

;Прошло 5 минут нужно повторить предупреждающий сигнал  388 0186 C2 77

clr notsound 389 0188 80 1B

sjmp exitin 390 018A

 391

;Проверка кончился ли промежуток генерации звука 3 c. 392 018A

p3_second: 393 018A C3

clr c 394 018B E5 48

mov a,soundgenl 395 018D 94 2C

subb a,#<300 396 018F 70 14

jnz exitin 397 0191

 398 0191 C3

clr c 399 0192 E5 49

mov a,soundgenh 400 0194 94 01

subb a,#>300 401 0196 70 0D

jnz exitin 402 0198

 403

;Остановить генерацию 404 0198 C2 A0

clr p2.0 405 019A

 406

;Обнуление переменных-счетчиков миллисекунд 407 019A 75 48 00

mov soundgenl,#0 408 019D 75 49 00

mov soundgenh,#0 409 01A0 75 62 00

mov minutes,#0 410 01A3 D2 77

setb notsound ;начать отсчитывание промежутка в 5 мин. 411 01A5

 412 01A5

exitin: 413

;Восстановление данных из стека перед выходом  414 01A5 D0 01

pop 1 415 01A7

 416

;Восстановление флага переноса 417 01A7 D0 E0

pop acc 418 01A9 33

rlc a 419 01AA

 420 01AA D0 E0

pop acc 421 01AC 32

reti 422

; 423

424

; Процедура подсчета значения температуры425

;Выход: a-численное значение температуры (модуль) 426

; 427 01AD

Calc_Temp: 428 01AD C0 00

push 0 429 01AF C0 01

push 1 430 01B1 C0 07

push 7  431 01B3

 432

;400*T1 433 01B3

 434 01B3 78 58

mov r0,#mem ;mem=400 435 01B5 76 90

mov @r0,#90h 436 01B7 08

inc r0 437 01B8 76 01

mov @r0,#1h 438 01BA 08

inc r0 439 01BB 76 00

mov @r0,#0h 440 01BD

 441 01BD 78 58

mov r0,#mem 442 01BF 79 52

mov r1,#pulse  443 01C1

 444 01C1 12 03 08

call MUL_3B ;mem=400*T1 445

446 01C4 78 52

mov r0,#pulse  447 01C6 79 55

mov r1,#pause 448 01C8

 449

;Сохраним значение длины паузы в переменной pulse 450

;для дальнейшего процесса округления 451 01C8 7F 03

mov r7,#3 452 01CA

moveb: 453 01CA E7

mov a,@r1  454 01CB F6

mov @r0,a 455 01CC 09

inc r1 456 01CD 08

inc r0 457 01CE DF FA

djnz r7,moveb 458 01D0

 459

;Восстановим адреса в регистрах 460 01D0 78 58

mov r0,#mem  461 01D2 79 55

mov r1,#pause 462 01D4 12 02 A8

call DIV_3B ;mem=(400*T1)/T2 463 01D7

 464

;После выполнения деления в pause содержится остаток 465 01D7

 466

;Из переменной mem можно взять только младшие два байта 467 01D7 C3

clr c 468 01D8 74 EB

mov a,#235 469 01DA 96

subb a,@r0 470 01DB F6

mov @r0,a 471 01DC 08

inc r0 472 01DD 74 00

mov a,#0  473 01DF 96

subb a,@r0 474 01E0 F6

mov @r0,a 475 01E1

 476

;Запись знака числа 477 01E1 92 7A

mov pos,c 478 01E3 B2 7A

cpl pos 479 01E5 E5 58

mov a,mem 480 01E7

 481

;Округление модуля температуры 482 01E7

trunc: 483

;Проверим остаток после операции деления и округлим модуль температуры 484

;в ту или иную сторону 485 01E7

 486

;pause-остаток  487

;pulse-делитель 488

;Для примерного округления разделим делитель на 2 и сравним с остатком 489

;если последний больше, то модуль температуры -1 490

;В случае когда они равны условимся округлять в большую сторону 491 01E7

 492 01E7 C0 E0

push acc 493

;Проверим не равняется ли остаток 0 494 01E9 78 55

mov r0,#pause 495

;Тестирование младшей части остатка 496 01EB E6

mov a,@r0 497 01EC B4 00 07

cjne a,#0,testost 498

;Тестирование старшей части остатка 499 01EF 08

inc r0 500 01F0 E6

mov a,@r0 501 01F1 B4 00 02

cjne a,#0,testost 502

;Остаток при делении равен 0 503 01F4 80 23

sjmp exitcalk 504 01F6

 505

;Протестируем величину погрешности 506 01F6

testost: 507

;Разделим делитель на 2 508 01F6 78 52

mov r0,#pulse 509 01F8 79 55

mov r1,#pause 510 01FA 12 02 59

call RRC_3B 511 01FD

 512

;Сравним остаток с полученным результатом (сравниваем младшие 2 байта) 513 01FD

 514

;Для начала сравним старшие байты, если они отличаютя то дальнейшее 515

;сравнение излишне 516 01FD 08

inc r0 517 01FE 09

inc r1 518 01FF

 519 01FF 7F 02

mov r7,#2 ;счетчик итераций цикла сравнения 520 0201

 521 0201

test: 522 0201 C3

clr c 523 0202 E6

mov a,@r0 ;байт поделенного делителя 524 0203 97

subb a,@r1 525 0204 50 07

jnc testequ 526

;Делитель меньше-от температуры нужно отнять 1  527 0206 D0 E0

pop acc 528 0208 14

dec a 529 0209 C0 E0

push acc 530 020B 80 0C

sjmp exitcalk 531 020D

 532

;Проверка на равенство байты  533 020D

mov a,@r0 535 020E 87 F0

mov b,@r1 536 0210 B5 F0 06

cjne a,b,exitcalk 537

;Проверим, какие байты тестируются (старшие или младшие) 538 0213 DF 04

djnz r7,exitcalk 539 0215

 540

;Тестировались старшие байты  541

;Старшие части равны, следовательно нужно проверять младшие 542

;Настройка указателей на младшие части 543 0215 19

dec r1 544 0216 18

dec r0 545 0217 80 E8

sjmp test 546 0219

 547 0219

 548 0219

exitcalk: 549 0219 D0 E0

pop acc 550

;Если температура отрицательна переведем число и дополнительного кода 551

; в пряиой  552 021B 20 7A 02

jb pos,ex 553 021E 14

dec a 554 021F F4

cpl a 555

556 0220

ex:  557 0220 D0 07

pop 7 558 0222 D0 01

pop 1 559 0224 D0 00

pop 0 560 0226

 561

;a-модуль температуры 562 0226 22

ret 563

; 564 0227

 565 0227

 566

; Проверка допустимости данной температуры 567

;Вход: a-численное значение температуры 568

; 569 0227

testlimit: 570 0227 C0 E0

push acc 571 0229 C0 F0

push b 572 022B C3

clr c 573 022C

 574 022C C2 7C

clr errtemp ;предварительный сброс флага ошибки 575 022E

 576 022E 20 7A 05

jb pos,positivs 577

;Отрицательная температура 578 0231 75 F0 28

mov b,#tempmin 579 0234 80 03

sjmp limittest 580 0236

 581

;Положительная температура 582 0236

positivs: 583 0236 75 F0 32

mov b,#tempmax 584 0239

 585

;Проверка вхождния в заданные пределы 586 0239

limittest: 587 0239 95 F0

subb a,b 588 023B 40 02

jc exitlim 589 023D D2 7C

setb errtemp 590 023F

 591 023F

exitlim: 592 023F D0 F0

pop b 593 0241 D0 E0

pop acc 594 0243 22

ret 595

; 596

597

598 0244

.include math.asm 599

;Файл math.asm процедуры выпонения арифметических операций с трехбайтными 600

;числами  601

602

; Процедура сдвига влево через флаг переноса 603

;Вход: R0-указатель на трехбайтное число 604

;Выход: R0-указатель на результат 605

; 606 0244

 607 0244

RLC_3B: 608 0244 C0 00

push 0 609 0246 C0 07

push 7 610 0248 C0 E0

push acc 611 024A

 612

;Сдвиг числа побайтно от младшего к старшему 613 024A 7F 03

mov r7,#3 614 024C

RL: 615 024C E6

mov a,@r0 616 024D 33

rlc a  617 024E F6

mov @r0,a 618 024F 08

inc r0 619 0250 DF FA

djnz r7,RL 620 0252

 621 0252 D0 E0

pop acc 622 0254 D0 07

pop 7 623 0256 D0 00

pop 0 624 0258 22

ret 625

; 626 0259

 627 0259

 628

629

; Процедура сдвига вправо через флаг переноса630

;Вход: R0-указатель на трехбайтное число 631

;Выход: R0-указатель на результат 632

; 633 0259

 634 0259

RRC_3B: 635 0259 C0 00

push 0 636 025B C0 07

push 7 637 025D C0 E0

push acc 638 025F

 639 025F

 640

;Настройка на старший байт 641 025F E8

mov a,r0 642 0260 24 02

add a,#2 643 0262 F8

mov r0,a 644

645

;Сдвиг числа побайтно от старшего к младшему 646 0263 7F 03

mov r7,#3 647 0265

RR: 648 0265 E6

mov a,@r0 649 0266 13

rrc a  650 0267 F6

mov @r0,a 651 0268 18

dec r0 652 0269 DF FA

djnz r7,RR 653 026B

 654 026B D0 E0

pop acc 655 026D D0 07

pop 7 656 026F D0 00

pop 0 657 0271 22

ret 658

; 659 0272

 660

661 0272

 662

; Процедура сложения трехбайтных чисел663

;Вход: 664

;R0-указатель на первое слагаемое 665

;R1-указатель на второе слагаемое 666

;Выход: 667

;R0-указатель на сумму 668

;C-перенос 669

; 670 0272

 671 0272

ADD_3B: 672 0272 C0 00

push 0 673 0274 C0 01

push 1 674 0276 C0 07

push 7 675 0278 C0 E0

push acc 676 027A

 677

;Предварительная очистка флага C 678 027A C3

clr c 679 027B 7F 03

mov R7,#3 ;число байт в числе 680 027D

 681

;Сложение числа побайтно с использованием флага переноса 682 027D

ADD: 683 027D E6

mov a,@R0 684 027E 37

addc a,@R1 685 027F F6

mov @R0,a 686 0280

 687 0280 08

inc R0 688 0281 09

inc R1 689 0282 DF F9

djnz r7,ADD 690 0284

 691 0284 D0 E0

pop acc 692 0286 D0 07

pop 7 693 0288 D0 01

pop 1 694 028A D0 00

pop 0  695 028C 22

ret 696

; 697 028D

 698

699

; Процедура вычитания трехбайтных чисел700

;Вход: 701

;R0-указатель на уменьшаемое 702

;R1-указатель на вычитаемое 703

;Выход: 704

;R0-указатель на разность 705

;C-заем 706

; 707 028D

 708 028D

SUB_3B: 709 028D C0 00

push 0 710 028F C0 01

push 1 711 0291 C0 07

push 7 712 0293 C0 E0

push acc 713 0295

 714

;Предварительное обнуление флага переноса 715 0295 C3

clr c 716 0296

 717 0296 7F 03

mov r7,#3 718 0298

 719

;Реализация вычитания 720 0298

SUB: 721 0298 E6

mov a,@R0 722 0299 97

subb a,@R1 723 029A F6

mov @R0,a 724 029B

 725 029B 08

inc r0 726 029C 09

inc r1 727 029D DF F9

djnz r7,SUB 728 029F

 729 029F D0 E0

pop acc 730 02A1 D0 07

pop 7 731 02A3 D0 01

pop 1 732 02A5 D0 00

pop 0  733 02A7 22

ret 734

; 735 02A8

 736

737

; Процедура деления трехбайтных чисел 738

;Вход: 739

;R0-указатель на делимое 740

;R1-указатель на делитель 741

;Выход: 742

;R0-указатель на частное 743

;R1-указатель на остаток 744

; 745 02A8

 746 02A8

DIV_3B: 747 0070

Remain: equ 70h ;промежуточный остаток 748 0073

REZ: equ 73h ;ячейка для временного хранения результата 749 02A8 C0 E0

push acc 750 02AA C0 07

push 7 751 02AC

 752 02AC C0 00

push 0 753 02AE C0 01

push 1 754 02B0

 755

;Начальная инициализация промежуточного остатка 756 02B0 78 70

mov R0,#Remain 757 02B2 79 73

mov r1,#REZ 758 02B4

 759 02B4 7F 03

mov r7,#3 760 02B6

init: 761 02B6 76 00

mov @R0,#0 762 02B8 77 00

mov @R1,#0 763 02BA 08

inc R0 764 02BB 09

inc r1 765 02BC DF F8

djnz r7,init 766 02BE

 767 02BE D0 01

pop 1  768 02C0 D0 00

pop 0 769 02C2

 770

;Реализация операции деления 771 02C2 7F 18

mov r7,#24 ;число битов в операндах 772 02C4

DIVIDE: 773

;Сдвинем делимое влево через флаг переноса 774 02C4 51 44

call RLC_3B ;R0-указатель на результат (тот же, что и входной) 775 02C6

 776 02C6 C0 00

push 0 777 02C8 78 70

mov r0,#Remain ;адрес промежуточного остатка 778 02CA 51 44

call RLC_3B ;сдвиг остатка влево с переносом 779 02CC

 780

;Вычтем из остатка делитель 781 02CC 51 8D

call SUB_3B 782 02CE 50 0A

jnc NOADD 783

784

;Сохраним флаг переноса в стеке 785 02D0 65 E0

xrl a,a 786 02D2 33

rlc a 787 02D3 C0 E0

push acc 788 02D5

 789

;Остаток отрицательный, необходимо его восстановление 790 02D5 51 72

call ADD_3B  791 02D7

 792

;Восстановление флага переноса 793 02D7 D0 E0

pop acc 794 02D9 13

rrc a 795 02DA

 796 02DA

NOADD: 797

;Сформируем бит частного 798 02DA B3

cpl c ;инверсия флага переноса 799 02DB 78 73

mov R0,#REZ ;загрузка адреса ячейки результата 800 02DD 51 44

call RLC_3B ;перенос флага C в ячейку результата 801 02DF D0 00

pop 0 ;восстановление в R0 адреса делимого 802 02E1

 803 02E1 DF E1

djnz r7,DIVIDE 804 02E3

 805

806

;Копируем результаты по входным адресам  807 02E3 C0 00

push 0 808 02E5 C0 01

push 1 809 02E7 79 73

mov R1,#REZ 810 02E9

 811 02E9 7F 03

mov R7,#3h 812 02EB

 813

;Копирование частного 814 02EB

copy1: 815 02EB E7

mov a,@R1 816 02EC F6

mov @r0,a 817 02ED 09

inc r1 818 02EE 08

inc r0 819 02EF DF FA

djnz R7,copy1 820

821 02F1 D0 01

pop 1 822 02F3

 823

;Копирование остатка 824 02F3 C0 01

push 1 825 02F5 78 70

mov R0,#Remain 826 02F7

 827 02F7 7F 03

mov r7,#3 828 02F9

copy2: 829 02F9 E6

mov a,@r0 830 02FA F7

mov @r1,a 831 02FB 09

inc r1 832 02FC 08

inc r0  833 02FD DF FA

djnz R7,copy2  834 02FF D0 01

pop 1 835 0301

 836 0301 D0 00

pop 0 837 0303

 838 0303 D0 07

pop 7 839 0305 D0 E0

pop acc 840 0307 22

ret 841

;842

843 0308

 844

; Процедура умножения трехбайтных чисел 845

;Вход: 846

;R0-указатель на первый множитель 847

;R1-указатель на второй множитель  848

;Выход: 849

;R0-указатель на произведение (трехбайтное !!!) 850

;851 0308

MUL_3B:  852 0070

Rezm: equ 70h ;ячейка для результата  853 0308 C0 E0

push acc 854 030A C0 07

push 7  855

856

;Предварительный сброс бита переноса 857 030C C3

clr c 858 030D

 859

;Очиска ячейки результатов 860 030D C0 00

push 0 861 030F 78 70

mov r0,#Rezm 862 0311

 863 0311 7F 03

mov r7,#3 864 0313

 865

;Очистка ячейки временного хранения результатов 866 0313

clear: 867 0313 76 00

mov @r0,#0 868 0315 08

inc r0 869 0316 DF FB

djnz r7,clear 870 0318 D0 00

pop 0 871 031A

 872 031A 7F 18

mov r7,#24 ;24 бита в трехбайтном числе 873 031C

 874 031C

MULT: 875

;Отправление младшего бита в битовый аккумулятор 876 031C C0 00

push 0 877 031E E9

mov a,r1 878 031F F8

mov r0,a 879 0320 51 59

call RRC_3B 880 0322 D0 00

pop 0 881 0324

 882 0324 50 10

jnc noadds 883 0326 C0 00

push 0 884 0328 C0 01

 886 032A C0 00

push 0 887 032C D0 01

pop 1 888 032E 78 70

mov r0,#Rezm 889 0330 51 72

call ADD_3B ;результат помещается по адресу Rezm 890 0332

 891 0332 D0 01

pop 1 892 0334 D0 00

pop 0 893 0336

 894 0336

noadds: 895 0336 C3

clr c ;сброс флага 896 0337 51 44

call RLC_3B ;сдвиг первого множителя  897 0339

 898 0339

newiter: 899 0339 DF E1

djnz r7,MULT 900 033B

 901

;Копирование результата в ячейки по входному адресу 902 033B 79 70

mov r1,#Rezm 903 033D

 904 033D C0 00

push 0 905 033F 7F 03

mov r7,#3 906 0341

 907 0341

copym: 908 0341 E7

mov a,@r1 909 0342 F6

mov @r0,a 910 0343 08

inc r0 911 0344 09

inc r1  912 0345 DF FA

djnz r7,copym 913 0347 D0 00

pop 0 914 0349

 915 0349 D0 07

pop 7 916 034B D0 E0

pop acc 917 034D 22

ret 918

; 919

920

921

;Коды семисегментного индикатора 922 034E

seg7ind: 923 034E C0

db C0h ;3fh ;0 924 034F F9

db F9h ;06h ;1 925 0350 A4

db A4h ;5bh ;2 926 0351 B0

db B0h ;4fh ;3 927 0352 99

db 99h ;66h ;4 928 0353 92

db 92h ;6dh ;5 929 0354 82

db 82h ;7dh ;6 930 0355 F8

db F8h ;07h ;7 931 0356 80

db 80h ;7fh ;8 932 0357 90

db 90h ;6fh ;9 933

934 0358

FUCK: Lines Assembled : 934 Assembly Errors : 0

Похожие работы на - Микропроцессорная система замера и индикации температуры на индикаторе

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!