MOV RCAP2H,#high() ;Т2 будет перезагружаться
MOV RCAP2L,#low()
SETB TR2 ;запуск счета цикла управления
MOV IE,#B ;Разрешение всех прерываний кроме ;прерываний от послед. ввода/вывода
MOV IP,#B ;установка приоритетов
;Приоритеты
;1(высший): от аварийного датчика (прерывание INT0)
;2: Счет 0,5 с (от таймера 2)
;3: При отказе источника питания (прерывание INT1)
;4: Формирование синхросигнала SCL (от таймера 1)
;5: От командных клавиш ВВОД, МЕНЮ, ПУСК (прерывание INT3)
;6: Вывод на светодиоды (от таймера 0)
;Инициализация счетчика ВИ53
MOV DPTR,#E003H ;Адрес регистра управляющего слова
MOV A,#B ;Управляющее слово: Используем таймер ;0, пишем сначала младший, затем ;старший байты, режим 1
MOVX @DPTR, A
RET
ENTER_X1234:
SETB P1.4 ;Перед приемом данных необходимо
SETB P1.5 ;установить порты в 1
SETB P1.6
SETB P1.7
MOV C, P1.5 ;ввод во флаг переноса Х2
ANL C, P1.6 ;X2∙X3
ORL C, P1.7 ;складываем (X4+X2∙X3)
ANL C, P1.4 ;Х1∙(X4+X2∙X3), результат (Q1) в С
JC Y1_H ;если Q1=1, то переход на метку вывода Y1_H
JNC END_ENTER_X1234 ;если Q1 равен 0, то Y1 не выводим
Y1_H:
SETB P1.0 ;начинаем вывод Y1 на линии Р1.0
;формируем длительность Y1 100 мс
MOV DPTR,#24999 ;команда mov dptr,#data длится 2 МЦ = 4 мкс
DJNZ DPTR,$ ;команда djnz длится также 2 МЦ = 4 мкс
CLR P1.0
END_ENTER_X1234:
RET ;конец подпрограммы
ENTER_X56:
MOV B,#N ;считываем Х5, Х6 10 раз
MOV R5,#N5 ;адрес начала массива N5
MOV R6,#N6 ;адрес начала массива N6
;Считываем данные с АЦП
C_BUSY1:
MOV C, BUSY ;Проверка готовности АЦП для считывания ;данных
JC C_BUSY1 ;Если С=1, то переход
;Если С=0, значит АЦП готово
MOV DPTR,#8000H ;Выбор микросхемы АЦП и мультиплексора и ;установка мультиплексора на 1 канал
MOVX A,@DPTR
MOV DPTR,#В000H ;Считывание старшего байта
MOVX A,@DPTR ;в аккумулятор из формирователя
ANL A,#B ;Накладываем маску на 2 мл. бита (т. к. у ;нас 10-разрядное АЦП и неизвестно, что в ;остальных битах)
MOV @R5,A ;Старший байт N5 записываем в память
;по адресу из R5
MOV DPTR,#С000Н ;Считывание младшего байта
MOV A,@DPTR ;в аккумулятор из регистра
INC R5
MOV @R5,A ;Младший байт N5 записываем в память
INC R5 ;по адресу из R5
C_BUSY2:
MOV C, BUSY ;Проверка готовности АЦП для считывания ;данных
JC C_BUSY2 ;Если С=1, то переход
;Если С=0, значит АЦП готово
MOV DPTR,#8100H ;Выбор микросхемы АЦП и мультиплексора и ;установка мультиплексора на 2 канал
MOVX A,@DPTR
MOV DPTR,#В000H ;Считывание старшего байта, в
MOVX A,@DPTR ;в аккумулятор из формирователя
ANL A,#B ;Накладываем маску на 2 мл. бита (т. к. у ;нас 10-разрядное АЦП и неизвестно, что в ;остальных битах)
MOV @R6,A ;Старший байт N6 записываем в память
MOV DPTR,#С000Н ;Считывание младшего байта
MOVX A,@DPTR ;в аккумулятор из регистра
INC R6
MOV @R6,A ;Младший байт N6 записываем в память
INC R6
DJNZ B, C_BUSY1 ;Уменьшаем В на 1 и если В<>0, то переходим к ;след. циклу ввода Х5, Х6
;В памяти хранятся массивы N5 и N6
;Вычисление функции Q2=N5-2*N6+K
CALC_Q2:
MOV R6, #0H ;R6 для перемещения в массиве N6
MOV R7, #0H ;R7 для перемещения в массиве N5
mt1:
MOV A, R6
INC A ;будем работать со старшей частью 16- ;разрядного числа
MOV DPTR, #N6 ;пересылка в указатель данных DPTR 16- ;разрядный операнд (N6)
MOVC A, @A + DPTR ;содержимое ячейки памяти программ по ;адресу @A + DPTR пересылается в ACC (в ;аккумуляторе младшая часть числа)
CLR C ;сброс флага переноса
RLC A ;сдвиг влево через флаг переноса ;(умножение на 2) (во флаге переноса ;записан знак числа)
MOV R3, A ;В R3 младшая часть N6
MOV A, R6
MOVC A, @A + DPTR ;содержимое ячейки памяти программ по ;адресу @A + DPTR пересылается в ACC (в ;аккумуляторе старшая часть числа)
RL A ;сдвигаем младшую часть числа (не через ;разряд переноса)
MOV R2, A ;В R2 старшая часть N6
MOV A, R6
INC A
INC A
MOV R6, A ;сдвинулись на одно 16-разр. число в N6
MOV A, R7
MOV DPTR, #N5
MOVC A, @A + DPTR
MOV R4, A ;в R4 старшая часть N5
MOV A, R7
INC A
MOV R7, A
MOVC A, @A + DPTR
MOV R5, A ;в R5 младшая часть N5
MOV A, R7
INC A
MOV R7, A ;сдвинулись в N5 на одно 16-разрядное ;число
;Вычисляем N5-2*N6
mt3:
MOV A, R5
CLR C
SUBB A, R3
MOV R0, A
MOV A, R4
SUBB A, R2
MOV R1, A
; прибавление К
MOV A, R0
ADD A, K
MOV R0, A
MOV A, #0
ADDC A, R1
MOV R1, A
MOV A, Q2_L ;Считываем в АСС, что хранится по адресу ;младшего байта результата Q2_L
ADD A, R0
MOV Q2_L, A ;Увеличиваем содержимое этого адреса на ;младший байт промежуточн. рез-та R0
MOV A, Q2_H
ADDC A, R1
MOV Q2_H, A ;Аналогично для старшего байта
DJNZ 30h, mt1
NOP ;Получили общую сумму Q2i, надо поделить ;на N=10
MOV A, Q2_H
CJNE A,#B,mt10 ;Если сумма отриц. число, то ;переводим из доп. кода в прямой и ;запоминаем знак
mt10:
JC mt11
CPL A ;Переводим результат в доп. код ;(отриц. число)
MOV Q2_H, A
MOV A, Q2_L
CPL A
INC A
MOV Q2_L, A
MOV Q2_ZN, #B
mt11:
;Реализуем деление вычитанием
MOV A, Q2_L
MOV B, Q2_H
MOV R7,#0
MOV R5,#0
MOV R6,#0
mt8:
CLR C
SUBB A,#N
CJNE R5,#b, nn ;если R5=FFH, то
MOV R5,#0 ;нужно его обнулить
INC R6 ;и увеличить счетчик в R6
JMP mm
nn:
INC R5 ;если R5<>FFH, то увеличиваем R5
mm:
CJNE A,#(N-1), mt9 ;сравниваем вычитаемое с 9
mt9:
JNC mt8 ;если младший байт при вычитании больше ;9, то продолжаем вычитание
MOV R7,A ;запоминаем промежуточный остаток
MOV A, B
CJNE A,#0, mt6 ;если ст. байт=0, то вычитание ;заканчиваем, иначе на mt6
jmp mt7
mt6:
DEC B ;уменьшаем на 1 ст. байт
MOV A,#N ;в R7 промежут. остаток
CLR C
SUBB A,R7 ;Вычитаем из 10 R7
MOV R7,A ;и запоминаем результат в R7
MOV A,#b
SUBB A, R7 ;Вычитаем из мл. байта(FFH) R7
INC A
INC R5
JMP mt8 ;Переходим к дальнейшему вычитанию
mt7:
MOV Q2_L,R5 ;Запись результатов
MOV Q2_H, R6
MOV Q2_MOD, R7
;Нач. установка внутреннего таймера 1, который будет использоваться ;для генерации синхросигнала SCL для подачи его на внешний таймер ;ВИ53 (Y2 и Y3), период сигнала 500 мкс
MOV TH1,#(256-125) ;МЦ=2 мкс, следовательно для ;формирования интервала 250 мкс ;необходимо загрузить (256-125)
MOV TL1,#(256-125)
;Сравниваем вычисленное значение Q2 со значением Q0=511.5, которое ;хранится в ПЗУ
MOV DPTR,#1000H ;Адрес в ПЗУ старшего байта Q0
MOV A,#0H
MOVC A,@A+DPTR
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |


