Помощь в написании студенческих работ
Антистрессовый сервис

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

КурсоваяПомощь в написанииУзнать стоимостьмоей работы

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

Микропроцессорная система замера и индикации температуры на индикаторе (реферат, курсовая, диплом, контрольная)

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

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

В данной работе решается определенная задача с использованием однокристальной ЭВМ МК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(напр. 11 011 111).

Разрешение работы индикатора производится нулем. В приведенном выше примере выбран самый младший индикатор. Далее в порт 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, который вызывает генерацию меандра.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

clr c.

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

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

ADD:

mov a,@R0.

addc a,@R1.

mov @R0,a.

inc R0.

inc R1.

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, на этом свойстве и основан данный принцип умножения.

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

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

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

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

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

Процедура реализации операции деления 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Ом.

R2 — R22.

C2 -14 0.125Вт 8870Ом.

Микросхемы.

DD1.

TMP03.

DD2.

К1554ЛН1.

DD3.

AT89C51 — 24AC.

DD4.

HG1.

BA/BC56 — 1.

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

VT1.

2N6038.

VT2 — VT4.

КП402А.

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

C1,C2.

C3.

ZQ1.

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

Thu May 8 2012 11:24 Page 1 2500 A.D. 8051 Macro Assembler — Version 4.02a Input Filename: E: ASM51KURSKURS. 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.

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

org 0003h 41 0003 02 00 C9.

jmp int0 42 0006.

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

org 0013h 45 0013 02 00 EE.

jmp int1 46 0016.

47 001B.

org 001bh 48 001B 02 00 FF.

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

50 0030.

org 30h 51 0030.

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

start: 54.

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

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

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

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

mov tl1,#.

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

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

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

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

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

;Инициализация флагов и переменных 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.

;Обнуление временных счетчиков 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,#1 110 1111b ;инициализация порта, управляющего включением 84.

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

;Запуск таймера динамической индикации 87 005 °F 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.

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

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

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

;Перепишем в первую очередь данные из спец ячеек в регистры, чтобы не 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.

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

clr c 108 0071.

109 0071 ED.

mov a, r5 110 0072 9 °F.

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.

;Пересылка длины импульса и паузы в специальные трехбайтные переменные 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 007 °F 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.

;Подсчитаем численное значение температуры 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.

;Перевод десятичного числа в 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.

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

seg7code: 151 009A 78 44.

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

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

push acc 155.

156 009E 54 0 °F.

anl a,#1111b 157 00A0.

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

clr inden 160 00A2.

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

movc a,@a+dptr 163 00A3 F6.

mov @r0,a 164 00A4 08.

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

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

pop acc 168 00A7 54 F0.

anl a,#1 111 0000b 169 00A9 C4.

swap a 170 00AA.

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

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

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

sjmp outind 175 00B1.

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

notguish: 178 00B1 93.

movc a,@a+dptr 179 00B2.

180 00B2.

outind: 181 00B2 F6.

mov @r0,a 182.

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

;Подготовим байт для знакового разряда 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.

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

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

cjne a,#ffh, notnull 194 00BD.

195 00BD A6 F0.

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

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

inc r0 199 00C0 76 FF.

mov @r0,#ffh 200 00C2 01 61.

jmp waitnew 201 00C4.

;Разряд не нулевой 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.

; 210.

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

int0: 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.

;Чтение данных о общей длине (импульс+пауза) 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.

;Обнуление таймера 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.

; 240.

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

int1: 242 00EE 30 79 0D.

jnb begread, end_I1 243 00F1.

;Сохранение данных о длине импульса 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.

; 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.

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

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

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

jb f0, display 275 010 °F B4 FA 16.

cjne a,#250,display 276.

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

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

;Загрузка слова 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.

;Досрочный звуковой сигнал в любом случае 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.

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

display: 297 0128 30 7B 21.

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

;Флаг установлен 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,#1 101 1111b ;инициализация порта, управляющего включением 308.

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

indicts: 310.

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

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

mov p1, a 313 0137 A9 47.

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

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

mov a,@r1 317 013A F5 80.

mov p0, a 318 013C 05 47.

inc rcount 319 013E.

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

exit_ind: 322 013E.

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

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

mov tl1,#.

;Если не установлен ни один и флагов ошибок то переход на генерацию не 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.

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

bell: 335 014C 20 77 11.

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

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

jnb f0, LimitErr 339 0152.

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

SensorErr: 342.

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

cpl p2.0 344 0154 80 0A.

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

;Сигнал выхода температуры за заданные пределы 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.

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

p5_minutes: 369 016C C3.

clr c 370 016D E5 48.

mov a, soundgenl 371 016 °F 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.

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

mov soundgenl,#0 380 017C 75 49 00.

mov soundgenh,#0 381 017 °F.

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

inc minutes 384 0181 E5 62.

mov a, minutes 385 0183 B4 05 1 °F.

cjne a,#5,exitin 386 0186.

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

clr notsound 389 0188 80 1B.

sjmp exitin 390 018A.

;Проверка кончился ли промежуток генерации звука 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 018 °F 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.

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

clr p2.0 405 019A.

;Обнуление переменных-счетчиков миллисекунд 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.

;Восстановление флага переноса 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.

; Процедура подсчета значения температуры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.

;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.

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

;для дальнейшего процесса округления 451 01C8 7 °F 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.

;Восстановим адреса в регистрах 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.

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

;Из переменной 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.

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

mov pos, c 478 01E3 B2 7A.

cpl pos 479 01E5 E5 58.

mov a, mem 480 01E7.

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

trunc: 483.

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

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

;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.

;Протестируем величину погрешности 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.

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

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

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

inc r0 517 01FE 09.

inc r1 518 01FF.

519 01FF 7 °F 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.

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

testequ: 534 020D E6.

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.

;Тестировались старшие байты 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 021 °F 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.

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

ret 563.

; 564 0227.

565 0227.

; Проверка допустимости данной температуры 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.

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

positivs: 583 0236 75 F0 32.

mov b,#tempmax 584 0239.

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

limittest: 587 0239 95 F0.

subb a, b 588 023B 40 02.

jc exitlim 589 023D D2 7C.

setb errtemp 590 023 °F.

591 023 °F.

exitlim: 592 023 °F D0 F0.

pop b 593 0241 D0 E0.

pop acc 594 0243 22.

ret 595.

; 596.

598 0244.

.include math. asm 599.

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

;числами 601.

; Процедура сдвига влево через флаг переноса 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.

;Сдвиг числа побайтно от младшего к старшему 613 024A 7 °F 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 024 °F 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.

; Процедура сдвига вправо через флаг переноса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 025 °F.

639 025 °F.

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

mov a, r0 642 0260 24 02.

add a,#2 643 0262 F8.

mov r0, a 644.

;Сдвиг числа побайтно от старшего к младшему 646 0263 7 °F 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 026 °F D0 00.

pop 0 657 0271 22.

ret 658.

; 659 0272.

661 0272.

; Процедура сложения трехбайтных чисел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.

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

clr c 679 027B 7 °F 03.

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

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

ADD: 683 027D E6.

mov a,@R0 684 027E 37.

addc a,@R1 685 027 °F 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.

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

;Вход: 701.

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

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

;Выход: 704.

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

;C-заем 706.

; 707 028D.

708 028D.

SUB_3B: 709 028D C0 00.

push 0 710 028 °F C0 01.

push 1 711 0291 C0 07.

push 7 712 0293 C0 E0.

push acc 713 0295.

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

clr c 716 0296.

717 0296 7 °F 03.

mov r7,#3 718 0298.

;Реализация вычитания 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 029 °F.

729 029 °F 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.

; Процедура деления трехбайтных чисел 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.

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

mov R0,#Remain 757 02B2 79 73.

mov r1,#REZ 758 02B4.

759 02B4 7 °F 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.

;Реализация операции деления 771 02C2 7 °F 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.

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

call SUB_3B 782 02CE 50 0A.

jnc NOADD 783.

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

xrl a, a 786 02D2 33.

rlc a 787 02D3 C0 E0.

push acc 788 02D5.

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

call ADD_3B 791 02D7.

;Восстановление флага переноса 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.

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

push 0 808 02E5 C0 01.

push 1 809 02E7 79 73.

mov R1,#REZ 810 02E9.

811 02E9 7 °F 03.

mov R7,#3h 812 02EB.

;Копирование частного 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.

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

push 1 825 02F5 78 70.

mov R0,#Remain 826 02F7.

827 02F7 7 °F 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.

; Процедура умножения трехбайтных чисел 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.

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

clr c 858 030D.

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

push 0 861 030 °F 78 70.

mov r0,#Rezm 862 0311.

863 0311 7 °F 03.

mov r7,#3 864 0313.

;Очистка ячейки временного хранения результатов 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 7 °F 18.

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

874 031C.

MULT: 875.

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

push 0 877 031E E9.

mov a, r1 878 031 °F 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.

push 1 885 032A.

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.

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

mov r1,#Rezm 903 033D.

904 033D C0 00.

push 0 905 033 °F 7 °F 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.

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

seg7ind: 923 034E C0.

db C0h ;3fh ;0 924 034 °F 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.

Показать весь текст
Заполнить форму текущей работой