Zadanie 1: Trzy zestawy znaków przełączane klawiszami *, #, D
ljmp start
P5 equ 0F8H
P7 equ 0DBH
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
#define LINE_1 0x7f
#define LINE_2 0xbf
#define LINE_3 0xdf
#define LINE_4 0xef
org 0100H
; ============================================================================
; MAKRA LCD
; ============================================================================
LCDcntrlWR MACRO x
LOCAL loop
loop: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,loop
MOV DPTR,#LCDcontrol
MOV A, x
MOVX @DPTR,A
ENDM
LCDcharWR MACRO
LOCAL tutu
PUSH ACC
tutu: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,tutu
MOV DPTR,#LCDdataWR
POP ACC
MOVX @DPTR,A
ENDM
init_LCD MACRO
LCDcntrlWR #INITDISP
LCDcntrlWR #CLEAR
LCDcntrlWR #LCDON
ENDM
; ============================================================================
; FUNKCJE
; ============================================================================
delay: mov r1, #0FFH
dwa: mov r2, #0FFH
trzy: djnz r2, trzy
djnz r1, dwa
ret
putcharLCD: LCDcharWR
ret
; ============================================================================
; TABLICA - MALE LITERY (a-m dla klawiszy 0-9, A, B, C)
; ============================================================================
keyascii_lower:
mov dptr, #80EBH
mov a, #"a"
movx @dptr, a
mov dptr, #8077H
mov a, #"b"
movx @dptr, a
mov dptr, #807BH
mov a, #"c"
movx @dptr, a
mov dptr, #807DH
mov a, #"d"
movx @dptr, a
mov dptr, #80B7H
mov a, #"e"
movx @dptr, a
mov dptr, #80BBH
mov a, #"f"
movx @dptr, a
mov dptr, #80BDH
mov a, #"g"
movx @dptr, a
mov dptr, #80D7H
mov a, #"h"
movx @dptr, a
mov dptr, #80DBH
mov a, #"i"
movx @dptr, a
mov dptr, #80DDH
mov a, #"j"
movx @dptr, a
mov dptr, #807EH
mov a, #"k"
movx @dptr, a
mov dptr, #80BEH
mov a, #"l"
movx @dptr, a
mov dptr, #80DEH
mov a, #"m"
movx @dptr, a
ret
; ============================================================================
; TABLICA - DUZE LITERY (A-M)
; ============================================================================
keyascii_upper:
mov dptr, #80EBH
mov a, #"A"
movx @dptr, a
mov dptr, #8077H
mov a, #"B"
movx @dptr, a
mov dptr, #807BH
mov a, #"C"
movx @dptr, a
mov dptr, #807DH
mov a, #"D"
movx @dptr, a
mov dptr, #80B7H
mov a, #"E"
movx @dptr, a
mov dptr, #80BBH
mov a, #"F"
movx @dptr, a
mov dptr, #80BDH
mov a, #"G"
movx @dptr, a
mov dptr, #80D7H
mov a, #"H"
movx @dptr, a
mov dptr, #80DBH
mov a, #"I"
movx @dptr, a
mov dptr, #80DDH
mov a, #"J"
movx @dptr, a
mov dptr, #807EH
mov a, #"K"
movx @dptr, a
mov dptr, #80BEH
mov a, #"L"
movx @dptr, a
mov dptr, #80DEH
mov a, #"M"
movx @dptr, a
ret
; ============================================================================
; TABLICA - CYFRY (0-9, A, B, C)
; ============================================================================
keyascii_num:
mov dptr, #80EBH
mov a, #"0"
movx @dptr, a
mov dptr, #8077H
mov a, #"1"
movx @dptr, a
mov dptr, #807BH
mov a, #"2"
movx @dptr, a
mov dptr, #807DH
mov a, #"3"
movx @dptr, a
mov dptr, #80B7H
mov a, #"4"
movx @dptr, a
mov dptr, #80BBH
mov a, #"5"
movx @dptr, a
mov dptr, #80BDH
mov a, #"6"
movx @dptr, a
mov dptr, #80D7H
mov a, #"7"
movx @dptr, a
mov dptr, #80DBH
mov a, #"8"
movx @dptr, a
mov dptr, #80DDH
mov a, #"9"
movx @dptr, a
mov dptr, #807EH
mov a, #"A"
movx @dptr, a
mov dptr, #80BEH
mov a, #"B"
movx @dptr, a
mov dptr, #80DEH
mov a, #"C"
movx @dptr, a
ret
; ============================================================================
; PROGRAM GLOWNY
; ============================================================================
start:
init_LCD
acall keyascii_lower ; domyslnie male litery
mov r7, #10H ; licznik znakow
mov r6, #01H ; flaga linii
; ============================================================================
; SPRAWDZANIE POZYCJI NA LCD
; ============================================================================
check_chars:
mov a, r7
jz check_line
jmp key_1
check_line:
mov a, r6
jnz set_line2
set_line1:
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov r7, #10H
mov r6, #01H
jmp key_1
set_line2:
LCDcntrlWR #HOM2
mov r6, #00H
mov r7, #10H
; ============================================================================
; SKANOWANIE LINII 1
; ============================================================================
key_1:
mov r0, #LINE_1
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz key_2
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
; ============================================================================
; SKANOWANIE LINII 2
; ============================================================================
key_2:
mov r0, #LINE_2
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz key_3
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
; ============================================================================
; SKANOWANIE LINII 3
; ============================================================================
key_3:
mov r0, #LINE_3
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz key_4
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
; ============================================================================
; SKANOWANIE LINII 4 - Z OBSLUGA KLAWISZY SPECJALNYCH
; ============================================================================
key_4:
mov r0, #LINE_4
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz jump_check ; brak klawisza
; Sprawdz czy * (kod E7H) -> male litery
mov a, r2
clr c
subb a, #0E7H
jz to_lower
; Sprawdz czy # (kod EDH) -> duze litery
mov a, r2
clr c
subb a, #0EDH
jz to_upper
; Sprawdz czy D (kod EEH) -> cyfry
mov a, r2
clr c
subb a, #0EEH
jz to_num
; Normalny klawisz - wyswietl
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
ljmp check_chars
jump_check:
ljmp check_chars
; ============================================================================
; PRZELACZANIE ZESTAWOW ZNAKOW
; ============================================================================
to_lower:
acall keyascii_lower
acall delay ; opoznienie zeby nie powtarzac
ljmp check_chars
to_upper:
acall keyascii_upper
acall delay
ljmp check_chars
to_num:
acall keyascii_num
acall delay
ljmp check_chars
nop
nop
nop
jmp $
end start
Zadanie 2: Wyświetlanie tekstu z klawiatury z przewijaniem
ljmp start
P5 equ 0F8H
P7 equ 0DBH
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
#define LINE_1 0x7f
#define LINE_2 0xbf
#define LINE_3 0xdf
#define LINE_4 0xef
org 0100H
; ============================================================================
; MAKRA LCD
; ============================================================================
LCDcntrlWR MACRO x
LOCAL loop
loop: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,loop
MOV DPTR,#LCDcontrol
MOV A, x
MOVX @DPTR,A
ENDM
LCDcharWR MACRO
LOCAL tutu
PUSH ACC
tutu: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,tutu
MOV DPTR,#LCDdataWR
POP ACC
MOVX @DPTR,A
ENDM
init_LCD MACRO
LCDcntrlWR #INITDISP
LCDcntrlWR #CLEAR
LCDcntrlWR #LCDON
ENDM
; ============================================================================
; FUNKCJE
; ============================================================================
delay: mov r1, #0FFH
dwa: mov r2, #0FFH
trzy: djnz r2, trzy
djnz r1, dwa
ret
putcharLCD: LCDcharWR
ret
; ============================================================================
; TABLICA PRZEKODOWAN
; ============================================================================
keyascii:
mov dptr, #80EBH
mov a, #"0"
movx @dptr, a
mov dptr, #8077H
mov a, #"1"
movx @dptr, a
mov dptr, #807BH
mov a, #"2"
movx @dptr, a
mov dptr, #807DH
mov a, #"3"
movx @dptr, a
mov dptr, #80B7H
mov a, #"4"
movx @dptr, a
mov dptr, #80BBH
mov a, #"5"
movx @dptr, a
mov dptr, #80BDH
mov a, #"6"
movx @dptr, a
mov dptr, #80D7H
mov a, #"7"
movx @dptr, a
mov dptr, #80DBH
mov a, #"8"
movx @dptr, a
mov dptr, #80DDH
mov a, #"9"
movx @dptr, a
mov dptr, #807EH
mov a, #"A"
movx @dptr, a
mov dptr, #80BEH
mov a, #"B"
movx @dptr, a
mov dptr, #80DEH
mov a, #"C"
movx @dptr, a
mov dptr, #80EEH
mov a, #"D"
movx @dptr, a
mov dptr, #80E7H
mov a, #"*"
movx @dptr, a
mov dptr, #80EDH
mov a, #"#"
movx @dptr, a
ret
; ============================================================================
; PROGRAM GLOWNY
; ============================================================================
start:
init_LCD
acall keyascii
mov r7, #10H ; licznik znakow w linii (16)
mov r6, #01H ; flaga linii (1=linia1, 0=linia2)
; ============================================================================
; SPRAWDZANIE POZYCJI NA LCD
; ============================================================================
check_chars:
mov a, r7
jz check_line
jmp key_1
check_line:
mov a, r6
jnz set_line2
set_line1:
; Po 32 znakach - czysc i zacznij od nowa
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov r7, #10H
mov r6, #01H
jmp key_1
set_line2:
; Po 16 znakach - przejdz do linii 2
LCDcntrlWR #HOM2
mov r6, #00H
mov r7, #10H
; ============================================================================
; SKANOWANIE LINII 1
; ============================================================================
key_1:
mov r0, #LINE_1
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz key_2
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
; ============================================================================
; SKANOWANIE LINII 2
; ============================================================================
key_2:
mov r0, #LINE_2
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz key_3
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
; ============================================================================
; SKANOWANIE LINII 3
; ============================================================================
key_3:
mov r0, #LINE_3
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz key_4
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
; ============================================================================
; SKANOWANIE LINII 4
; ============================================================================
key_4:
mov r0, #LINE_4
mov a, r0
mov P5, a
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz jump_check
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr
mov P1, a
acall putcharLCD
acall delay
dec r7
ljmp check_chars
jump_check:
ljmp check_chars
nop
nop
nop
jmp $
end start
Zadanie 3: Wyłączenie repetycji klawisza
ljmp start
P5 equ 0F8H
P7 equ 0DBH
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
#define LINE_1 0x7f
#define LINE_2 0xbf
#define LINE_3 0xdf
#define LINE_4 0xef
org 0100H
; ============================================================================
; MAKRA LCD
; ============================================================================
LCDcntrlWR MACRO x
LOCAL loop
loop: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,loop
MOV DPTR,#LCDcontrol
MOV A, x
MOVX @DPTR,A
ENDM
LCDcharWR MACRO
LOCAL tutu
PUSH ACC
tutu: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,tutu
MOV DPTR,#LCDdataWR
POP ACC
MOVX @DPTR,A
ENDM
init_LCD MACRO
LCDcntrlWR #INITDISP
LCDcntrlWR #CLEAR
LCDcntrlWR #LCDON
ENDM
; ============================================================================
; FUNKCJE POMOCNICZE
; ============================================================================
delay: mov r1, #0FFH
dwa: mov r2, #0FFH
trzy: djnz r2, trzy
djnz r1, dwa
ret
putcharLCD: LCDcharWR
ret
; ============================================================================
; TABLICE PRZEKODOWANIA (Mapowanie kodów klawiatury na ASCII w XRAM)
; ============================================================================
keyascii_lower:
mov dptr, #80EBH
mov a, #"a"
movx @dptr, a
mov dptr, #8077H
mov a, #"b"
movx @dptr, a
mov dptr, #807BH
mov a, #"c"
movx @dptr, a
mov dptr, #807DH
mov a, #"d"
movx @dptr, a
mov dptr, #80B7H
mov a, #"e"
movx @dptr, a
mov dptr, #80BBH
mov a, #"f"
movx @dptr, a
mov dptr, #80BDH
mov a, #"g"
movx @dptr, a
mov dptr, #80D7H
mov a, #"h"
movx @dptr, a
mov dptr, #80DBH
mov a, #"i"
movx @dptr, a
mov dptr, #80DDH
mov a, #"j"
movx @dptr, a
mov dptr, #807EH
mov a, #"k"
movx @dptr, a
mov dptr, #80BEH
mov a, #"l"
movx @dptr, a
mov dptr, #80DEH
mov a, #"m"
movx @dptr, a
ret
keyascii_upper:
mov dptr, #80EBH
mov a, #"A"
movx @dptr, a
mov dptr, #8077H
mov a, #"B"
movx @dptr, a
mov dptr, #807BH
mov a, #"C"
movx @dptr, a
mov dptr, #807DH
mov a, #"D"
movx @dptr, a
mov dptr, #80B7H
mov a, #"E"
movx @dptr, a
mov dptr, #80BBH
mov a, #"F"
movx @dptr, a
mov dptr, #80BDH
mov a, #"G"
movx @dptr, a
mov dptr, #80D7H
mov a, #"H"
movx @dptr, a
mov dptr, #80DBH
mov a, #"I"
movx @dptr, a
mov dptr, #80DDH
mov a, #"J"
movx @dptr, a
mov dptr, #807EH
mov a, #"K"
movx @dptr, a
mov dptr, #80BEH
mov a, #"L"
movx @dptr, a
mov dptr, #80DEH
mov a, #"M"
movx @dptr, a
ret
keyascii_num:
mov dptr, #80EBH
mov a, #"0"
movx @dptr, a
mov dptr, #8077H
mov a, #"1"
movx @dptr, a
mov dptr, #807BH
mov a, #"2"
movx @dptr, a
mov dptr, #807DH
mov a, #"3"
movx @dptr, a
mov dptr, #80B7H
mov a, #"4"
movx @dptr, a
mov dptr, #80BBH
mov a, #"5"
movx @dptr, a
mov dptr, #80BDH
mov a, #"6"
movx @dptr, a
mov dptr, #80D7H
mov a, #"7"
movx @dptr, a
mov dptr, #80DBH
mov a, #"8"
movx @dptr, a
mov dptr, #80DDH
mov a, #"9"
movx @dptr, a
mov dptr, #807EH
mov a, #"A"
movx @dptr, a
mov dptr, #80BEH
mov a, #"B"
movx @dptr, a
mov dptr, #80DEH
mov a, #"C"
movx @dptr, a
ret
; ============================================================================
; PROGRAM GŁÓWNY
; ============================================================================
start:
init_LCD
acall keyascii_lower ; Domyślnie małe litery
mov r5, #0 ; R5: Przechowuje ostatnio wciśnięty klawisz (anti-repetycja)
mov r7, #10H ; R7: Licznik znaków w linii
mov r6, #01H ; R6: Flaga aktualnej linii (1 lub 0)
; ============================================================================
; LOGIKA PRZEŁĄCZANIA LINII LCD
; ============================================================================
check_chars:
mov a, r7
jnz scan_start ; Jeśli r7 > 0, skanuj klawisze
; Jeśli linia się skończyła:
mov a, r6
jnz set_line2 ; Jeśli była linia 1, idź do 2
set_line1:
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov r7, #10H
mov r6, #01H
jmp scan_start
set_line2:
LCDcntrlWR #HOM2
mov r6, #00H
mov r7, #10H
; ============================================================================
; SKANOWANIE KLAWIATURY (Debouncing & Anti-repetition)
; ============================================================================
scan_start:
; Skanowanie wszystkich linii po kolei
; --- Linia 1 ---
mov r0, #LINE_1
acall scan_line
jnz key_found ; Jeśli A != 0, znaleziono klawisz
; --- Linia 2 ---
mov r0, #LINE_2
acall scan_line
jnz key_found
; --- Linia 3 ---
mov r0, #LINE_3
acall scan_line
jnz key_found
; --- Linia 4 ---
mov r0, #LINE_4
acall scan_line
jnz key_found
; Brak wciśniętego klawisza
mov r5, #0 ; Resetujemy pamięć poprzedniego klawisza
ljmp check_chars
; Podfunkcja skanująca konkretną linię (R0)
; Zwraca w akumulatorze kod klawisza lub 0
scan_line:
mov a, r0
mov P5, a ; Ustaw linię skanowania
mov a, P7
anl a, r0 ; Odczytaj stan
mov r2, a ; R2 = aktualny stan pinów
clr c
subb a, r0
jz no_key_in_line ; Jeśli wynik 0, nic nie wciśnięto
; Sprawdzenie anti-repetycji (czy to ten sam klawisz co przed chwilą?)
mov a, r2
clr c
subb a, r5
jz no_key_in_line ; Ten sam klawisz - zignoruj
; Debouncing (krótkie opóźnienie i ponowne sprawdzenie)
acall delay_short
mov a, P7
anl a, r0
mov r2, a
clr c
subb a, r0
jz no_key_in_line ; Drgania styków - fałszywy alarm
mov a, r2 ; Zwróć kod klawisza
ret
no_key_in_line:
mov a, #0
ret
delay_short: mov r3, #50H ; Krótkie opóźnienie dla debouncingu
djnz r3, $
ret
; ============================================================================
; OBSŁUGA ZNALEZIONEGO KLAWISZA
; ============================================================================
key_found:
mov r5, a ; Zapamiętaj klawisz w R5 (blokada powtórzeń)
mov r2, a ; R2 = kod klawisza do analizy
; 1. Sprawdź funkcje specjalne (Linia 4)
; * (E7H) -> małe litery
cjne a, #0E7H, check_upper
acall keyascii_lower
ljmp check_chars
check_upper:
; # (EDH) -> duże litery
mov a, r2
cjne a, #0EDH, check_num
acall keyascii_upper
ljmp check_chars
check_num:
; D (EEH) -> cyfry
mov a, r2
cjne a, #0EEH, print_normal
acall keyascii_num
ljmp check_chars
print_normal:
; 2. Wyświetl standardowy znak
mov a, r2
mov dph, #80H
mov dpl, a
movx a, @dptr ; Pobierz mapowanie ASCII
mov P1, a ; Diagnostyka na LED
acall putcharLCD ; Wyślij na LCD
dec r7 ; Zmniejsz licznik znaków w linii
acall delay
acall delay
acall delay
acall delay
ljmp check_chars
nop
jmp $
end start
BONUS: Kalkulator prosty (dodawanie dwóch cyfr)
ljmp start
P5 equ 0F8H
P7 equ 0DBH
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
#define LINE_1 0x7f
#define LINE_2 0xbf
#define LINE_3 0xdf
#define LINE_4 0xef
; zmienne w RAM
key_state equ 30H
last_scan equ 31H
num1 equ 32H ; pierwsza liczba (0-9)
num2 equ 33H ; druga liczba (0-9)
result equ 34H ; wynik
calc_state equ 35H ; stan kalkulatora: 0=czekaj na num1, 1=czekaj na num2, 2=pokaz wynik
org 0100H
; ============================================================================
; MAKRA LCD
; ============================================================================
LCDcntrlWR MACRO x
LOCAL loop
loop: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,loop
MOV DPTR,#LCDcontrol
MOV A, x
MOVX @DPTR,A
ENDM
LCDcharWR MACRO
LOCAL tutu
PUSH ACC
tutu: MOV DPTR,#LCDstatus
MOVX A,@DPTR
JB ACC.7,tutu
MOV DPTR,#LCDdataWR
POP ACC
MOVX @DPTR,A
ENDM
init_LCD MACRO
LCDcntrlWR #INITDISP
LCDcntrlWR #CLEAR
LCDcntrlWR #LCDON
ENDM
; ============================================================================
; DANE - komunikaty
; ============================================================================
msg_calc: db "KALKULATOR +",0
msg_num1: db "Podaj 1 liczbe:",0
msg_num2: db "Podaj 2 liczbe:",0
msg_result: db "Wynik: ",0
msg_clear: db "* = RESET",0
; ============================================================================
; TABLICA PRZEKODOWAN (tylko cyfry 0-9)
; ============================================================================
init_keys:
mov dptr, #80EBH
mov a, #0 ; '0' -> wartosc 0
movx @dptr, a
mov dptr, #8077H
mov a, #1 ; '1' -> wartosc 1
movx @dptr, a
mov dptr, #807BH
mov a, #2
movx @dptr, a
mov dptr, #807DH
mov a, #3
movx @dptr, a
mov dptr, #80B7H
mov a, #4
movx @dptr, a
mov dptr, #80BBH
mov a, #5
movx @dptr, a
mov dptr, #80BDH
mov a, #6
movx @dptr, a
mov dptr, #80D7H
mov a, #7
movx @dptr, a
mov dptr, #80DBH
mov a, #8
movx @dptr, a
mov dptr, #80DDH
mov a, #9
movx @dptr, a
; Klawisze specjalne
mov dptr, #80E7H ; '*' = reset
mov a, #0FEH
movx @dptr, a
mov dptr, #80EDH ; '#' = oblicz
mov a, #0FDH
movx @dptr, a
ret
; ============================================================================
; FUNKCJE POMOCNICZE
; ============================================================================
delay: mov r0, #10H
d_one: mov r1, #0FFH
d_two: mov r2, #0FFH
d_three: djnz r2, d_three
djnz r1, d_two
djnz r0, d_one
ret
delay_short:
mov r0, #03H
ds_one: mov r1, #0FFH
ds_two: djnz r1, ds_two
djnz r0, ds_one
ret
putcharLCD: LCDcharWR
ret
; Wyswietl string z pamieci programu
putstrLCD: clr a
movc a, @a+dptr
jz ps_end
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
ps_end: ret
; Wyswietl cyfre (0-9) na LCD
show_digit:
add a, #'0' ; konwersja na ASCII
acall putcharLCD
ret
; Wyswietl liczbe dwucyfrowa (0-18)
show_number:
mov b, #10
div ab ; A = dziesiatki, B = jednosci
jz only_units ; jesli dziesiatki = 0, pokaz tylko jednosci
add a, #'0'
acall putcharLCD
only_units:
mov a, b
add a, #'0'
acall putcharLCD
ret
; ============================================================================
; SKANOWANIE KLAWIATURY Z ANTI-REPETYCJA
; ============================================================================
scan_keyboard:
mov a, #LINE_1
mov P5, a
mov a, P7
anl a, #0FH
cjne a, #0FH, sk_l1
mov a, #LINE_2
mov P5, a
mov a, P7
anl a, #0FH
cjne a, #0FH, sk_l2
mov a, #LINE_3
mov P5, a
mov a, P7
anl a, #0FH
cjne a, #0FH, sk_l3
mov a, #LINE_4
mov P5, a
mov a, P7
anl a, #0FH
cjne a, #0FH, sk_l4
mov a, #0FFH
ret
sk_l1: orl a, #LINE_1
ret
sk_l2: orl a, #LINE_2
ret
sk_l3: orl a, #LINE_3
ret
sk_l4: orl a, #LINE_4
ret
get_key:
acall scan_keyboard
mov r4, a
mov a, key_state
jnz gk_pressed
gk_released:
mov a, r4
cjne a, #0FFH, gk_just_pressed
mov a, #0FFH
ret
gk_just_pressed:
acall delay_short
mov last_scan, r4
mov key_state, #1
mov a, #0FFH
ret
gk_pressed:
mov a, r4
cjne a, #0FFH, gk_still
acall delay_short
mov key_state, #0
mov a, last_scan
mov dph, #80H
mov dpl, a
movx a, @dptr
ret
gk_still: mov a, #0FFH
ret
; ============================================================================
; FUNKCJA RESETU KALKULATORA
; ============================================================================
reset_calc:
mov calc_state, #0
mov num1, #0
mov num2, #0
mov result, #0
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #msg_calc
acall putstrLCD
LCDcntrlWR #HOM2
mov dptr, #msg_num1
acall putstrLCD
ret
; ============================================================================
; PROGRAM GLOWNY
; ============================================================================
start:
init_LCD
acall init_keys
mov key_state, #0
acall reset_calc
; ============================================================================
; GLOWNA PETLA KALKULATORA
; ============================================================================
main_loop:
acall get_key
cjne a, #0FFH, process_input
sjmp main_loop
process_input:
; Sprawdz czy to reset (*)
cjne a, #0FEH, chk_equals
acall reset_calc
sjmp main_loop
chk_equals:
; Sprawdz czy to oblicz (#)
cjne a, #0FDH, chk_digit
; Oblicz wynik jesli mamy obie liczby
mov r5, a
mov a, calc_state
cjne a, #1, main_loop ; musimy byc w stanie 1
; Oblicz sume
mov a, num1
add a, num2
mov result, a
; Wyswietl wynik
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov a, num1
acall show_digit
mov a, #'+'
acall putcharLCD
mov a, num2
acall show_digit
mov a, #'='
acall putcharLCD
mov a, result
acall show_number
LCDcntrlWR #HOM2
mov dptr, #msg_clear
acall putstrLCD
mov calc_state, #2
sjmp main_loop
chk_digit:
; To musi byc cyfra (0-9)
mov r5, a ; wartosc cyfry
; Sprawdz w jakim jestesmy stanie
mov a, calc_state
cjne a, #0, state1
; Stan 0: czekamy na pierwsza liczbe
mov num1, r5
; Wyswietl na LCD
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov a, num1
acall show_digit
mov a, #' '
acall putcharLCD
mov a, #'+'
acall putcharLCD
mov a, #' '
acall putcharLCD
mov a, #'?'
acall putcharLCD
LCDcntrlWR #HOM2
mov dptr, #msg_num2
acall putstrLCD
mov calc_state, #1
sjmp main_loop
state1:
cjne a, #1, state2
; Stan 1: czekamy na druga liczbe
mov num2, r5
; Wyswietl na LCD
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov a, num1
acall show_digit
mov a, #' '
acall putcharLCD
mov a, #'+'
acall putcharLCD
mov a, #' '
acall putcharLCD
mov a, num2
acall show_digit
LCDcntrlWR #HOM2
mov a, #'#'
acall putcharLCD
mov a, #'='
acall putcharLCD
mov a, #'O'
acall putcharLCD
mov a, #'B'
acall putcharLCD
mov a, #'L'
acall putcharLCD
mov a, #'I'
acall putcharLCD
mov a, #'C'
acall putcharLCD
mov a, #'Z'
acall putcharLCD
sjmp main_loop
state2:
; Stan 2: wynik wyswietlony, czekamy na reset
sjmp main_loop
nop
nop
nop
jmp $
end start
https://github.com/Ite-2022-pwr/sem4-ptm1-lab-ak-mb/tree/master/lab4