;
; Program obrotomierza
;
CZ5ms equ 0ec77h ;5ms dla 12MHz
LCZYN equ 3 ;dlugosc czynnikow w bajtach
KEY equ 6+8 ;R6 z banku 1-go, stan klawiatury
OLDKEY equ 5+8 ;stary klawisz
ILOSC_C equ 4+8 ;ilosc cylindrow silnika
;
STATUS equ 20h
CZAST3 equ 21h ;ostatni pomiar czasu T
CZAST2 equ CZAST3+1
CZAST1 equ CZAST2+1
CZASTA3 equ CZAST1+1 ;ostatni pomiar czasu TA
CZASTA2 equ CZASTA3+1
CZASTA1 equ CZASTA2+1
THL0 equ CZASTA1+1
T equ THL0+1 ;bufor czasu T
TA equ T+LCZYN ;bufor czasu TA
;
BCD equ TA+LCZYN
CZYNIK1 equ BCD+LCZYN
CZYNIK2 equ CZYNIK1+LCZYN
AKU1 equ CZYNIK2+LCZYN
AKU2 equ AKU1+LCZYN*2
WYNIK equ AKU2+LCZYN*2
RAKU1 equ WYNIK+LCZYN*2
RAKU2 equ RAKU1+1
;
DISP equ RAKU2+1 ;pamiec wyswietlacza w bajtach
DISPO equ DISP+4 ;pamiec Obrotow w BCD
DISPK equ DISPO+2 ;pamiec Kata w BCD
STOS equ DISPK+2
;
org 0
ajmp INIT
;obsluga przerwania INT0 zboczem opadajacym
;pomiar T (odczyt licznika i zerowanie)
org 3
ajmp OBINT0
;obsluga przerwania TF0
;powieksza zakres licznika T o 1 bajt
org 0bh
inc THL0
reti
; ajmp OB_TF0
;
;obsluga przerwania INT1 zboczem opadajacym realizuje
;pomiar kata wyprzedzenia (odczyt licznika jako TA)
org 13h
ajmp OBINT1
;obsluga przerwania TF1
;obsluguje wyswietlanie
org 1bh
push psw
push acc
setb psw.3 ;bank 1
mov TL1,#CZ5ms&255 ;77h ;5ms dla 12MHz
mov TH1,#CZ5ms/256 ;0ech
;w R7 licznik pozycji wyswietlanej cyfry
inc r7
mov c,STATUS.6 ;p3.2 ;przepisuje wejscie OBROTOW do przecinka
mov a,DISP+3
mov acc.7,c
mov DISP+3,a
mov c,STATUS.7 ;p3.3 ;przepisuje wejscie KAT do przecinka
mov a,DISP
mov acc.7,c
mov DISP,a
mov a,r7
mov c,acc.3 ;symulacja impulsow halotronu
mov p3.5,c
cpl c
mov p3.4,c ;negacja p3.5 symuluje KAT
cjne a,#128,DAL_INT0
mov r7,#0
jnb STATUS.0,DAL_INT0
setb STATUS.2
clr STATUS.0
DAL_INT0:
;obsluga klawiatury
setb p3.7 ;DISP OFF, KEY ON
mov p1,#0ffh
mov a,r7
anl a,#3
cjne a,#0,ZLYZAD
mov a,p1 ;odczyt stanu klawiatury
cpl a
cjne a,KEY,NOWYZNAK ;w R6 stan klawiatury
ajmp ZLYZAD
NOWYZNAK:
mov r6,a ;nowy stan klawiatury R6=KEY
;
ZLYZAD: mov a,r7
anl a,#3 ;obciecie do 4-ch cyfr
add a,#DISP ;obliczenie adresu wyswietlanej pozycji
mov r0,a
mov a,@r0 ;pobranie cyfry do wyswietlenia
mov p1,a
mov a,r7
cpl a
mov c,acc.0
mov p3.0,c
mov c,acc.1
mov p3.1,c
clr p3.7 ;DISP ON
pop acc
pop psw
reti
;-------------------------
OBINT0: clr TCON.4 ;zatrzymanie TR0
clr TCON.3
setb IE.2 ;zezwala na INT1
mov CZAST1,TL0
mov TL0,#0
mov CZAST2,TH0
cpl STATUS.6
jnb TCON.5,OBI ;TF0
clr TCON.5
inc THL0
OBI: mov CZAST3,THL0 ;przedluzenie T0
mov TH0,#0
mov THL0,#0
setb TCON.4 ;start TR0
jb STATUS.0,NieT
mov T,CZAST3
mov T+1,CZAST2
mov T+2,CZAST1
NieT: setb STATUS.0
reti
OBINT1:
clr TCON.4 ;zatrzymanie TR0
clr IE.2 ;zamyka INT1
mov CZASTA1,TL0
mov CZASTA2,TH0
mov CZASTA3,THL0
setb TCON.4 ;start TR0
cpl STATUS.7
jb STATUS.1,NieTA
mov TA,CZASTA3
mov TA+1,CZASTA2
mov TA+2,CZASTA1
NieTA: setb STATUS.1
reti
;---------------------------------------------------------
;Program mnozenia liczb binarnych urzywa rejestry R0 do R7
;Organizacja pamieci dla procedur
; xxxx BCD
; xxxx CZYNIK1 oraz BIN
; xxxx CZYNIK2
; xxxxxxxx AKU1 oraz WYNIKD
; xxxxxxxx AKU2 oraz DZIELNIK
; xxxxxxxx WYNIK oraz DZIELNA
; x RAKU1
; x RAKU2
;
MUL: mov r0,#AKU1
mov r2,#WYNIK-AKU1+LCZYN*2
acall ZERO
mov RAKU1,#AKU1+LCZYN*2-1
mov RAKU2,#AKU2+LCZYN*2-2
mov r6,#CZYNIK1+LCZYN-1
mov r3,#LCZYN ;ilosc czynnikow 2
LOOP: mov r7,#CZYNIK2+LCZYN-1
mov r5,RAKU1
mov r4,RAKU2
acall ZER_AKU
acall MUL1
acall D_ABW
dec r6 ;nastepny czynnik 2
dec RAKU1
dec RAKU2
djnz r3,LOOP
ret
;
;Procedura dadawania
;R0 i R1 => R1 w R2 dlugosc
DODAJ1: clr c
DL: mov a,@r0
addc a,@r1
mov @r1,a
dec r0
dec r1
djnz r2,DL
ret
;Procedura dadwania czesciowego
D_ABW: mov r0,#AKU1+LCZYN*2-1
mov r1,#WYNIK+LCZYN*2-1
mov r2,#LCZYN*2
acall DODAJ1
mov r0,#AKU2+LCZYN*2-1
mov r1,#WYNIK+LCZYN*2-1
mov r2,#LCZYN*2
ajmp DODAJ1
;Procedura zerowania akumulatorow
ZER_AKU:
mov r0,#AKU1
mov r2,#LCZYN*4 ;16, AKU1+AKU2
;Procedura zerowania
ZERO: mov @r0,#0
inc r0
djnz r2,ZERO
ret
;Procedura mnozenia
;w R6 czynnik 1
;w R7 czynnik 2
;w R5 AKU1 adres A, w R4 AKU2 adres B
;w R2 dlugosc
MUL1: mov r2,#LCZYN ;4
MLOOP: mov r0,6
mov r1,7
mov a,@r0
mov b,@r1
mul ab
mov r0,5
mov r1,4
mov @r0,a
mov @r1,b
dec r4
dec r5
dec r7
djnz r2,MLOOP
ret
;--------------------------------------------------
; Procedura dzielenia
;
; xxxxxx DZIELNA w WYNIKu z mnozenia
; xxxxxx DZIELNIK w AKU2
; xxxxxx WYNIKD w AKU1
;
DZIELNA equ WYNIK
LDA equ LCZYN*2
LDK equ LDA
DZIELNIK equ AKU2 ;DZIELNA+LDA
WYNIKD equ AKU1
LWY equ LDA
;
DZIEL: acall ZERWYN ;if DZIELNIK=0 then C=1 else C=0
acall CZY_0
jc KONIEC
mov r1,#DZIELNIK+LDK-1
mov r0,#DZIELNA+LDA-1
mov r2,#LDA
acall POROW
jc NEGAT
acall SZUKAJ
DA_DK: acall ODJAC8
mov r0,#WYNIKD+LWY-1
mov r2,#LWY
acall MNOZ2 ;wynik*2
inc WYNIKD+LWY-1 ;+1
DAL: djnz r3,DALEJ
clr c
ajmp KONIEC
DALEJ: acall DZIEL8 ;dzielnik/2
acall PODZIELNE ;czy jest podzielne
jc DA_DK
mov r0,#WYNIKD+LWY-1
mov r2,#LWY
acall MNOZ2 ;wynik*2
ajmp DAL
NEGAT: clr c
KONIEC: ret
;Procedura odejmowania od R1, R0 wynik umieszcza w R1
;w R2 dlugosc bufora w bajtach
ODJAC8: acall USTAW8
ODJAC: clr c
LOOPO: mov a,@r1
subb a,@r0
mov @r1,a
dec r0
dec r1
djnz r2,LOOPO
ret
;Procedura dodawania do R0, R1 wynik umieszcza w R0
;w R2 dlugosc bufora w bajtach
DODAJ8: acall USTAW8
DODAJ: clr c
LOOP1: mov a,@r0
addc a,@r1
mov @r0,a
dec r0
dec r1
djnz r2,LOOP1
ret
;Sprawdzenie if Dzielnik = 0 then C=1 else C=0
CZY_0: mov r0,#DZIELNIK
mov r2,#LDK
setb c
CZY: mov a,@r0
jnz ZERO_C
inc r0
djnz r2,CZY
ret
ZERO_C: clr c
ret
;Sprawdzenie rownosci if R0 = R1 then C=1 else C=0
;w R2 dlugosc bufora w bajtach
PODZIELNE:
acall USTAW8
CZYR: mov a,@r0
mov b,@r1
cjne a,b,ROZNE
dec r0
dec r1
djnz r2,CZYR
setb c
ret
ROZNE: acall POROW8
ret
;Porownanie R0 z R1 wynik umieszczany jest w C
;w R2 dlugosc bufora w bajtach
POROW8: acall USTAW8
POROW: clr c
LOOP2: mov a,@r0
subb a,@r1
dec r0
dec r1
djnz r2,LOOP2
ret
;Mnozenie razy 2 bufora R0 o dlugosci w R2
MNOZ8: mov r0,#DZIELNIK+LDK-1
mov r2,#LDK
MNOZ2: clr c
LOOP3: mov a,@r0
rlc a
mov @r0,a
dec r0
djnz r2,LOOP3
ret
;Dzielenie przez 2 bufora R0 o dlugosci w R2
DZIEL8: mov r0,#DZIELNIK
mov r2,#LDK
DZIEL2: clr c
LOOP4: mov a,@r0
rrc a
mov @r0,a
inc r0
djnz r2,LOOP4
ret
;Ustawia rejestry dla procedur
USTAW8: mov r0,#DZIELNIK+LDK-1
mov r1,#DZIELNA+LDA-1
mov r2,#LDA ;podstawic dluzszy bufor
ret
;Szukanie pozycji dzielnika w stosunku do dzielnej
SZUKAJ: mov r3,#0 ;wskaznik ilosci przesuniec
LOOP5: mov r0,#DZIELNA+LDA-1
mov r1,#DZIELNIK+LDK-1
mov r2,#LDA
acall POROW
jc WROC
inc r3
acall MNOZ8
ajmp LOOP5
WROC: acall DZIEL8
PRZEZ0: ret
;
ZERWYN: mov r0,#WYNIKD
mov r2,#LWY
ZER: mov @r0,#0
inc r0
djnz r2,ZER
ret
;----------------------------------------------------------
; Procedury przeliczeniowe Bin na BCD oraz BCD na Bin
; dla komputera 8031
;/***** ***** ***** ***** *****/***** ***** ***** *****/
;/ BCD / BIN /
;BCD equ 20h ;adres bazowy bufora
LBCD equ LCZYN
BIN equ BCD+LBCD
LBIN equ LCZYN
;
; Procedura zamiany liczby BIN na BCD
; Wywolanie przez ACALL BBCD niszczy A,R1,R2,R3
;
BBCD: mov r3,#8*LBIN
acall ZER_BCD
S1: acall KOR
acall ROL
djnz r3,S1
ret
;
KOR: mov r0,#BCD+LBCD-1
mov r1,#LBCD
KOR1: mov a,@r0
cjne a,#50h,KOR2
KOR2: jc NIEKOR
add a,#30h
mov @r0,a
NIEKOR: anl a,#0fh
cjne a,#5,KOR3
KOR3: jc NIEKO
add a,#3
mov r7,a
mov a,@r0
anl a,#0f0h
orl a,r7
mov @r0,a
NIEKO: dec r0
djnz r1,KOR1
ret
;
ROL: clr c
mov r2,#LBCD+LBIN
mov r0,#BIN+LBIN-1
ROL1: mov a,@r0
rlc a
mov @r0,a
dec r0
djnz r2,ROL1
ret
;
ZER_BCD:
mov r0,#BCD
mov r1,#LBCD
ZER1: mov @r0,#0
inc r0
djnz r1,ZER1
ret
;---------------------------------------------------
; Procedura zamiany liczby z kodu BCD na B
; Wywolanie przez ACALL BCDB niszczy A,R1,R2,R3
;
BCDB: MOV R1,#BCD+LBCD
MOV R2,#LCZYN
PBCDB1: MOV @R1,#0
INC R1
DJNZ R2,PBCDB1
CLR C
MOV R2,#LBIN*8 ;ilosc bitow do przesuniecia w B
PP2: MOV R3,#LBCD+LBIN ; -"- bajtow do dzielenia w BCDB
MOV R1,#BCD
PLOP2: MOV A,@R1 ;petla dzielaca BUFBCD/2
RRC A
MOV @R1,A
INC R1
DJNZ R3,PLOP2
DJNZ R2,DAL1
RET ;koniec przeliczenia
DAL1: MOV R3,#LBCD ;ilosc bajtow do korekcji w BCD
MOV R1,#BCD
PLOP5: MOV A,@R1 ;korekcja biezacego bajtu
ANL A,#80H
JZ POMIT1
MOV A,@R1
ANL A,#7FH
ADD A,#50H ;korekcja nibla H
MOV @R1,A
POMIT1: MOV A,@R1
ANL A,#8
JZ POMIT2
MOV A,#0F7H
ANL A,@R1
ADD A,#5 ;korekcja nibla L
MOV @R1,A
POMIT2: INC R1
DJNZ R3,PLOP5 ;do korekcji nastepnego bajtu
AJMP PP2 ;nastepne dzielenie BUFBCD/2
;-----------------------
;Procedura dzieli 60M/T (60M=3938700h)
OBROTY: mov r0,#DZIELNA
; mov r1,#0
mov r2,#LCZYN*2
;Wpisanie 60M do Dzielnej
mov a,ILOSC_C
dec a
mov b,#6
mul ab
mov r1,a
W60M: mov a,r1
acall DaneObroty
mov @r0,a
inc r0
inc r1
djnz r2,W60M
;przepisanie CZASTn do DZIELNIKa
mov r0,#DZIELNIK+LCZYN*2-1
mov r1,#CZAST1
mov r2,#LCZYN
CD: mov a,@r1
mov @r0,a
dec r0
dec r1
djnz r2,CD
mov r2,#LCZYN
CD1: mov @r0,#0
dec r0
djnz r2,CD1
acall DZIEL
;Przepisanie Wyniku z Dzielenia do BIN
mov r0,#WYNIKD+LCZYN*2-1
mov r1,#BIN+LCZYN-1
mov r2,#LCZYN
PWD: mov a,@r0
mov @r1,a
dec r0
dec r1
djnz r2,PWD
;Przeliczenie z Bin na BCD
acall BBCD
ret
DaneObroty:
inc a
movc a,@a+PC
ret
db 0,0,3,93h,87h,0 ;Cyl=1 (1 zaplon na 1 obrot)
db 0,0,7,27h,0eh,0 ;Cyl=2 (1 zaplon na 2 obroty)
;
;Procedura obliczania kata wyprzedzenia
;kat = 360*TA/T
KAT: acall Set360
mov a,ILOSC_C
cjne a,#2,KAT1
acall Set720
KAT1: acall MovTA
acall MUL
acall MovT
acall DZIEL
acall MovWyD
acall BBCD
ret
Set360: mov CZYNIK1,#0 ;360
mov CZYNIK1+1,#1
mov CZYNIK1+2,#68h
ret
Set720: mov CZYNIK1,#0 ;720
mov CZYNIK1+1,#2
mov CZYNIK1+2,#0d0h
ret
MovTA: mov CZYNIK2,TA ;CZASTA3
mov CZYNIK2+1,TA+1 ;CZASTA2
mov CZYNIK2+2,TA+2 ;CZASTA1
ret
MovT: mov DZIELNIK,#0
mov DZIELNIK+1,#0
mov DZIELNIK+2,#0
mov DZIELNIK+3,T
mov DZIELNIK+4,T+1
mov DZIELNIK+5,T+2
ret
MovWyD: mov BIN,WYNIKD+3
mov BIN+1,WYNIKD+4
mov BIN+2,WYNIKD+5
ret
MovBcdDO:
mov DISPO+1,BCD+LBCD-1
mov DISPO,BCD+LBCD-2
ret
MovBcdDK:
mov DISPK+1,BCD+LBCD-1
mov DISPK,BCD+LBCD-2
ret
;-------------
D_KAT: ;wyswietlanie KATA
mov r0,#DISPK
ajmp D_O2
;-------------
D_OBROTY: ;wyswietlanie OBROTOW
mov r0,#DISPO
D_O2: mov r1,#DISP
mov r2,#2
D_O1: mov a,@r0
swap a
acall TabKon
mov @r1,a
inc r1
mov a,@r0
acall TabKon
mov @r1,a
inc r0
inc r1
djnz r2,D_O1
ret
;-------------
;Tablica Konwersji Nibla na kod 7-segmentowy
;D7 . . . . . . D0 ; a
; __
;h g f e d c b a ;f|__| b
;e|__| c
; d 'h
TabKon: anl a,#0fh
add a,#2
movc a,@a+PC
cpl a
ret ; hgfedcba
db 00111111b ;0
db 00000110b ;1
db 01011011b ;2
db 01001111b ;3
db 01100110b ;4
db 01101101b ;5
db 01111101b ;6
db 00000111b ;7
db 01111111b ;8
db 01101111b ;9
db 01110111b ;A
db 01111100b ;b
db 00111001b ;C
db 01011110b ;d
db 01111001b ;E
db 01110001b ;F
;-----------
POCZ_D: mov r0,#DISP
mov r1,#1
mov r2,#4
POCZ1: mov a,r1
acall POCZ2
cpl a
mov @r0,a
inc r0
inc r1
djnz r2,POCZ1
ret
POCZ2: movc a,@a+PC
ret
db 01000000b ;"-"
db 11101101b ;"S."
db 11111001b ;"E."
db 01000000b ;"-"
;----------
DKEY: mov a,KEY
jnz ZNAK
mov OLDKEY,a
ret ;brak znaku
ZNAK: cjne a,OLDKEY,NOWY
clr a
ret ;brak znaku
NOWY: mov OLDKEY,a
ret ;jest znak
;------------
POBROTY:
acall OBROTY
acall MovBcdDO
clr STATUS.2 ;zwalnia wpis do CZASTn
acall D_OBROTY
ajmp START
PKAT: acall KAT
acall MovBcdDK
clr STATUS.1
acall D_KAT
ajmp START
;----------
KATY: mov DISP,#11000110b ;C
ajmp CYL4
;----------
CYLINDRY:
mov DISP,#10100011b ;o
CYL4: mov DISP+1,#255
mov DISP+2,#255
CYL2: mov a,ILOSC_C
acall TabKon
mov DISP+3,a
CYL1: acall DKEY
jz CYL1
cjne a,#16,NIE_16
CYL: cpl psw.5
jb psw.5,KATY
ajmp CYLINDRY
NIE_16: cjne a,#4,NIE_4
ajmp CYL
NIE_4: cjne a,#8,NIE_G
CYL3: mov a,ILOSC_C
xrl a,#3
mov ILOSC_C,a
ajmp CYL2
NIE_G: cjne a,#2,NIE_D
ajmp CYL3
NIE_D: cjne a,#1,CYL1
acall POCZ_D
ret
;===================================================
INIT: mov sp,#STOS
mov STATUS,#0c0h ;bity 6 i 7 = "1"
mov TL1,#CZ5ms&255 ;okolo 5ms dla 12MHz
mov TH1,#CZ5ms/256
mov TMOD,#11h
mov TCON,#55h
mov IE,#10001011b
mov ILOSC_C,#1
acall POCZ_D
;========================
START: jb psw.5,START1
jb STATUS.2,POBROTY
START2: acall DKEY
jz START
cjne a,#1,START ;klawisz "O"
acall WYBIERZ
ajmp START
START1: jb STATUS.1,PKAT
ajmp START2
WYBIERZ:
jb psw.5,P_KATY
acall CYLINDRY
ajmp START
P_KATY: acall KATY
ajmp START
end