TESTY
Proste programy testowe LCD dla mikrokontrolera 8051
📝 Test 1 - Wyświetlenie pojedynczego znaku
assembly
;==============================================================
; TEST 1: Wyświetlenie jednego znaku 'X' na LCD
; Cel: Sprawdzenie czy LCD działa poprawnie
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define INITDISP 0x38
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- MAKRA ---
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
; --- PROGRAM GŁÓWNY ---
start:
init_LCD ; Inicjalizacja LCD
mov a, #'X' ; Załaduj znak 'X' do akumulatora
LCDcharWR ; Wyświetl znak
jmp $ ; Zatrzymaj program
end start
Wynik na LCD:
text
┌────────────────┐
│X │
│ │
└────────────────┘
📝 Test 2 - Wyświetlenie tekstu w obu liniach
assembly
;==============================================================
; TEST 2: Tekst w linii 1 i linii 2
; Cel: Test przełączania między liniami LCD
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- TEKSTY ---
linia1: db "Linia 1 - gora",00
linia2: db "Linia 2 - dol",00
; --- MAKRA ---
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 ---
putcharLCD:
LCDcharWR
ret
putstrLCD:
clr a
movc a, @a+dptr
jz koniec
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
koniec: ret
; --- PROGRAM GŁÓWNY ---
start:
init_LCD
; Wyświetl tekst w linii 1
LCDcntrlWR #HOME ; Kursor na początek linii 1
mov dptr, #linia1
acall putstrLCD
; Wyświetl tekst w linii 2
LCDcntrlWR #HOM2 ; Kursor na początek linii 2
mov dptr, #linia2
acall putstrLCD
jmp $
end start
Wynik na LCD:
text
┌────────────────┐
│Linia 1 - gora │
│Linia 2 - dol │
└────────────────┘
📝 Test 3 - Wypełnienie całego LCD
assembly
;==============================================================
; TEST 3: Wypełnienie całego wyświetlacza znakami
; Cel: Test wszystkich 32 pozycji (16x2)
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- MAKRA ---
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
; --- PROGRAM GŁÓWNY ---
start:
init_LCD
; Linia 1: 16 znaków 'A'
LCDcntrlWR #HOME
mov r0, #16 ; Licznik: 16 znaków
fill1:
mov a, #'A'
LCDcharWR
djnz r0, fill1
; Linia 2: 16 znaków 'B'
LCDcntrlWR #HOM2
mov r0, #16
fill2:
mov a, #'B'
LCDcharWR
djnz r0, fill2
jmp $
end start
Wynik na LCD:
text
┌────────────────┐
│AAAAAAAAAAAAAAAA│
│BBBBBBBBBBBBBBBB│
└────────────────┘
📝 Test 4 - Liczby i znaki specjalne
assembly
;==============================================================
; TEST 4: Wyświetlanie cyfr 0-9 i znaków specjalnych
; Cel: Test różnych kodów ASCII
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- MAKRA ---
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
; --- PROGRAM GŁÓWNY ---
start:
init_LCD
; Linia 1: Cyfry 0-9
LCDcntrlWR #HOME
mov a, #'0' ; Kod ASCII '0' = 0x30
mov r0, #10 ; 10 cyfr
cyfry:
LCDcharWR
inc a ; Następna cyfra
djnz r0, cyfry
; Linia 2: Znaki specjalne
LCDcntrlWR #HOM2
mov a, #'!'
LCDcharWR
mov a, #'@'
LCDcharWR
mov a, #'#'
LCDcharWR
mov a, #'$'
LCDcharWR
mov a, #'%'
LCDcharWR
mov a, #'^'
LCDcharWR
mov a, #'&'
LCDcharWR
mov a, #'*'
LCDcharWR
jmp $
end start
Wynik na LCD:
text
┌────────────────┐
│0123456789 │
│!@#$%^&* │
└────────────────┘
📝 Test 5 - Test opóźnienia i czyszczenia
assembly
;==============================================================
; TEST 5: Naprzemienne wyświetlanie dwóch tekstów
; Cel: Test funkcji CLEAR i opóźnienia
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- TEKSTY ---
tekst_a: db "=== TEST A ===",00
tekst_b: db "=== TEST B ===",00
; --- MAKRA ---
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 r0, #10H
d1: mov r1, #0FFH
d2: mov r2, #0FFH
d3: djnz r2, d3
djnz r1, d2
djnz r0, d1
ret
putcharLCD:
LCDcharWR
ret
putstrLCD:
clr a
movc a, @a+dptr
jz done
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
done: ret
; --- PROGRAM GŁÓWNY ---
start:
init_LCD
petla:
; Wyświetl tekst A
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #tekst_a
acall putstrLCD
acall delay
; Wyświetl tekst B
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #tekst_b
acall putstrLCD
acall delay
sjmp petla ; Powtarzaj w nieskończoność
end start
Wynik na LCD (animacja):
text
┌────────────────┐ ┌────────────────┐
│=== TEST A === │ ──► │=== TEST B === │ ──► (powtarza)
│ │ │ │
└────────────────┘ └────────────────┘
📝 Test 6 - Prosty licznik
assembly
;==============================================================
; TEST 6: Licznik 0-9 na LCD
; Cel: Test pętli i wyświetlania zmieniających się wartości
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
tekst: db "Licznik: ",00
; --- MAKRA ---
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 r0, #0AH
d1: mov r1, #0FFH
d2: mov r2, #0FFH
d3: djnz r2, d3
djnz r1, d2
djnz r0, d1
ret
putcharLCD:
LCDcharWR
ret
putstrLCD:
clr a
movc a, @a+dptr
jz done
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
done: ret
; --- PROGRAM GŁÓWNY ---
start:
init_LCD
licznik_loop:
mov r3, #'0' ; Rozpocznij od '0'
next_digit:
LCDcntrlWR #HOME
mov dptr, #tekst
acall putstrLCD
mov a, r3 ; Aktualna cyfra
LCDcharWR
acall delay
inc r3 ; Następna cyfra
cjne r3, #'9'+1, next_digit ; Jeśli nie przekroczono '9'
sjmp licznik_loop ; Zacznij od nowa
end start
Wynik na LCD (animacja):
text
Licznik: 0 → Licznik: 1 → ... → Licznik: 9 → Licznik: 0 (powtarza)
📝 Test 7 - Biegający znak
assembly
;==============================================================
; TEST 7: Animacja - znak przesuwający się po LCD
; Cel: Test pozycjonowania kursora
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- MAKRA ---
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 r0, #05H
d1: mov r1, #0FFH
d2: mov r2, #0FFH
d3: djnz r2, d3
djnz r1, d2
djnz r0, d1
ret
; --- PROGRAM GŁÓWNY ---
start:
init_LCD
animacja:
; Linia 1: ruch w prawo
mov r3, #HOME ; Pozycja startowa = 0x80
mov r4, #16 ; 16 pozycji
linia1_prawo:
LCDcntrlWR #CLEAR
mov a, r3
LCDcntrlWR a ; Ustaw kursor na pozycji r3
mov a, #'>' ; Znak strzałki w prawo
LCDcharWR
acall delay
inc r3
djnz r4, linia1_prawo
; Linia 2: ruch w prawo
mov r3, #HOM2 ; Pozycja = 0xC0 (linia 2)
mov r4, #16
linia2_prawo:
LCDcntrlWR #CLEAR
mov a, r3
LCDcntrlWR a
mov a, #'>'
LCDcharWR
acall delay
inc r3
djnz r4, linia2_prawo
sjmp animacja ; Powtarzaj
end start
Wynik na LCD (animacja):
text
Linia 1: >............... → .>.............. → ..>............. → ...
Linia 2: >............... → .>.............. → ...
📊 Podsumowanie testów
Test Opis Testowana funkcja
1 Pojedynczy znak Podstawowa komunikacja z LCD
2 Dwie linie Przełączanie HOME/HOM2
3 Wypełnienie Pętla i liczniki
4 Cyfry i znaki Kody ASCII
5 Czyszczenie CLEAR + delay
6 Licznik Zmienne wyświetlanie
7 Animacja Pozycjonowanie kursora
MATRIX
;==============================================================
; PROGRAM: "Matrix Hacker" - Animacja + Zabawny tekst
; Efekt: Symulacja "deszczu matrixa" + żartobliwe komunikaty
;==============================================================
ljmp start
LCDstatus equ 0FF2EH
LCDcontrol equ 0FF2CH
LCDdataWR equ 0FF2DH
#define HOME 0x80
#define INITDISP 0x38
#define HOM2 0xc0
#define LCDON 0x0e
#define CLEAR 0x01
org 0100H
; --- TEKSTY ---
intro1: db ">>> HACKING <<<",00
intro2: db "Please wait...",00
loading: db "||||||||||||||||",00 ; Pasek postępu
hack1: db "ACCESS DENIED!",00
hack2: db "Just kidding ;)",00
joke1: db "Kawa > Kod",00
joke2: db "Debuguj to! XD",00
final1: db "*** PTM LAB ***",00
final2: db "Ocena: 5.0 ? :D",00
; Znaki do animacji (pseudo-matrix)
matrix_chars: db "|/-\|/-\",00
;==============================================================
; MAKRA (takie same jak poprzednio)
;==============================================================
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
;==============================================================
; Krótkie opóźnienie
delay_short:
mov r0, #08H
ds1: mov r1, #0FFH
ds2: mov r2, #080H
ds3: djnz r2, ds3
djnz r1, ds2
djnz r0, ds1
ret
; Długie opóźnienie
delay_long:
mov r0, #20H
dl1: mov r1, #0FFH
dl2: mov r2, #0FFH
dl3: djnz r2, dl3
djnz r1, dl2
djnz r0, dl1
ret
; Wypisanie znaku
putcharLCD:
LCDcharWR
ret
; Wypisanie łańcucha
putstrLCD:
clr a
movc a, @a+dptr
jz str_end
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
str_end: ret
; Animacja spinnera (kręcące się kółko)
spinner:
mov r3, #08H ; 8 obrotów
spin_loop:
mov r4, #00H ; Indeks znaku
spin_char:
LCDcntrlWR #HOME ; Kursor na początek
mov a, r4
mov dptr, #matrix_chars
movc a, @a+dptr
jz spin_reset
acall putcharLCD
acall delay_short
inc r4
sjmp spin_char
spin_reset:
djnz r3, spin_loop
ret
; Animacja paska ładowania
progress_bar:
LCDcntrlWR #HOM2
mov r3, #10H ; 16 znaków
pb_loop:
mov a, #0FFH ; Pełny blok (lub użyj '#')
acall putcharLCD
acall delay_short
djnz r3, pb_loop
ret
; Efekt "migania" tekstu
blink_text:
mov r3, #03H ; 3 mignięcia
blink_loop:
LCDcntrlWR #CLEAR
acall delay_short
mov dptr, #hack1
LCDcntrlWR #HOME
acall putstrLCD
acall delay_short
djnz r3, blink_loop
ret
;==============================================================
; PROGRAM GŁÓWNY
;==============================================================
start:
init_LCD
;--- SCENA 1: Intro "Hacking" ---
mov dptr, #intro1
acall putstrLCD
LCDcntrlWR #HOM2
mov dptr, #intro2
acall putstrLCD
acall delay_long
;--- SCENA 2: Pasek ładowania ---
LCDcntrlWR #CLEAR
mov a, #'['
acall putcharLCD
mov dptr, #loading
acall putstrLCD ; Symulacja ładowania
mov a, #']'
acall putcharLCD
; Animowany pasek
LCDcntrlWR #HOM2
acall progress_bar
acall delay_long
;--- SCENA 3: "Błąd" + żart ---
acall blink_text
acall delay_short
LCDcntrlWR #HOM2
mov dptr, #hack2
acall putstrLCD
acall delay_long
;--- SCENA 4: Żarty programistyczne ---
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #joke1
acall putstrLCD
LCDcntrlWR #HOM2
mov dptr, #joke2
acall putstrLCD
acall delay_long
;--- SCENA 5: Końcowy komunikat ---
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #final1
acall putstrLCD
LCDcntrlWR #HOM2
mov dptr, #final2
acall putstrLCD
; Pętla nieskończona
nop
nop
jmp $
end start
ZAD1
ljmp start
LCDstatus equ 0FF2EH ; adres do odczytu gotowosci LCD
LCDcontrol equ 0FF2CH ; adres do podania bajtu sterujacego LCD
LCDdataWR equ 0FF2DH ; adres do podania kodu ASCII na LCD
// bajty sterujace LCD, inne dostepne w opisie LCD na stronie WWW
#define HOME 0x80 // put cursor to second line
#define INITDISP 0x38 // LCD init (8-bit mode)
#define HOM2 0xc0 // put cursor to second line
#define LCDON 0x0e // LCD nn, cursor off, blinking off
#define CLEAR 0x01 // LCD display clear
org 0100H
// deklaracje tekstów
text1: db "dwa",00
text2: db "jeden",00
text3: db "trzy",00
text4: db "siedem",00
// macro do wprowadzenia bajtu sterujacego na LCD
LCDcntrlWR MACRO x ; x – parametr wywolania macra – bajt sterujacy
LOCAL loop ; LOCAL oznacza ze etykieta loop moze sie powtórzyc w programie
loop: MOV DPTR,#LCDstatus ; DPTR zaladowany adresem statusu
MOVX A,@DPTR ; pobranie bajtu z biezacym statusem LCD
JB ACC.7,loop ; testowanie najstarszego bitu akumulatora
; – wskazuje gotowosc LCD
MOV DPTR,#LCDcontrol ; DPTR zaladowany adresem do podania bajtu sterujacego
MOV A, x ; do akumulatora trafia argument wywolania macra–bajt sterujacy
MOVX @DPTR,A ; bajt sterujacy podany do LCD – zadana akcja widoczna na LCD
ENDM
// macro do wypisania znaku ASCII na LCD, znak ASCII przed wywolaniem macra ma byc w A
LCDcharWR MACRO
LOCAL tutu ; LOCAL oznacza ze etykieta tutu moze sie powtórzyc w programie
PUSH ACC ; odlozenie biezacej zawartosci akumulatora na stos
tutu: MOV DPTR,#LCDstatus ; DPTR zaladowany adresem statusu
MOVX A,@DPTR ; pobranie bajtu z biezacym statusem LCD
JB ACC.7,tutu ; testowanie najstarszego bitu akumulatora
; – wskazuje gotowosc LCD
MOV DPTR,#LCDdataWR ; DPTR zaladowany adresem do podania bajtu sterujacego
POP ACC ; w akumulatorze ponownie kod ASCII znaku na LCD
MOVX @DPTR,A ; kod ASCII podany do LCD – znak widoczny na LCD
ENDM
// macro do inicjalizacji wyswietlacza – bez parametrów
init_LCD MACRO
LCDcntrlWR #INITDISP ; wywolanie macra LCDcntrlWR – inicjalizacja LCD
LCDcntrlWR #CLEAR ; wywolanie macra LCDcntrlWR – czyszczenie LCD
LCDcntrlWR #LCDON ; wywolanie macra LCDcntrlWR – konfiguracja kursora
ENDM
// funkcja opóznienia
delay: mov r0, #15H
one: mov r1, #0FFH
dwa: mov r2, #0FFH
trzy: djnz r2, trzy
djnz r1, dwa
djnz r0, one
ret
// funkcja wypisania znaku
putcharLCD: LCDcharWR
ret
//funkcja wypisania lancucha znaków
putstrLCD: clr a
movc a, @a+dptr
jz koniec
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
koniec: ret
przycisk1: LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #text1
acall putstrLCD
acall delay
ljmp begin
przycisk2: LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #text2
acall putstrLCD
acall delay
ljmp begin
przycisk3: LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #text3
acall putstrLCD
ljmp begin
przycisk4: LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #text4
acall putstrLCD
acall delay
ljmp begin
// program glówny
start: init_LCD
begin: clr c
mov a, p3
subb a, #0cfh ; 1100 1111 - koniec
jz finito
mov a, p3
subb a, #0dfh ; 1101 1111
jnz omin1
skok1:
ljmp przycisk1
omin1:
mov a, p3
subb a, #0efh ; 1110 1111
jnz omin2
skok2:
ljmp przycisk2
omin2:
mov a, p3
subb a, #0f7h ; 1111 0111
jnz omin3
skok3:
ljmp przycisk3
omin3:
mov a, p3
subb a, #0fbh ; 1111 1011
jnz omin4
skok4:
ljmp przycisk4
omin4:
sjmp begin
finito: LCDcntrlWR #CLEAR
nop
nop
nop
jmp $
end start
ZAD2
ljmp start
LCDstatus equ 0FF2EH ; adres do odczytu gotowosci LCD
LCDcontrol equ 0FF2CH ; adres do podania bajtu sterujacego LCD
LCDdataWR equ 0FF2DH ; adres do podania kodu ASCII na LCD
; bajty sterujace LCD
#define HOME 0x80 ; kursor na poczatek linii 1
#define INITDISP 0x38 ; LCD init (8-bit mode)
#define HOM2 0xc0 ; kursor na poczatek linii 2
#define LCDON 0x0e ; LCD on, cursor off, blinking off
#define CLEAR 0x01 ; LCD display clear
org 0100H
; Dlugi lancuch znakow (znacznie wiecej niz 16 znakow)
long_text: db "Witamy w laboratorium systemow mikroprocesorowych. "
db "Pracujemy z mikrokontrolerem 80C537 firmy Siemens. "
db "Wyswietlacz LCD HD44780 posiada dwie linie po 16 znakow. "
db "Program demonstruje przewijanie dlugiego tekstu stronami. "
db "To jest koniec wiadomosci - dziekujemy za uwage!",0
; Teksty koncowe
end_msg1: db "=== KONIEC ===",0
end_msg2: db "Tekst wyswietl.",0
; Zmienne w pamieci RAM
text_ptr_l equ 30H ; mlodszy bajt wskaznika tekstu
text_ptr_h equ 31H ; starszy bajt wskaznika tekstu
; macro do wprowadzenia bajtu sterujacego na 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
; macro do wypisania znaku ASCII na LCD
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
; macro do inicjalizacji wyswietlacza
init_LCD MACRO
LCDcntrlWR #INITDISP
LCDcntrlWR #CLEAR
LCDcntrlWR #LCDON
ENDM
; funkcja opoznienia (pauza miedzy stronami - ok. 2 sekundy)
delay_long:
mov r0, #30H ; dluzsza pauza
long_one: mov r1, #0FFH
long_two: mov r2, #0FFH
long_three: djnz r2, long_three
djnz r1, long_two
djnz r0, long_one
ret
; funkcja opoznienia (krotka - koncowa)
delay: mov r0, #15H
one: mov r1, #0FFH
dwa: mov r2, #0FFH
trzy: djnz r2, trzy
djnz r1, dwa
djnz r0, one
ret
; funkcja wypisania znaku
putcharLCD: LCDcharWR
ret
; funkcja wypisania lancucha znakow (zwykla)
putstrLCD: clr a
movc a, @a+dptr
jz str_end
push dph
push dpl
acall putcharLCD
pop dpl
pop dph
inc dptr
sjmp putstrLCD
str_end: ret
;===============================================================================
; Funkcja wypisania dokladnie 16 znakow (lub mniej jesli koniec tekstu)
; Wejscie: DPTR = wskaznik na tekst
; Wyjscie: DPTR = wskaznik na nastepny znak po wypisanych
; A = ostatni pobrany znak (0 jesli koniec tekstu)
; R7 = liczba wypisanych znakow
;===============================================================================
put16chars:
mov r7, #16 ; licznik 16 znakow
put16_loop:
clr a
movc a, @a+dptr ; pobierz znak
jz put16_end ; jesli 0, koniec tekstu
push dph
push dpl
acall putcharLCD ; wypisz znak
pop dpl
pop dph
inc dptr ; nastepny znak
djnz r7, put16_loop ; powtorz 16 razy
put16_end:
ret
;===============================================================================
; PROGRAM GLOWNY
;===============================================================================
start:
init_LCD
; Inicjalizacja wskaznika tekstu
mov text_ptr_l, #LOW(long_text)
mov text_ptr_h, #HIGH(long_text)
;-------------------------------------------------------------------------------
; Glowna petla wyswietlania stron
;-------------------------------------------------------------------------------
display_loop:
; Czyszczenie LCD i ustawienie kursora na linie 1
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
; Zaladuj wskaznik z pamieci RAM do DPTR
mov dph, text_ptr_h
mov dpl, text_ptr_l
;-------------------------------------------------------------------
; Wyswietlanie pierwszej linii (16 znakow)
;-------------------------------------------------------------------
acall put16chars
; Sprawdz czy koniec tekstu
clr a
movc a, @a+dptr
jz end_of_text
; Zapisz biezacy wskaznik
mov text_ptr_l, dpl
mov text_ptr_h, dph
;-------------------------------------------------------------------
; Przejscie do drugiej linii LCD
;-------------------------------------------------------------------
LCDcntrlWR #HOM2
; Zaladuj wskaznik
mov dph, text_ptr_h
mov dpl, text_ptr_l
;-------------------------------------------------------------------
; Wyswietlanie drugiej linii (16 znakow)
;-------------------------------------------------------------------
acall put16chars
; Zapisz biezacy wskaznik
mov text_ptr_l, dpl
mov text_ptr_h, dph
; Sprawdz czy koniec tekstu
clr a
movc a, @a+dptr
jz end_of_text
;-------------------------------------------------------------------
; Pauza miedzy stronami
;-------------------------------------------------------------------
acall delay_long
; Kontynuuj z nastepna strona
sjmp display_loop
;-------------------------------------------------------------------------------
; Koniec tekstu - wyswietl komunikat koncowy
;-------------------------------------------------------------------------------
end_of_text:
; Pauza koncowa (zeby zobaczyc ostatnia strone)
acall delay_long
; Wyswietl komunikat koncowy
LCDcntrlWR #CLEAR
LCDcntrlWR #HOME
mov dptr, #end_msg1
acall putstrLCD
LCDcntrlWR #HOM2
mov dptr, #end_msg2
acall putstrLCD
acall delay_long
; Zatrzymanie programu
nop
nop
nop
jmp $
end start