Микропроцессорная система замера и индикации температуры на индикаторе
Примерный вид выходного сигнала датчика. Описание и блок-схема алгоритма обработчиков прерываний. Формула вычисления температуры на индикаторе. Перевод абсолютного значения в BCD-код. Блок-схема алгоритма основной программы. Динамическая индикация.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 21.10.2012 |
Размер файла | 141,2 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Введение
Использование микроЭВМ существенно повышает уровень автоматизации процессов управления. МП позволяют значительно уменьшить габаритные размеры устройств, при этом сложность решения задачи программирование может оказаться значительно меньшей чем при реализации такого же устройства на дискретных элементах. Данный аспект значительно расширяет область применения МП-систем, в системах управления.
Поэтому современный специалист в области промышленной электроники должен обладать некоторыми определенными навыками и знаниями, позволяющими ему успешно использовать и внедрять микропроцессорную технику в промышленное производство.
В данной работе решается определенная задача с использованием однокристальной ЭВМ МК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, который вызывает генерацию меандра.
Алгоритм процедуры достаточно прост:
сбрасывается флаг ошибки.
Определяется знак температуры (флаг 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, на этом свойстве и основан данный принцип умножения.
Операция умножения реализуется в цикле:
анализируется бит множителя и в зависимости от его значения осуществляется прибавление множимого к сумме предыдущих частичных произведений.
Сдвиг множимого влево.
Текст процедуры написан в листинге.
Размещено на http://www.allbest.ru/
Блок-схема алгоритма умножения
Процедура реализации операции деления 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 |
Листинг программы
Thu 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
183
;Выведем знак числа 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
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
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
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
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
Размещено на Allbest.ru
Подобные документы
Изучение понятия и свойств алгоритма. Определение сущности технологии Robson. Исполнитель, а также блок-схема алгоритма или его графическое представление, в котором он изображается в виде последовательности связанных между собой функциональных блоков.
реферат [155,9 K], добавлен 19.10.2013Описание алгоритма работы и разработка структурной схемы МКС. Схема вывода аналогового управляющего сигнала, подключения ЖК-дисплея, клавиатуры и аварийного датчика. Разработка блок-схемы алгоритма главной программы работы МКС. Функция инициализации.
курсовая работа [5,7 M], добавлен 26.06.2016Элементы и переменные, используемые для составления записи в Паскале. Основные числовые типы языка Turbo Pascal. Составление блок-схемы приложения, программирование по ней программы для вычисления функции. Последовательность выполнения алгоритма.
лабораторная работа [256,9 K], добавлен 10.11.2015Решение трансцендентного уравнения методом Ньютона. Построение графика функции. Блок-схема алгоритма решения задачи и программа решения на языке Pascal. Вычисление значения интеграла методом трапеции, блок-схема алгоритма, погрешности вычисления.
задача [163,4 K], добавлен 16.12.2009Изучение категории типов данных, видов выражений и операций, работа на языке Си. Составление программы вычисления значения функции у(х) при произвольном значении х. Блок-схема алгоритма. Описание текста программы и рассмотрение контрольного примера.
лабораторная работа [124,7 K], добавлен 09.01.2012Описание работы элементов программы в виде блок-схем. Анализ структурной схемы модели домофона. Блок-схема работы открытия двери ключом. Моделирование в Proteus: принцип динамического опроса и индикации, внешний вид жидкокристаллического дисплея.
курсовая работа [1,4 M], добавлен 12.04.2019Разработка игровой программы, моделирующей поведение мяча в закрытом безвоздушном пространстве. Изменение значения гравитации и трения о стены. Интерфейс программы, ее основная форма. Блок-схема программы и ее основной код. Добавление третьего измерения.
контрольная работа [111,1 K], добавлен 27.08.2012Решение задачи по методу Адамса. Блок-схема функции main. Блок-схема функции Adams. Листинг программы. Блок-схема функции MMinor. Блок-схема функции MatrixMultiply. Блок-схема функции Determinant. Результат решения задачи на ЭВМ.
курсовая работа [68,9 K], добавлен 16.04.2004Структура автомата для сбора данных. Программы, реализующие заданный пользователем алгоритм автоматизации процедуры обработки журнальных данных. Описание микропроцессорной системы, ее упрощенная модель, система команд, блок-схема алгоритма обработки.
контрольная работа [65,8 K], добавлен 14.11.2010Разработка алгоритма решения задачи численного интегрирования методом трапеции. Словесное описание и блок-схема разработанного алгоритма программы. Описание интерфейса, главного окна и основных форм программы. Проверка работоспособности программы.
курсовая работа [1,4 M], добавлен 16.03.2012