Brociek Adrian
Zemsta Paweł
Grupa 21A
Sprawozdanie nr 6
Obsługa portu szeregowego UART w mikrokontrolerach 8051
Kod programu:
PROG SEGMENT CODE ;definiuje segment nazwie PROG w klasie pamięci CODE
CSEG AT 0 ;kod programu będzie umieszczony w jego pamięci począwszy od adresu „0”
JMP reset ;skok do miejsca oznaczonego etykietą reset
CSEG AT 03h ;kod procedury będzie umieszczony w pamięci począwszy od adresu „03h”
JMP INT0ser ;skok do procedury obsługi przerwania zewnętrznego INT0
CSEG AT 13h ;kod programu będzie umieszczony w jego pamięci począwszy od adresu „13h”
JMP INT1ser ;skok do procedury obsługi przerwania zewnętrznego INT1
CSEG AT 30h ;kod programu będzie umieszczony w jego pamięci począwszy od adresu „30h”
RSEG PROG ;rozpoczyna segment, od którego, znajdujący się poniżej kod zostanie umieszczony w pamięci programu
reset:
CLR P2,7 ; sygnalizacja uruchomienia programu – wyzerowanie bitu
8 na porcie P2
MOV SCON,#60h ; UART w trybie 1 (8 bit), REN=1
MOV TMOD,#20h ; licznik 1 w trybie 2
MOV TH1,#0FDh ; 9600 BDs at 11.0592MHz – szybkość transmisji w bodach
SETB TR1 ; uruchomienie licznika
CLR TI ; wyzerowanie flagi wysłania TI
MOV R2,#60h ; rejestr R2 pełni role wskaźnika końca buforu cyklicznego (tail)
SETB EX0 ; odblokowanie przerwania zewnętrznego INT0
SETB EX1 ; odblokowanie przerwania zewnętrznego INT1
SETB EA ; globalne odblokowanie przerwań
loop:
AJMP loop ; program oczekuje na wciśnięcie jednego z przycisków,
które aktywują odpowiednie przerwania (S6 lub S7)
INT0ser : ; procedura obsługi przerwania INT0 - kodowanie
wpisywanych znaków
CLR P2.6 ; załączenie LED "nadawanie"
wait:
CJNE R3,#16,Bufor ; sprawdzenie rejestru R3, który zawiera informacje
dotycząca bufora cyklicznego. Jeżeli nie osiągnął swojego maksymalnego rozmiaru (16B) to następuje skok do etykiety o nazwie Bufor
MOV R2,#60h ; ustawienie wskaźnika końca buforu na jego początek
(adres head)
MOV R3,#0 ; reset rejestru R3
Bufor:
JNB RI,wait ; sprawdzenie flagi odbioru RI
MOV A,SBUF ; czytanie z UART
CLR RI ; zerowanie flagi odbioru RI
INC R3 ; zwiększamy rejestr R3 o 1, kolejny element zostanie
dopisany do buforu cyklicznego
INC A ; modyfikacja danej (kodowanie) zawartej w akumulatorze
MOV SBUF,A ; zapis do UART
MOV R1,SP ; kopiujemy zawartość wskaźnika stosu do rejestru R1 po
to by był możliwy powrót z przerwania (w przeciwnym wypadku instrukcja PUSH zmieniłaby rejestr SP o 1 i instrukcja RETI skoczyłaby pod zły adres)
MOV SP,R2 ; ustawienie nowego wskaźnika stosu - wskaźnika ogona
buforu cyklicznego (tail)
PUSH ACC ; wartość odczytana z UART zostaje zapisana do buforu
cyklicznego
MOV SP,R1 ; przywracamy wskaźnik stosu SP przed wykonaniem
operacji dodania nowego elementu do buforu cyklicznego
INC R2 ; zwiększenie wskaźnika ogona buforu cyklicznego (tail)
JNB TI,$ ; czekanie na opróżnienie bufora nadajnika
CLR TI ; wyzerowanie flagi wysłania TI
SETB P2.6 ; wyłączenie LED "nadawanie"
RETI ; powrót z przerwania
INT1ser: ; procedura obsługi przerwania INT1 - dekodowanie
wpisywanych znaków
CLR P2.7 ; załączenie LED "odbieranie"
wait2:
CJNE R3,#16,Bufor2 ; sprawdzenie rejestru R3, który zawiera informacje
dotycząca wielkości bufora cyklicznego. Jeżeli bufor nie osiągnął swojego maksymalnego rozmiaru (16 bajtów) to następuje skok do etykiety Bufor2
MOV R2,#60h ; ustawienie wskaźnika końca buforu cyklicznego na jego
początek (adres head)
MOV R3,#0 ; reset rejestru R3
Bufor2:
JNB RI,wait2 ; sprawdzenie flagi odbioru RI
MOV A,SBUF ; czytanie z UART
CLR RI ; zerowanie flagi odbioru RI
INC R3 ; zwiększamy rejestr R3 o 1, kolejny element zostanie
dopisany do buforu cyklicznego
DEC A ; modyfikacja danej (dekodowanie) zawartej w
akumulatorze
MOV SBUF,A ; zapis do UART
MOV R1,SP ; kopiujemy zawartość wskaźnika stosu do rejestru R1 po
to by był możliwy powrót z przerwania ( w przeciwnym wypadku instrukcja PUSH zmieniłaby rejestr SP o 1 i instrukcja RETI skoczyłaby pod zły adres)
MOV SP,R2 ; nowym wskaźnikiem stosu jest wskaźnik ogona buforu
cyklicznego (tail)
PUSH ACC ; wartość odczytana z UART zostaje zapisana do buforu
cyklicznego
MOV SP,R1 ; przywracamy wskaźnik stosu SP przed wykonaniem
operacji dodania nowego elementu do buforu cyklicznego
INC R2 ; zwiększenie wskaźnika ogona buforu cyklicznego (tail)
JNB TI,$ ; czekanie na opróżnienie bufora nadajnika
CLR TI ; wyzerowanie flagi wysłania TI
SETB P2.7 ; wyłączenie LED "odbieranie"
RETI ; powrót z przerwania
END ; zakończenie wykonywania programu
Wprowadzane dane w obu przerwaniach wpisywane są do 16B bufora cyklicznego, którego początek (head) jest pod adresem 60h. Zaś wskaźnik do jego końca (tail) przechowywany jest w rejestrze R2. UWAGA!!! Jeżeli przekroczymy maksymalny rozmiar buforu to wskaźnik końca (tail) ustawia się ponownie na adres początku bufora (head) i dane zostaną nadpisane.