Обработчик IRQ0 (начало измерений)



Функция обработчика – обнулить таймеры T1 и T2, а также специальную ячейку памяти D_NUM (2 байта). Эта ячейка инкрементируется всякий раз после чтения напряжения Ud с датчика диаметра. По приходу запроса IRQ0, когда приходит новое бревно, она должна быть обнулена.

 

Листинг 17: обработчик запроса IRQ0

    ; – – – обнулить T1, T2, D_NUM

    IR0_H             PUSH    BC         ;

                                PUSH    AF         ;

                                LD BC, 0     ;

                                LD (T1), BC ; обнулить T1

                                LD (T2), BC ; обнулить T2

                                LD (D_NUM), BC ; обнулить D_NUM

                                POP AF         ;

                                POP BC         ;

                                RETI               ;

 

Обработчик IRQ2 (информация с АЦП готова)

Функция обработчика – если бревно сейчас под пластиной датчика (можно судить, прочтя порт фотоэлементов с адресом 0B), считать два байта напряжения из портов 00 (младший) и 01 (старший). Записать их в массив напряжений, под который отведена область памяти начиная с адреса 0100Н до конца ОЗУ (всего 2К). Перед записью проверить, не заполнен ли этот массив. Инкрементировать ячейку D_NUM, содержащую число элементов этого массива.

 

Листинг 18: обработчик запроса IRQ2

; – – – считать и обработать байт с АЦП

IR2_H            PUSH    BC         ;

PUSH    HL         ;

PUSH    AF         ;

 

IN A, (#0B) ;

AND #02        ; наложить маску 000000010

JR Z, IR2_H1 ; если второй бит нулевой, то выход

LD HL, #1000 ; рассчитать адрес очередного элемента массива

LD C, (D_NUM)  ; считать D_NUM

LD B, (D_NUM+1) ;

SLA C           ; умножить его на 2

RL B           ;

ADD HL, BC  ; теперь адрес в HL

LD A, H      ;

CP #18        ;

JR NC, IR2_H1   ; если вышли за пределы массива, то выход

IN A, (#00) ; считать первый байт с АЦП

LD (HL), A  ; и отправить его в память

INC HL         ;

IN A, (#01) ; считать второй

LD (HL), A  ; отправить

INC BC         ; увеличить переменную D_NUM на единицу

LD (D_NUM), BC ;

IR2_H1 POP AF ;

POP HL         ;

POP BC         ;

RETI              ;

 

Обработчик IRQ3 (от генератора 16 Гц)

Функция обработчика – произвести инкремент часов реального времени и условный инкремент таймеров. Часы реального времени – это 4 байта в памяти:

TIME              1/16 секунды (0..15);

TIME+1 секунды (0..59);

TIME+2 минуты (0..59);

TIME+3 часы (0..23);

Все величины хранятся в двоичном формате.

Таймерам T1 и T2 отведено по 2 байта с начальными адресами T1 и T2. Условия, при которых они инкрементируются, были приведены в п. 3.4.

 

Листинг 19: обработчик запроса IRQ3

; – – – инкремент часов реального времени и условный инкремент таймеров

IR3_H   PUSH    BC         ;

              PUSH    HL         ;

              PUSH    AF         ;

              ; часы реального времени

              LD HL, TIME ;

              INC (HL)      ; инкремент 1/16 секунд

              LD A, (HL)           ;

              CP 16          ; проверить на достижение максимума           JR C, IR3_H1 ; условный выход из подпрограммы

              LD (HL), 0            ; иначе обнулить 1/16 секунды и продолжить

              INC HL         ;

              LD B, 2       ; инкремент секунд и минут делается в цикле

              IR3_H2           INC (HL)      ;

              LD A, (HL)           ;

              CP 60          ;

              JR C, IR3_H1 ;

              LD (HL), 0            ;

              INC HL         ;

              DJNZ    IR3_H2           ; конец цикла

              INC (HL)      ; инкремент часов

              LD A, (HL)           ;

              CP 24          ;

              JR C, IR3_H1 ;

              XOR A           ; если счетчик часов=24

              LD (HL), A           ; то обнулить все 4 байта часов реального времени

              DEC HL         ;

              LD (HL), A           ;

              DEC HL         ;

              LD (HL), A           ;

              DEC HL         ;

              LD (HL), A           ;

              ; таймеры

              IR3_H1           IN A, (#0B)         ; загрузить слово статуса фотоэлементов

              AND 1            ;

              JR Z, IR3_H3 ; если не установлен 1-й бит, то выход

              LD HL, T2            ; иначе инкремент Т2

              INC (HL)      ;

              JR NZ, IR3_H4    ; если инкремент не обнулил

              ; первый байт Т2, то идем дальше

              INC HL         ; иначе увеличить на 1 и второй байт

              INC (HL)      ;

              IR3_H4           IN A, (#0B)         ;

              AND 2            ; проверить 2-й бит статуса ФЭЛ

              JR Z, IR3_H3 ; если он не установлен, то выход

              LD HL, T1            ; иначе инкремент Т1

              INC (HL)      ;

              JR NZ, IR3_H3    ;

              INC HL         ;

              INC (HL)      ;

              IR3_H3 POP AF         ;

                                POP HL         ;

                                POP BC         ;

                                RETI               ;

 

Обработчик IRQ4 (от кнопки “+Час”)

Функция обработчика – увеличить на единицу часы реального времени (ячейка TIME+3).

Листинг 20: обработчик запроса IRQ4

              ; – – – инкремент часов

              IR4_H   PUSH    HL         ;

                                PUSH    AF         ;

                                LD HL, TIME+3;

                                INC (HL)      ; инкремент часов

                                LD A, (HL)  ;

                                CP 24          ;

                                JR C, IR4_H1 ;

                       XOR A           ; если счетчик часов=24

                       LD (HL), A           ; то обнулить часы и минуты

                       DEC HL         ;

                       LD (HL), A           ;

              IR4_H1           POP AF ;

                                POP HL         ;

                                RETI

 

Обработчик IRQ5 (от кнопки “+Мин”)

Функция обработчика – увеличить на единицу минуты реального времени (ячейка TIME+2).

 

Листинг 21: обработчик запроса IRQ5

              ; – – – инкремент минут

              IR5_H   PUSH    HL         ;

              PUSH    AF         ;

              LD HL, TIME+2;

              INC (HL)      ; инкремент минут

              LD A, (HL)  ;

              CP 60          ;

              JR C, IR5_H1 ;

              XOR A           ; если счетчик минут=60

              LD (HL), A           ; то обнуление минут

              INC HL         ; и инкремент часов

              INC (HL)      ;

              LD A, (HL)  ; с проверкой часов на 24

              CP 24          ;

              JR C, IR5_H1 ;

              XOR A           ; если счетчик часов=24

              LD (HL), A  ; то обнулить и часы

              IR4_H1           POP AF ;

              POP HL         ;

              RETI

 

Обработчик IRQ1 (от фотоэлемента Фэл2)

Обработчик IRQ1 выполняет самую важную функцию. Его задача – вычислить объем бревна. Последовательность следующая: вычисляем диаметр бревна, длину, вычисляем объем Vi, находим объем V S.

Для вычисления диаметра все значения, прежде считанные в массив напряжений с АЦП, усредняются: суммируются и делятся на количество (D_NUM). При суммировании может произойти переполнение суммы (а она двухбайтная), чтобы этого не было, массив разбивается на группы по 16 измерений в каждой. Если осталась остаточная группа с числом меньше 16, то она отбрасывается. В каждой из них подсчитывается среднее, затем рассчитывается искомое как среднее средних.

Из среднего напряжения находится угол

 

a= .

 

Затем находим диаметр d=0,625 – 0,5cos a=00,A0H – 00,80Hcos a. Занести его в ячейку DIAM (2 байта в памяти). Сравнить диаметр с допустимыми пределами [0,2..0,5]=[0,33H..0,8H]. Если он выходит за эти пределы, то выдать на отбраковку (порт 02H) единицу.

Объем Vi находится как Vi=(p/4)d2×T1/T2=0,C9H×d2×T1/T2.

Листинг 22: обработчик запроса IRQ1

; – – – найти объем бревна и суммарный объем

; усреднение всех напряжений с датчика диаметра в массиве по адресу 1000H

IR1_H   PUSH    AF ;

              PUSH    BC ;

              PUSH    DE ;

              PUSH    HL ;

 

              LD L, (D_NUM)   ;

              LD H, (D_NUM+1) ;

              LD B, 4       ; делим D_NUM на 16

IR1_H1          SRL H  ;

              RR L            ;

              DJNZ    IR1_H1 ;

              LD C, L ; в результате C=число групп по 16

              PUSH    BC         ; сохранить С в стеке

 

              LD HL, #1000 ;

              LD DE, 0     ; DE – начальная сумма групп

    PUSH    DE         ; отправить ее в стек, C станет второй в стеке

    PUSH    DE         ; DE – начальная сумма отдельной группы,

                                ; отправить®в стек, сумма групп вторая в стеке

                                ; C – третья в стеке

IR1_H4          LD B, 16     ;

IR1_H2          LD E, (HL)  ; читаем в DE элемент массива

    INC HL         ;

    LD D, (HL)  ;

    INC HL         ;

    EX (SP), HL ; текущую сумма в HL, текущий адрес в стеке

    ADD HL, DE  ;

    EX (SP), HL ; новая сумма в стеке, текущий адрес в HL

    DJNZ    IR1_H2 ;

    ; в итоге сумма одной группы по 16 – в стеке

    ; начальный адрес следующей группы – в HL

    POP DE         ;

    LD B, 4       ; находим среднее одной группы,

    IR1_H3 SRL D  ; деля сумму в DE на 16

    RR E           ;

    DJNZ    IR1_H3           ;

    POP HL         ; берем из стека сумму групп

    ADD HL, DE           ;

    PUSH    HL         ; снова отправляем в стек: сначала сумму групп

    PUSH    DE         ; затем сумму одной группы

    DEC C           ; С – счетчик групп

    JR NZ, IR1_H4    ; следующая группа…

 

    POP HL         ;

    POP HL         ; извлечь найденную сумму групп

    POP BC         ; извлечь счетчик групп C

    LD D, C      ; DE=C.0

    LD E, 0       ;

    CALL    DIV       ; делим сумму групп на число групп

    ; теперь HL=Ud=среднее всего массива напряжений датчика

    ; следующий шаг – нахождение угла a, cos a, d

    LD D, 4       ; DE=491H

    LD E, #91             ;

    LD B, H      ; сохранить Ud в BC

    LD C, L       ;

    EX DE, HL           ;

    CALL    MINUS           ; HL=491H-Ud

    EX HL, DE           ;

    LD H, B      ;

    LD L, C       ;

    CALL    DIV       ; HL= Ud/(491H-Ud)

    LD D, 0       ;

    LD E, #4F             ;

    CALL    MUL     ; HL=a

    CALL    COS      ; HL=cos a

    LD D, 0       ;

    LD E, #80             ;

    CALL    MUL     ; HL=0,5cos a

    LD D, 0       ;

    LD E, #A0            ;

    EX HL, DE           ;

    CALL    MINUS           ; HL=0,625-0,5cos a=d

    LD (DIAM), HL    ; занести диаметр в память

    ; формируем сигнал отбраковки

    LD A, L       ;

    CP #33        ;

    JR NC, IR1_H5   ; если d>20, то идем дальше

    LD A, 1       ; иначе в порт отбраковки записать 1

    OUT (#02), A          ;

    JR IR1_OUT ; и выход, не считая объем

    IR1_H5           LD A, L       ;

    CP #80        ;

    JR C, IR1_H6 ; если d<50, то идем дальше

    LD A, 1       ; иначе в порт отбраковки записать 1

    OUT (#02), A          ;

    ; дальше находим Vi, VS

    IR1_H6           LD L, (T1)   ;

    LD H, (T1+1) ;

    LD E, (T2)            ;

    LD D, (T2+1) ;

    CALL    DIV       ; HL=T1/T2

    LD E, (DIAM) ;

    LD D, (DIAM+1)  ;

    PUSH    DE         ;

    CALL    MUL     ; HL=T1×d/T2

    POP DE         ;

    CALL    MUL     ; HL=T1×d2/T2

    LD D, 0       ;

    LD E, #C9            ;

    CALL    MUL     ; HL=(p/4)T1×d2/T2=Vi

    EX HL, DE           ;

    LD L, (V_SUM)   ;

    LD H, (V_SUM+1) ;

    CALL    PLUS              ; HL=VS

    LD (V_SUM), HL ; занести суммарный объем в память

 

    IR1_OUT POP HL ;

    POP DE         ;

    POP BC         ;

    POP AF         ;

    RETI               ;

 

Основная исполняемая часть программы

Эту часть, которая, собственно, и является управляющей программой, микропроцессор выполняет большую часть своего времени, изредка отвлекаясь от нее на обработку прерываний.

Ее функции:

прочесть V S из ячейки V_SUM, перевести его в 2-10 код (подпрограммы B2D, B2D_F), перевести каждую цифру в семисегментный код (подпрограмма D27) и вывести в порт индикаторов (03-0A), присоединив десятичную запятую в индикаторе 06Н;

прочесть время из ячейки TIME (TIME+1–секунды, TIME+2–минуты, TIME+3–часы), перевести его в 2-10 код, перевести каждую цифру в семисегментный код и вывести в порт индикаторов (13-1A), присоединив десятичную запятую в индикаторах 13Н, 15Н, 17Н.

 

Рис. 7 Расположение объема и времени на индикаторах

Листинг 23: основная часть

    ; – – – вывести на индикаторы объем и время

    ; вывод объема

    MAIN             LD E, (V_SUM)   ;

    LD D, (V_SUM+1) ; D.E – суммарный объем

                                ; выводим целую часть D

    LD C, D      ;

    CALL    B2D ; HL=2-10 код D

    LD A, H      ;

    CALL    D27 ; в семисегментный код

    OUT (#08), A ; вывести в порт

    LD A, H      ;

    AND #0F        ;

    CALL    D27 ;

    OR #80        ; примешать десятичную запятую

    OUT (#06), A ; вывести в порт

    LD A, H      ;

    RR A           ; четырежды сдвигаем вправо

    RR A           ;

    RR A           ;

    RR A           ;

    AND #0F        ;

    CALL    D27 ;

    OUT (#07), A ; вывести в порт

                                ; выводим дробную часть E

    LD L, E       ;

    CALL    B2D_F  ; ABC=три цифры 2-10 кода числа 0.L

    CALL    D27       ;

    OUT (#05), A          ; вывести в порт

    LD A, B      ;

    CALL    D27       ;

    OUT (#04), A          ; вывести в порт

    LD A, C      ;

    CALL    D27       ;

    OUT (#03), A          ; вывести в порт

    ; вывод текущего времени

    LD HL, (TIME+1) ; HL=адрес секунд

    LD B, #13             ; самый правый индикатор

    MAIN1  PUSH    HL ;

    LD A, (HL)           ;

    LD C, A      ;

    CALL    B2D      ; HL=2-10 код секунд/минут/часов (причем Н=0)

    LD A, L       ;

    AND #0F        ;

    CALL    D27 ;

    OR #80        ; примешать запятую

    OUT (B), A             ; вывести в порт

    INC B           ; следующий индикатор

    LD A, L       ;

    RR A           ; четырежды сдвигаем А вправо

    RR A           ;

    RR A           ;

    RR A           ;

    AND #0F        ;

    CALL    D27       ;

    OUT (B), A             ; вывести в порт

    INC B           ; следующий индикатор

 

    POP HL         ;

    INC HL         ; перейти к следующей ячейке (TIME+2, TIME+3)

    LD A, B      ;

    CP #08        ; проверка конца цикла

    JR NZ, MAIN1    ;

 

    JP MAIN             ; начинаем все сначала


Дата добавления: 2019-07-15; просмотров: 161; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!