Generowanie opóźnienia przy pomocy podwójnej pętli.
MOV R0, #05h
petla1:
MOV R1,#05h
petla2:
DJNZ R1, petla2
DJNZ R0, petla1
Zapalenie diody a następnie zgaszenie jej po 1,6s.
CLR P1.7 ; zapala diodę
MOV A, #10H ; wprowadza do akumulatora liczbę 16
LCALL DELAY_100MS ; czeka 1,6s – dioda świeci się
SETB P1.7 ; gasi diodę
L00: LJMP L00 ; kończy działanie programu
Zapalenie diody po czasie 1s, a następnie zgaszenie jej po 1s.
L00: MOV A, #0AH ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda nie świeci się
CLR P1.7 ; zapala diodę
MOV A, #0AH ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda świeci się
SETB P1.7 ; gasi diodę
LJMP L00 ; powtarza całą procedurę od L00
Zapalenie diody i zgaszenie w 1 sekundowych odstępach czasu. Program rozpoczyna się od zapalenia diody.
L00: CLR P1.7 ; zapala diodę
MOV A, #0AH ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda świeci się
SETB P1.7 ; gasi diodę
MOV A, #0AH ; wprowadza do akumulatora liczbę 10
LCALL DEL_100 ; czeka 1s – dioda nie świeci się
LJMP L00 ; powtarza całą procedurę od L00
Zapalenie diody na czas 1,5s i zgaszenie na 0,5s.
L00: CLR P1.7 ; zapala diodę
MOV A, #0FH ; wprowadza do akumulatora liczbę 15
LCALL DELAY_100MS ; czeka 1,5s – dioda świeci się
SETB P1.7 ; gasi diodę
MOV A, #05H ; wprowadza do akumulatora liczbę 5
LCALL DELAY_100MS ; czeka 0,5s – dioda nie świeci się
LJMP L00 ; powtarza całą procedurę od L00
Czyszczenie wyświetlacza przed wyświetleniem liczby z akumulatora.
LCALL LCD_CLR ; czyści wyświetlacz
MOV A, #10H ; wprowadza do akumulatora liczbę
LCALL WRITE_HEX ; wyświetla na wyświetlaczu liczbę z akumulatora
L00: LJMP L00 ; kończy działanie programu
Czyszczenie wyświetlacza przed wyświetleniem liczby z akumulatora, którą wcześniej zwiększono o 1.
LCALL LCD_CLR ; czyści wyświetlacz
MOV A, #10H ; wprowadza do akumulatora liczbę
INC A ; zwiększa liczbę z akumulatora o 1
LCALL WRITE_HEX ; wyświetla liczbę powiększoną o 1
L00: LJMP L00 ; kończy działanie programu
Liczba zapaleń diody jest zliczana i automatycznie wyświetlana.
MOV R0, #0 ; wprowadza do rejestru liczbę 0
L00: MOV A, #0AH ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s
CLR P1.7 ; zapala diodę
LCALL DELAY_100MS ; czeka 1s – dioda świeci się
SETB P1.7 ; gasi diodę
INC R0 ; zwiększa liczbę z rejestru o 1
MOV A, R0 ; przenosi liczbę z rejestru do akumulatora, aby ją wyświetlić
LCALL LCD_CLR ; czyści wyświetlacz
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
LJMP L00 ; powtarza całą procedurę od L00
Napisz program, który będzie powodował zaświecenie diody LED podłączonej do 7 linii w porcie P1 i krokontrolera 8051.
CLR P1.7 ; zapala diodę
L00: LJMP L00 ; kończy działanie programu
Zmodyfikuj program z polecenia 1) tak by dioda była na przemian zapalana i gaszona. Wykorzystaj podprogram realizujący opóźnienie DELAY_100MS. Parametr zwiększający czas opóźnienia jest przekazywany do tego podprogramu przez rejestr A.
L00: MOV A, #30 ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda nie świeci się
CLR P1.7 ; zapala diodę
MOV A, #30 ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda świeci się
SETB P1.7 ; gasi diodę
LJMP L00 ; powtarza całą procedurę od L00
Przekształć przykład 2) w ten sposób, by świecenie diody odbywało się na przemian z włączaniem brzęczyka podłączonego do linii piątej portu P1. Narysuj, algorytm działania tego programu. Zastosuj rozkazy odwołujące się do poszczególnych bitów w porcie.
L00: MOV A, #10 ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda nie świeci się
CLR P1.7 ; zapala diodę
MOV A, #10 ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s – dioda świeci się
SETB P1.7 ;
CLR P1.5 ; brzeczyk
MOV A, #10 ; wprowadza do akumulatora liczbę 10
LCALL DELAY_100MS ; czeka 1s
SETB P1.5 ;
LJMP L00 ; powtarza całą procedurę od L00
Napisz program, który będzie wyświetlał na wyświetlaczu LCD numery kolejnych banków rejestrów (0 - 3), zapisane wcześniej w poszczególnych rejestrach tych banków np. R7. Do czyszczenia wyświetlacza LCD służy procedura LCD_CLR. Procedura WRITE_HEX powoduje wyświetlenie na wyświetlaczu LCD zawartość akumulatora.
L00:
LCALL LCD_CLR ; czyści wyświetlacz
MOV R0, #00H
MOV A, R0
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #10
LCALL DELAY_100MS ;
LCALL LCD_CLR ; czyści wyświetlacz
MOV R1, #01H
MOV A, R1
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #10
LCALL DELAY_100MS ;
LCALL LCD_CLR ; czyści wyświetlacz
MOV R2, #02H
MOV A, R2
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #10
LCALL DELAY_100MS ;
LCALL LCD_CLR ; czyści wyświetlacz
MOV R3, #03H
MOV A, R3
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #10
LCALL DELAY_100MS ;
Pętla:
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
mov cx,5 ; ile razy ma być wykonana pętla (rejest CX)
Start:
mov ah, 9 ; jakie rozkazy w pętli tutaj..
loop Start
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Wyświetlanie znaku 'S' na ekranie.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,'S' ; S jest znakiem do wyświetlenia
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Odczytanie znaku z klawiatury.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,1 ; funkcja DOS odczytująca znaki z klawiatury
INT 21H ; wezwij DOS w celu wykonania tej funkcji (odczytaj znak)
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Odczytanie znaku z klawiatury i wyświetlenie go na ekranie.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,1 ; funkcja DOS odczytująca znaki z klawiatury
INT 21H ; wezwij DOS w celu wykonania tej funkcji (odczytaj znak)
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,AL ; przenieś znak (uzyskany z funkcji nr 1) z AL do DL
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Odczytanie znaków z klawiatury i wyświetlenie ich na ekranie.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,1 ; funkcja DOS odczytująca znaki z klawiatury
INT 21H ; wezwij DOS w celu wykonania tej funkcji (odczytaj znak)
CMP AL,13 ; czy naciśnięto klawisz [Enter]?
JZ Stop ; jeśli tak to idź na koniec programu
MOV DL,AL ; przenieś znak (uzyskany z funkcji nr 1) z AL do DL
MOV AH,2 ; funkcja DOS wyświetla znaki
INT 21H ; wezwij DOS w celu wykonania tej funkcji
JMP Start ; skok do etykiety
Stop:
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Hello world!
.model SMALL
.stack 100h
.data
; tekst zakończony znakiem nowej linii CR+LF(CarrigeReturn+LineFeed)
hello db "Hello World", 0Dh, 0Ah,"$"
.code
org 100h
prog:
mov ax,@data ; kopiujemy adres segmentu data do rejestru ax
mov ds,ax ; kopiujemy ax do rejestru segmentowego ds
mov ah, 9 ; funkcja do wypisania łańcucha znaków
mov dx, offset hello ; DS:DX adres początku łańcuch znaków
int 21h ; wywołanie funkcji
mov ah, 4ch ; funkcja do zakończenia programu
int 21h ; wywołanie funkcji
end prog
Napisz program, który pięć razy wyświetli tekst Ala. Podpowiedź: należy użyć funkcji 09H oraz rozkazu do pętli loop.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
mov cx,5 ; ile razy ma być wykonana pętla (rejest CX)
Start:
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,'A' ; S jest znakiem do wyświetlenia
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,'L' ; S jest znakiem do wyświetlenia
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,'A' ; S jest znakiem do wyświetlenia
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,' ' ; jest znakiem do wyświetlenia
INT 21H ; wezwij DOS w celu wykonania tej funkcji
loop Start
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Napisz program wypisujący na ekranie znaki: H e j.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,'H' ; S jest znakiem do wyświetlenia
INT 21H
MOV DL,'e'
INT 21H
MOV DL,'j'
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Napisz program wczytujący z klawiatury znak. Niech go następnie wypisze na ekranie.
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,1 ; funkcja DOS odczytująca znaki z klawiatury
INT 21H ; wezwij DOS w celu wykonania tej funkcji (odczytaj znak)
MOV AH,2 ; funkcja DOS wyświetla znaki
MOV DL,AL ; przenieś znak (uzyskany z funkcji nr 1) z AL do DL
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Napisz program, który narysuje taką figurę (drzewko)
.model small ; model pamięci
.stack 100h ; gdzie zaczyna się stos programu w pamięci
.code ; zaczyna się sekcja z programem
Start: ; etykieta
MOV AH,2 ; funkcja DOS wyświetla znaki
gwiazdka db "*", 0Dh, 0Ah,"$"
INT 21H ; wezwij DOS w celu wykonania tej funkcji
MOV AH,2 ; funkcja DOS wyświetla znaki
gwiazdka db "*"
MOV AH, 4Ch ; kod funkcji DOS do zakończenia programu
INT 21h ; wezwij DOS w celu wykonania tej funkcji
end ; Koniec kodu
Procedura wypisująca słowo Ala
.model small
.stack
.data
hello db "Ala", 0Dh, 0Ah,"$"
.code
main proc
mov ax,@data ;
mov ds,ax ; ustawienie rejestru DS na segment danych
call myProc
mov ax,4c00h
int 21h
main endp
myProc proc
mov ah, 9
mov dx, offset hello
int 21h
ret
myProc endp
end main
Procedura obliczająca największy wspólny dzielnik 2 liczb
.model small, c ; dzięki dodaniu c można używać proc z agrumentami
.stack
.data
xx dw 12 ; zmienna xx programu
yy dw 3 ; zmienna yy programu
.code
main proc
mov ax,@data ;
mov ds,ax ; utawiamy DS na segment danych
push xx ; przeslanie argumentu x do funkcji
push yy ; przesłanie argumentu y do funkcji
call euclid ; wywołanie funkcji
; wypisanie wyniku z procedury (w rejestrze AX)
add al,30h ; dodanie 30h, żeby zamienić np liczbę 4 na znak '4'
mov ah, 2 ; wybranie funkcji DOS do wypisania znaku
mov dl, al ; wpisanie do DL znaku do wypisania
int 21h ; wywołanie funkcji DOS
mov ax,4c00h
int 21h
main endp
euclid PROC x:WORD, y:WORD
mov cx, x
mov ax, y
@@:
cmp cx, ax
jge noswap
xchg ax, cx
noswap:
sub cx, ax
jnz @B
; return value already in ax
RET
euclid ENDP
end main
Makro- def:
.model small
.stack
.code
aMacro macro Arg
mov dl,Arg
mov ah,2
int 21h
endm
main proc
aMacro 100
mov ax,4c00h
int 21h
main endp
end main
Napisz funkcję odejmującą z akumulatora wartość 5.
.model small, c ; dzięki dodaniu c można używać proc z agrumentami
.stack
.data
xx dw 9 ; zmienna xx programu
.code
main proc
mov ax,@data
mov ds,ax ; utawiamy DS na segment danych
push xx ; przeslanie argumentu x do funkcji
call odejmowanie ; wywołanie funkcji
add al,30h ; dodanie 30h, żeby zamienić np liczbę 4 na znak '4'
mov ah, 2 ; wybranie funkcji DOS do wypisania znaku
mov dl, al ; wpisanie do DL znaku do wypisania
int 21h ; wywołanie funkcji DOS
mov ax,4c00h
int 21h
main endp
odejmowanie PROC x:WORD
mov ax, x ; wpisanie do akumulatora wartosci xx dw
sub ax,5
RET
odejmowanie ENDP
end main
Napisz program z procedurą do obliczania pola kwadratu. Należy napisać procedurę i ją wywołać
przekazując odpowiednią wartość w argumencie.
.model small, c ; dzięki dodaniu c można używać proc z agrumentami
.stack
.data
xx dw 2 ; zmienna xx programu
.code
main proc
mov ax,@data
mov ds,ax ; utawiamy DS na segment danych
push xx ; przeslanie argumentu x do funkcji
call poleKwadratu ; wywołanie funkcji
add al,30h ; dodanie 30h, żeby zamienić np liczbę 4 na znak '4'
mov ah, 2 ; wybranie funkcji DOS do wypisania znaku
mov dl, al ; wpisanie do DL znaku do wypisania
int 21h ; wywołanie funkcji DOS
mov ax,4c00h
int 21h
main endp
poleKwadratu PROC x:WORD
mov ax, x ; wpisanie do akumulatora wartosci xx dw
mul x ; mnozenie x*x
RET
poleKwadratu ENDP
end main
Napisz makro do konwersji podanej liczby na znak i jego wypisanie na ekranie. Niech nazywa się
print. Należy ją wywołać w programie głównym.
Napisz program z procedurą do obliczania średniej z dwóch liczb. Należy ją wywołać w programie
Kalkulator dodawania:
L00:
LCALL LCD_CLR ; czyści wyświetlacz
LCALL WAIT_KEY
MOV R1, A
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #'+'
LCALL WRITE_DATA ; WYSWIETLA ZNAK PLUSA
LCALL WAIT_KEY
MOV R2, A
LCALL WRITE_HEX
MOV A, #'='
LCALL WRITE_DATA; WYSWIETLA ZNAK =
MOV A, R1 ; PRZENOSI WARTOSC Z REJESTRU DO AKUMULATORA
ADD A, R2
MOV R3, A
LCALL WRITE_HEX; WYSWIETLA SUME
Kalkulator dodawania, odejmowania, mnożenia i dzielenia:
DODAWANIE:
LCALL LCD_CLR ; czyści wyświetlacz
LCALL WAIT_KEY
MOV R0, A
CJNE A, #0AH, NIEDODAWANIE ; NIEDODAWANIE
LCALL WAIT_KEY
MOV R1, A
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #'+'
LCALL WRITE_DATA ; WYSWIETLA ZNAK PLUSA
LCALL WAIT_KEY
MOV R2, A
LCALL WRITE_HEX
MOV A, #'='
LCALL WRITE_DATA; WYSWIETLA ZNAK =
MOV A, R1 ; PRZENOSI WARTOSC Z REJESTRU DO AKUMULATORA
ADD A, R2
MOV R3, A
LCALL WRITE_HEX; WYSWIETLA SUME
NIEDODAWANIE:
MOV A, R0
CJNE A, #0BH, NIEODEJMOWANIE
LCALL WAIT_KEY
MOV R1, A
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #'-'
LCALL WRITE_DATA ; WYSWIETLA ZNAK ODEJMOWANIA
LCALL WAIT_KEY
MOV R2, A
LCALL WRITE_HEX
MOV A, #'='
LCALL WRITE_DATA; WYSWIETLA ZNAK =
MOV A, R1 ; PRZENOSI WARTOSC Z REJESTRU DO AKUMULATORA
SUBB A, R2
INC A
MOV R3, A
LCALL WRITE_HEX; WYSWIETLA ROZNICE
NIEODEJMOWANIE:
MOV A, R0
CJNE A, #0CH, NIEMNOZENIE
LCALL WAIT_KEY
MOV R1, A
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #'*'
LCALL WRITE_DATA ; WYSWIETLA ZNAK MNOZENIA
LCALL WAIT_KEY
MOV R2, A
LCALL WRITE_HEX
MOV A, #'='
LCALL WRITE_DATA; WYSWIETLA ZNAK =
MOV A, R1 ; PRZENOSI WARTOSC Z REJESTRU DO AKUMULATORA
MOV B, R2
MUL AB
MOV R3, A
LCALL WRITE_HEX; WYSWIETLA ILOCZYN
NIEMNOZENIE:
MOV A, R0
CJNE A, #0DH, KONIEC
LCALL WAIT_KEY
MOV R1, A
LCALL WRITE_HEX ; wyświetla liczbę z akumulatora
MOV A, #':'
LCALL WRITE_DATA ; WYSWIETLA ZNAK DZIELENIA
LCALL WAIT_KEY
MOV R2, A
LCALL WRITE_HEX
MOV A, #'='
LCALL WRITE_DATA; WYSWIETLA ZNAK =
MOV A, R1 ; PRZENOSI WARTOSC Z REJESTRU DO AKUMULATORA
MOV B, R2
DIV AB
MOV R3, A
LCALL WRITE_HEX; WYSWIETLA ILORAZ
KONIEC:
LJMP KONIEC
Podstawowymi poleceniami arytmetycznymi są:
ADD A=A+... ADD A,Rr A,direct A,@Ri A,data
ADDC A=A+...+C
SUBB A=A-...-C
INC ...++ INC A Rr direct @Ri
DEC ...--
MUL A*B wynik: A-low B-high
DIV A/B wynik: A-dzielenie całkowite
B-reszta
DA poprawka dziesiętna
Użycie danych, a użycie danych z pamięci:
MOV A,#30h A=30h
MOV A,#'+' A='+' (znak plus)
MOV A,30h A=zawartosć komórki pamięci z adresu 30h