CWICZENIE 9
Transmisja szeregowa.
W systemach mikroprocesorowych bardzo czesto zachodzi koniecznosc przeslania
danych od innych systemów lub do komputerów. Najczesciej potrzebna jest transmisja w obu
kierunkach. Typowym przykladem moze byc tu system pomiarowy, który wykonuje pomiary
na rozkaz przeslany z komputera, a nastepnie odsyla wyniki pomiarów.
W mikroprocesorach 8-bitowych z pozoru najprosciej jest przesylac dane calymi bajtami
jednoczesnie. Jest to tzw. transmisja równolegla. Kazdemu bitowi przyporzadkowana jest
jedna linia, tak wiec na caly bajt potrzeba 8 linii mikrokontrolera. Dodatkowo potrzebne sa
jeszcze linie sterujace. Liczba linii wejsc/wyjsc mikrokontrolera, które trzeba przeznaczyc na
ten rodzaj transmisji, jest dosc znaczna. W systemach mikroprocesorowych jest to duza
niedogodnosc. Przewaznie nie ma tylu wolnych linii w mikrokontrolerze, wiec trzeba
dobudowac uklady zewnetrzne. W systemie DSM-51 mozliwa jest transmisja równolegla
poprzez zewnetrzny uklad 8255.
Druga powazna niedogodnoscia tego typu transmisji jest liczba przewodów potrzebnych do
polaczenia. Przy transmisji na wieksze odleglosci powstaja problemy przesluchów pomiedzy
liniami, co stwarza koniecznosc dodatkowego ekranowania i obnizenia predkosci transmisji.
Z tych powodów transmisja równolegla jest praktycznie wykorzystywana tylko do
przesylania danych na nieduza odleglosc (z komputera do drukarki). Przy laczeniu systemów
mikroprocesorowych zdecydowanie króluje transmisja szeregowa.
W transmisji szeregowej bity przesylane sa szeregowo jeden za drugim. Istnieja dwa sposoby
transmisji szeregowej: synchroniczna i asynchroniczna.
W transmisji synchronicznej, oprócz linii danych, po której przesylane sa kolejne bity danych,
istnieje jeszcze linii synchronizacji, po której przesylane sa impulsy informujace, w których
momentach na linii danych jest kolejny bit. Do tego sposobu transmisji potrzebne sa dwie
linie.
Zdecydowanie najczesciej wykorzystywana jest transmisja asynchroniczna. Potrzebna jest do
niej jedna linia. Dla rozróznienia kolejnych bajtów przesyla sie dodatkowo specjalne bity
sterujace. Przeslanie jednego bajtu wyglada nastepujaco:
Pomiedzy transmisja kolejnych bajtów linia jest w stanie wysokim. Transmisja bajtu
rozpoczyna sie od wyslania bitu startu, który zawsze jest równy 0. Nastepnie przesylane sa
kolejne bity bajtu, w kolejnosci od najmlodszego do najstarszego. Po danych wysylany jest bit
parzystosci. Jego wartosc zalezy od liczby bitów równych 1 w przesylanym bajcie i sluzy do
kontroli poprawnosci transmisji. Bit parzystosci moze kontrolowac parzystosc, nieparzystosc
lub byc w ogóle pominiety. Na koniec przesylane sa (1 lub 2) bity stopu. Bity te maja wartosc
1, a wiec ustawiaja juz linie w stan stabilny, który wystepuje pomiedzy transmisja
poszczególnych bajtów.
Sposób przesylania jednego bajtu musi byc jednakowo zdefiniowany w nadajniku
i odbiorniku przed rozpoczeciem transmisji. W przeciwnym razie transmisja moze byc
niezrozumiala. Oprócz ustalenia przesylanych bitów trzeba jeszcze zdefiniowac predkosc
transmisji.
Predkosc transmisji wyrazona jest w bodach, czyli w liczbie bitów transmitowanych w ciagu
1 sekundy. Istnieja typowe ustalone predkosci transmisji. Sa to, zaczynajac od 300 bodów,
bit
stopu
bit
startu
D7
D0
D1
D2
D3
D4
D5
D6
D8
predkosc uzyskane przez kolejne podwajanie tej liczby, a wiec: 300, 600, 1200, 2400, 4800,
9600, 19200.
Predkosc 19200 bodów jest w zasadzie maksymalna predkoscia w standardzie RS232. Jednak
przy nieduzych odleglosciach mozna stosowac wyzsze predkosci. Sterownik transmisji
RS232 umieszczony w komputerze IBM PC moze prowadzic transmisje z maksymalna
predkoscia 115200 bodów. W systemie DSM-51 maksymalna predkosc wynosi 57600. Taka
tez predkosc jest wykorzystywana do przesylania programów z komputera do systemu DSM-
51.
Nalezy zaznaczyc, ze predkosc przesylania bajtów nie wynika z podzielenia przez 8 predkosci
wyrazonej w bodach. Do przeslania 1 bajtu zuzywa sie minimum 10 bitów (8bitów+bit startu
+bit stopu)., a maksymalnie 12 bitów (dodatkowo bit parzystosci i drugi bit stopu).
W mikrokontrolerze 8051 wbudowano do wnetrza sterownik transmisji szeregowej. Moze on
pracowac w czterech trybach, z czego tryb 0 to transmisja synchroniczna, a tryby 1...3 to
transmisja asynchroniczna. W systemie DSM-51 mozna wykorzystac transmisje
asynchroniczna, a wiec tryb 1...3.
Sterowanie transmisja szeregowa odbywa sie poprzez wpisanie odpowiedniego bajtu do
rejestru SCON, który znajduje sie w obszarze rejestrów specjalnych, pod adresem 98H.
Rejestr ten wyglada nastepujaco:
SM0
SM1
SM3
REN
TB8
RB8
TI
RI
SM0, SM1 Ustawienie trybu transmisji:
SM0
SM1 Tryb Transmisja
Predkosc
0
0
0
synchroniczna
f
OSC
/12
0
1
1
asynchroniczna 8 bit
Timer 1
1
0
2
asynchroniczna 9 bit
f
OSC
/64 lub f
OSC
/32
1
1
3
asynchroniczna 9 bit
Timer 1
SM2 sterowanie komunikacji wieloprocesorowej w trybach 2 i 3 (normalnie = 0)
REN zezwolenie na odbiór. Jesli wpisane jest 0, sterownik tylko nadaje,
TB8, RB8 9 bit transmisji w trybie 2 i 3 odpowiednio dla nadawania i odbioru,
T1, R1 flagi zakonczenia operacji nadawania / odbioru.
Standardowo do transmisji komputer – DSM-51 wykorzystuje sie tryb 1. W trybie tym
przesylany jest bit startu, 8 bitów danych i bit stopu.
Do rejestru SCON nalezy wpisac wartosc 0101 0000B. Jak widac z tabeli, predkosc transmisji
ustalana jest przez Timer 1, a dokladnie jest okreslona wzorem:
V = [ 2
SMOD
/ 32 ] * [ 1 / okres Timera 1 ].
SMOD jest najstarszym bitem w rejestrze PCON. Poniewaz bity tego rejestru nie moga byc
indywidualnie adresowane, do ustawienia bitu SMOD trzeba uzyc odpowiednio rozkazów
ANL i ORL. Timer 1 uzywany jest najczesciej w trybie 2 – pracuje wtedy jako automatycznie
przeladowywany timer 8-bitowy. Przy tym zalozeniu wzór na predkosc wyglada tak:
V = [ 2
SMOD
/ 32 ] * [ f
OSC
/ ( 12 * [ 256 – TH1 ] ) ].
gdzie TH1 – wartosc wpisana do rejestru TH1.
Stad:
256 – TH1 = [ 2
SMOD
/ 32 ] * [ 11.059.200 / ( 12 * V ) ] =
= [ 2
SMOD
* 11.059.200 ] / [ 32 * 12 * V ] =
= [ 2
SMOD
* 28800 ] / V.
Dla SMOD = 1 otrzymujemy
TH1 = 256 – [ 57600 / V ].
Tutaj ujawnia sie druga zaleta zastosowanego w systemie DSM-51 rezonatora kwarcowego.
Wszystkie wymienione wyzej standardowe predkosci transmisji moga byc w sterowniku
mikrokontrolera 8051 dokladnie ustawione. Dodatkowo równie dokladnie mozna ustawic
predkosc 19200 * 3 = 57600, dostepna równiez w komputerach IBM PC. Trzeba jasno
powiedziec, ze to wlasnie mozliwosc ustawiania standardowych predkosci transmisji
szeregowej zadecydowala o wyborze takiego rezonatora.
Prostym przykladem transmisji szeregowej jest ponizszy program.
;************** Ustawienie TIMERów ************
;TIMER 0
T0_G EQU 0
; GATE
T0_C EQU 0
; COUNTER/- TIMER
T0_M EQU 1
; MODE (0..3)
TIM0 EQU T0_M+T0_C*4+T0_G*8
; TIMER 1
T1_G EQU 0
;GATE
T1_C EQU 0
; COUNTER/- TIMER
T1_M EQU 0
; MODE (0..3)
TIM1 EQU T1_M+T1_C*4+T1_G*8
TMOD_SET EQU TIM0+TIM1*16
;***************Transmisja szeregowa***************
TR_M EQU 1
; tryb transmisji (1...3)
TR_R EQU 0
; zezwolenie na odbiór
SCON_SET EQU TR_M*64+TR_R*16
; SMOD=1
; TIMER1=57600/300bodów=192
TH1_SET
EQU 256-192
TL1_SET
EQU 256-192
;***********************************************
LJMP START
ORG 100H
START:
MOV SCON, #SCON_SET
; port szeregowy
ORL PCON, #80H
; SMOD=1
MOV TMOD, #TMOD_SET
; Timer 1 dla
MOV TH1, #TH1_SET
; transmisji
MOV TL1, #TL1_SET
SETB TR1
; start Timera 1
SETB TI
LCALL
LCD_CLR
LOOP:
LCALL
WAIT_KEY
JNB
TI, $
; czy mozna nadac
CLR TI
; kolejny znak
ADD A, #30H
MOV SBUF, A
; nadaj znak
LCALL
WRITE_DATA
; wyswietl na LCD
SJMP
LOOP
Po ustawieniach rejestru SCON i Timera 1, system DSM-51 nadaje kolejno kody naciskanych
klawiszy. Predkosc transmisji zostala ustawiona na 300 bodów. Aby to osiagnac, nalezy
zgodnie ze wzorem ustawic okres Timera 1 = 192 (dla SMOD = 1). Pamietajac, ze timer liczy
w góre do wartosci 256, nalezy do rejestru TH1 wpisac wartosci 256-192. Nie trzeba wlaczac
przerwan od Timera 1. Dla sterownika transmisji wystarczajacy jest sam sygnal przepelnienia
Timera 1.
Zapoczatkowanie transmisji nastepuje w momencie wpisania bajtu do rejestru SBUF.
Sterownik automatycznie wysyla bajt z bufora transmisji (SBUF) szeregowo przez linie TxD.
Sterownik sygnalizuje zakonczenie transmisji bajtu poprzez ustawienie flagi T1. Od tej pory
mozna wpisac kolejny bajt do bufora transmisji. Wpisanie kolejnego bajtu przed
zakonczeniem transmisji poprzedniego spowodowaloby zapisanie nowego bajtu na czesciowo
wysuniety poprzedni – wystapilby blad w transmisji. Dlatego tez kazdorazowo przed
wpisaniem bajtu do SBUF nalezy sprawdzic stan flagi T1.
Dzialanie przykladu mozna zaobserwowac wlaczajac na komputerze IBM PC dowolny
program emulujacy terminal. Jezeli ustawienia beda zgodne z przyjetymi w programie, to na
ekranie komputera pojawia sie znaki odpowiadajace wybranym klawiszom.
Przyklad 2 ilustruje odbiór transmisji szeregowej.
;************** Ustawienie TIMERów ************
;TIMER 0
T0_G EQU 0
; GATE
T0_C EQU 0
; COUNTER/- TIMER
T0_M EQU 1
; MODE (0..3)
TIM0 EQU T0_M+T0_C*4+T0_G*8
; TIMER 1
T1_G EQU 0
;GATE
T1_C EQU 0
; COUNTER/- TIMER
T1_M EQU 0
; MODE (0..3)
TIM1 EQU T1_M+T1_C*4+T1_G*8
TMOD_SET EQU TIM0+TIM1*16
;************Transmisja Szeregowa****************
TR_M EQU 1
; tryb transmisji (1...3)
TR_R EQU 0
; zezwolenie na odbiór
SCON_SET EQU TR_M*64+TR_R*16
; SMOD=1
; TIMER1=57600/300bodów=192
TH1_SET
EQU 256-192
TL1_SET
EQU 256-192
;***********************************************
LJMP START
ORG 100H
START:
MOV SCON, #SCON_SET
; port szeregowy
ORL PCON, #80H
; SMOD=1
MOV TMOD, #TMOD_SET
; Timer 1 dla
MOV TH1, #TH1_SET
; transmisji
MOV TL1, #TL1_SET
SETB TR1
; start Timera 1
LCALL
LCD_CLR
LOOP:
JNB
RI, $
; czy odebrany znak
CLR RI
MOV A, SBUF
; pobierz znak
LCALL
WRITE_DATA
; wyswietl na LCD
SJMP LOOP
W momencie wystapienia bitu startu sterownik automatycznie rozpoczyna odbiór transmisji.
Po skompletowaniu calego bajtu (zgodnie z ustawiona predkoscia transmisji) sterownik
przepisuje bajt do bufora transmisji SBUF. Jednoczesnie sygnalizuje ten stan poprzez
ustawienie flagi RI.
Odbiór transmisji w programie polega na odczytaniu rejestru SBUF po ustawieniu flagi RI.
Nastepnie flage nalezy wyzerowac, aby sterownik mógl sygnalizowac odebranie kolejnego
bajtu. Zawartosc rejestru SBUF jest prawidlowa, az do momentu zakonczenia odbioru
kolejnego bajtu przez sterownik. W tym momencie nowy bajt jest wpisywany na miejsce
starego. Tak wiec program powinien zdazyc odczytac bajt przed odebraniem nastepnego.
Program mozna uruchomic laczac DSM-51 z komputerem. Druga mozliwosc to podlaczenie
dwóch systemów DSM-51 poprzez COM1 za pomoca kabla RS232. Na jednym nalezy
uruchomic program z przykladu 1, a na drugim z przykladu 2.
Rejestr SBUF z przykladu 2 nie jest, pomimo jednej nazwy, tym samym rejestrem, co SBUF
z przykladu 1. Chociaz adres tego rejestru jest zawsze taki sam, w rzeczywistosci sa to dwa
rejestry. Do jednego z nich mozna tylko pisac ( bufor nadawczy), natomiast drugi moze byc
tylko czytany (bufor odbiorczy). Tak wiec bajty nadawane i odbierane nie mieszaja sie ze
soba.
Kolejny przyklad realizuje jednoczesna transmisje w obu kierunkach. Aby ulatwic jej
obsluge, zostaly wykorzystane przerwania.
;************** Ustawienie TIMERów ************
;TIMER 0
T0_G EQU 0
; GATE
T0_C EQU 0
; COUNTER/- TIMER
T0_M EQU 1
; MODE (0..3)
TIM0 EQU T0_M+T0_C*4+T0_G*8
; TIMER 1
T1_G EQU 0
;GATE
T1_C EQU 0
; COUNTER/- TIMER
T1_M EQU 0
; MODE (0..3)
TIM1 EQU T1_M+T1_C*4+T1_G*8
TMOD_SET EQU TIM0+TIM1*16
;***************Transmisja szeregowa***************
TR_M EQU 1
; tryb transmisji (1...3)
TR_R EQU 0
; zezwolenie na odbiór
SCON_SET EQU TR_M*64+TR_R*16
; SMOD=1
; TIMER1=57600/300bodów=192
TH1_SET
EQU 256-192
TL1_SET
EQU 256-192
;***********************************************
LJMP START
;***************Przerwanie RS 232 ****************
ORG 23H
PUSH ACC
PUSH PSW
JBC
TI, NAD
; koniec nadania znaku
CLR RI
; znak odebrany
MOV A, SBUF
; pobranie znaku
LCALL
WRITE_DATA
; wyswietl na LCD
NAD:
POP PSW
POP ACC
RETI
;***********************************************
ORG 100H
START:
MOV SCON, #SCON_SET
; port szeregowy
ORL PCON, #80H
; SMOD=1
MOV TMOD, #TMOD_SET
; Timer 1 dla
MOV TH1, #TH1_SET
; transmisji
MOV TL1, #TL1_SET
SETB TR1
; start Timera 1
SETB EA
; zezwolenie na przerwanie
SETB ES
; z transmisji szeregowej
LCALL
LCD_CLR
LOOP:
LCALL
WAIT_KEY
; czekaj na klawisz
ADD A, #30H
; modyfikuj
MOV SBUF, A
; nadaj znak
SJMP LOOP
Przerwanie od transmisji zglaszane jest w momencie ustawiania flagi T1 lub R1, a wiec
zakonczenia nadawania lub odbioru. Obsluge przerwania nalezy umiescic pod adresem 23H.
Rozróznienie, czy przerwanie zwiazane jest z nadawaniem, czy z odbiorem opiera sie na
sprawdzeniu flagi TI i RI. W trakcie obslugi przerwania odpowiednia flaga powinna byc
wyzerowana.
W powyzszym przykladzie odbiór transmisji obslugiwany jest calkowicie w przerwaniu.
Zgloszenie skompletowanego bajtu w buforze odbiorczym przez flage RI powoduje jego
odczytanie i wypisanie na wyswietlacz LCD. Obsluga przerwania pochodzacego od flagi TI,
czyli zakonczenie nadawania bajtu, zostala sprowadzona jedynie do zerowania tej flagi.
Natomiast wyslanie kolejnego bajtu odbywa sie z programu glównego. Zalozono, ze zanim
zostanie ponownie uzyta klawiatura, poprzedni znak zostanie nadany w calosci.
Taka organizacja transmisji nie jest zupelnie prawidlowa. Umieszczone wewnatrz przerwania
wypisywanie znaku na wyswietlacz LCD powoduje niepotrzebne wydluzenie obslugi
przerwania. Jednoczesnie to nie przerwanie, a program glówny powinien decydowac, co
zrobic z odbieranymi danymi. Niektóre moga byc w rzeczywistosci wyswietlane
bezposrednio na wyswietlaczu LCD jako przesylane komunikaty, ale inne moga pelnic ma
przyklad funkcje sterujace programem glównym.
Równiez nadawanie powinno byc oddzielone od programu glównego. Czesto program musi
nadac nie jeden, ale caly ciag znaków. Nadajac kolejne znaki i czekajac na flage TI program
glówny bedzie calkowicie zajety tym zadaniem, podczas gdy faktycznie móglby wykonywac
juz inne pozyteczne czynnosci.
Takie rozdzielenie transmisji od programu glównego realizowane jest poprzez bufory:
nadawczy i odbiorczy. Bufory sa w tym przypadku nie pojedynczymi rejestrami, ale kilkoma
lub kilkunastoma komórkami pamieci. Odbierane bajty wpisywane sa do kolejnych komórek
pamieci bufora odbiorczego. Program glówny odczytuje te bajty kolejno, zgodnie
z zapotrzebowaniem. Bufor nadawczy wykorzystywany jest analogicznie do przekazywania
danych z programu glównego do systemu nadawczego.
Obrazuje to przyklad 4.
;**************Pamiec wewnetrzna RAM ***************
B1R2 EQU 8+2
; rejestr 2 w banku 1
B1R3 EQU 8+3
; rejestr 3 w banku 1
FLAGA
EQU 20H
; zestaw flag bitowych
NADAJE EQU
FLAGA.0
; trwa nadawanie znaku
BUFOR
EQU 10H
; wielkosc bufora
BUF_N
EQU 30H
; bufor nadawczy
BUF_NE EQU
BUF_N+BUFOR
; koniec buf. nad.
BUF_O EQU BUF_NE
; bufor odbiorczy
BUF_OE EQU
BUF_O+BUFOR
; koniec buf. odb.
STOS EQU 60H
; pozycja stosu
;************** Ustawienie TIMERów ************
;TIMER 0
T0_G EQU 0
; GATE
T0_C EQU 0
; COUNTER/- TIMER
T0_M EQU 1
; MODE (0..3)
TIM0 EQU T0_M+T0_C*4+T0_G*8
; TIMER 1
T1_G EQU 0
;GATE
T1_C EQU 0
; COUNTER/- TIMER
T1_M EQU 0
; MODE (0..3)
TIM1 EQU T1_M+T1_C*4+T1_G*8
TMOD_SET EQU TIM0+TIM1*16
;***************Transmisja szeregowa***************
TR_M EQU 1
; tryb transmisji (1...3)
TR_R EQU 0
; zezwolenie na odbiór
SCON_SET EQU TR_M*64+TR_R*16
; SMOD=1
; TIMER1=57600/300bodów=192
TH1_SET
EQU 256-192
TL1_SET
EQU 256-192
;*************** MACRA *************************
BANK0
MACRO
; ustawienie banku 0 rejestrów
CLR RS0
; (z banku 0)
MACEND
BANK1
MACRO
; ustawienie banku 1 rejestrów
SETB RS0
; (z banku 0)
MACEND
;*************************************************
LJMP START
;**************** Przerwanie RS 232 *****************
ORG 23H
PUSH ACC
PUSH PSW
BANK1
SETB RS0
MACEND
JBC
TI, NAD
; koniec nadania znaku
CLR RI
; znak odebrany
MOV @R1, SBUF
; wpisz do buf. odb.
INC
R3
; zwieksz licznik
INC
R1
; zwieksz adres wpisu
CJNE R1, #BUF_OE, ODB_E
MOV R1, #BUF_O
; zapetlenie bufora
ODB_E:
POP PSW
POP ACC
RETI
NAD:
; nadaj nastepny znak
CJNE R2, #0, NAD_N
; czy jest w buforze
CLR NADAJE
; nie – koniec nadawania
POP PSW
POP ACC
RETI
NAD_N:
MOV SBUF, @R0
; nadanie nastepnego znaku
DEC R2
; zmniejsz licznik
INC
R0
; zwieksz adres pobierania
CJNE R0, #BUF_NE, NAD_E
MOV R0, #BUF_N
; zapetlenie bufora
NAD_E:
POP PSW
POP ACC
RETI
;**********************************************
ORG 100H
START:
MOV SP, #STOS
MOV SCON, #SCON_SET
; port szeregowy
ORL PCON, #80H
; SMOD=1
MOV TMOD, #TMOD_SET
; Timer 1 dla
MOV TH1, #TH1_SET
; transmisji
MOV TL1, #TL1_SET
SETB TR1
; start Timera 1
CLR NADAJE
; nie trwa nadawanie
MOV R0, #BUF_N
; ustawienie adresów
MOV R1, #BUF_O
; wpisu i pobierania
BANK1
; dla buforów
SETB RS0
; (z banku 0)
MACEND
MOV R0, #BUF_N
MOV R1, #BUF_O
MOV R2, #0
MOV R3, #0
BANK0
CLR RS0
; (z banku 1)
MASCEND
SETB EA
; zezwolenie na przerwanie
SETB ES
; z transmisji szeregowej
LCALL
LCD_CLR
LOOP:
MOV A, B1R3
; czy bufor odbioru pusty
JZ
ODB_NO
MOV A, @R1
; nie – wpisz znak
LCALL
WRITE_DATA
DEC B1R3
; zmniejsz licznik
INC
R1
; zwieksz adres pobierania
CJNE R1, #BUF_OE, LOOP
MOV R1, #BUF_O
; zapetlenie bufora
SJMP LOOP
ODB_NO:
LCALL
TEST_ENTER
; czy trzeba nadawac
JC
LOOP
MOV DPTR, #TEXT
; nadaj text
LP1:
CLR A
MOVC
A, @A+DPTR
; pobierz znak
JZ
LOOP
; 0 – koniec textu
PUSH ACC
; czy jest miejsce
MOV A, #BUFOR
; w buforze nadawczym
LP2:
CJNE A, B1R2, LP3
SJMP LP2
LP3:
POP ACC
MOV @R0, A
; wpisz znak do bufora
INC
R0
; zwieksz adres wpisu
INC
B1R2
; zwieksz licznik
JB
NADAJE, LP4
; inicjuj nadawanie
SETB NADAJE
; jesli nie trwa
SETB TI
LP4:
INC
DPTR
; nastepny znak w tekscie
CJNE R0, #BUF_NE, LP1
MOV R0, #BUF_N
; zapetlenie bufora nad.
SJMP LP1
TEXT:
DB
‘MicroMade’, 0
Wpis do bufora odbiorczego nastepuje w przerwaniu, przy wykorzystaniu rejestru R1 z banku
1. Po kazdym wpisuje zwiekszany jest adres zawarty w rejestrze R1 oraz licznik w rejestrze
R3 z banku 1. W programie glównym nastepuje sprawdzenie licznika. Jesli jest on rózny od
zera, to znaczy, ze w buforze sa bajty do odebrania. Nalezy wiec je pobrac i wyswietlic na
wyswietlaczu, odpowiednio korygujac licznik oraz wskaznik odczytu z bufora – rejestr R1
z banku 0.
bufor odbiorczy (równiez nadawczy) nie jest nieskonczony. Przeznaczony jest dla niego
pewien obszar pamieci RAM. Jezeli wskaznik dojdzie do konca tego obszaru, to musi byc
z powrotem przestawiony na jego poczatek. Dopóki liczba bajtów w buforze nie przekroczy
jego pojemnosci, wszystko bedzie w porzadku. W buforze odbiorczym nie jest to
kontrolowane, gdyz i tak program nie ma wplywu na liczbe bajtów nadawanych z zewnatrz.
Natomiast w buforze nadawczym przed wpisaniem kolejnego bajtu sprawdzana jest liczba
batów w buforze. Jezeli liczba ta równa sie pojemnosci bufora, program musi zaczekac, az
zostanie nadany kolejny bajt i zwolni sie miejsce w buforze.
Przy nadawaniu powstaje jeszcze problem rozpoczecia nadawania. Zazwyczaj po
zakonczeniu nadawania bajtu nastepuje ustawienie flagi TI i w przerwaniu rozpoczyna sie
nadawanie kolejnego bajtu. Jezeli jednak nadane zostana wszystkie bajty z bufora
nadawczego, to ten automatyczny proces zostanie przerwany. Umieszczajac kolejne bajty
w buforze nadawczym nalezy zainicjowac proces nadawania od poczatku. Wykonywane jest
to przez ustawienie flagi TI, a tym samym programowe wygenerowanie przerwania. Dalej
przebiegnie juz wszystko automatycznie. Dla okreslenia, kiedy nalezy transmisje zainicjowac,
wprowadzono specjalna flage: „NADAJE”. Flaga ta jest ustawiana przy inicjalizacji
nadawania i zerowania w momencie nadania ostatniego bajtu.
Przy transmisji, szczególnie na wieksza odleglosc, zdarzaja sie bledy. Nalezy sie przed tym
zabezpieczyc. Najprostszym takim zabezpieczeniem jest przesylanie z kazdym bajtem
dodatkowego bitu parzystosci. Kontrola poprawnosci tego bitu pozwala przewaznie na
wylapanie blednie przeslanych bajtów.
W mikrokontrolerze 8051 mozna do tego typu transmisji wykorzystac tryb 3 sterownika
transmisji. Tryb ten rózni sie od trybu 1 tylko tym, ze po 8 bitach danych przesylany jest
dodatkowo 9 bit. Bit ten pobierany jest przez sterownik transmisji z rejestru SCON – bit TB8.
Przez odpowiednie jego ustawienie decyduje sie, który bit zostanie nadany.
Bit ten moze byc wykorzystany jako dodatkowy bit stopu (ustawiony stale na 1) lub jako bit
kontroli parzystosci, jesli jego wartosc bedzie kazdorazowo ustalana przy wysylaniu bajtu.
Kontrola parzystosci moze kontrolowac parzystosc badz nieparzystosc liczby bitów równych
1 w bajcie. Kontrola parzystosci (even parity) polega na tym, ze bit parzystosci ustawiany jest
tak, aby liczba jedynek w bajcie wraz z bitem parzystosci byla parzysta. NA przyklad, przy
przesylaniu cyfr bit parzystosci wyglada tak:
Znak
Bajt
Bit
parzystosci
Liczba
jedynek
1
0011 0001
1
3 + 1
2
0011 0010
1
3 + 1
3
0011 0011
0
4 + 0
4
0011 0100
1
3 + 1
Kontrola nieparzystosci wyglada przeciwnie.
W przykladzie 5 realizowana jest transmisja z bitami parzystosci.
LED EQU P1.7
;************** Ustawienie TIMERów ************
;TIMER 0
T0_G EQU 0
; GATE
T0_C EQU 0
; COUNTER/- TIMER
T0_M EQU 1
; MODE (0..3)
TIM0 EQU T0_M+T0_C*4+T0_G*8
; TIMER 1
T1_G EQU 0
;GATE
T1_C EQU 0
; COUNTER/- TIMER
T1_M EQU 0
; MODE (0..3)
TIM1 EQU T1_M+T1_C*4+T1_G*8
TMOD_SET EQU TIM0+TIM1*16
;***************Transmisja szeregowa***************
TR_M EQU 1
; tryb transmisji (1...3)
TR_R EQU 0
; zezwolenie na odbiór
SCON_SET EQU TR_M*64+TR_R*16
; SMOD=1
; TIMER1=57600/300bodów=192
TH1_SET
EQU 256-192
TL1_SET
EQU 256-192
;***********************************************
LJMP STAR
ORG 100H
START:
MOV SCON, #SCON_SET
; port szeregowy
ORL PCON, #80H
; SMOD=1
MOV TMOD, #TMOD_SET
; Timer 1 dla
MOV TH1, #TH1_SET
; transmisji
MOV TL1, #TL1_SET
SETB TR1
; start Timera 1
SETB TI
LCALL
WAIT_KEY
JNB
TI, $
; czy mozna nadac
CLR TI
; kolejny znak
ADD A, #30H
MOV C, P
; ustaw bit parzystosci
MOV RB8, C
; do nadania
MOV LED, C
; pokazanie bitu parzyst.
MOV SBUF, A
; nadaj znak
LCALL
WRITE_DATA
; wyswietl na LCD
SJMP LOOP
Liczenie liczby 1 w bajcie przed wyslaniem byloby dosc uciazliwe. Na szczescie w rejestrze
stanu istnieje bit parzystosci ‘P’. Bit parzystosci jest ustawiany zgodnie z liczba jedynek
znajdujacych sie w akumulatorze. Przepisanie tego bitu do TB8, w momencie, gdy
w akumulatorze znajduje sie bajt do wyslania, powoduje wyslanie 9 bitu zgodnie z kontrola
parzystosci. Ustawienie linii LED zgodnie z tym bitem pozwala na porównanie ustawienia
tego bitu dla róznych znaków. Odpowiednie zanegowanie tego bitu pozwala na transmisje
z kontrola nieparzystosci.
ZADANIA
ZADANIE 1
Ustawic inna (wybrana z typowych) predkosc transmisji w przykladzie 1, 2 lub 3.
ZADANIE 2
Zmodyfikowac przyklad 3 tak, aby nie bylo mozliwosci wpisania kolejnego bajtu do
nadawania przed zakonczeniem nadawania poprzedniego bajtu.
ZADANIE 3
Po uruchomieniu przykladu 4 we wspólpracy z komputerem mozna zaobserwowac takie
zjawisko: stale nacisniecie klawisza na klawiaturze komputera powoduje jednostajne
dopisywanie znaków na wyswietlaczu LCD. Jezeli jednak jednoczesnie nacisniety zostanie
klawisz [Enter] na klawiaturze DSM-51, a tym samym rozpocznie sie nadawanie do
komputera, to dopisywanie na wyswietlacz LCD jest skokowe – po kilka znaków. Z czego to
wynika?
ZADANIE 4
Zmodyfikowac przyklad 2 dodajac kontrole parzystosci. Znaki odebrane prawidlowo
wyswietlac na wyswietlaczu, a bledy w odbiorze sygnalizowac na przyklad dioda TEST.
WSKAZÓWKI
Ad. 1
Nalezy wpisac inne wartosci do Timera 1. Wartosci te maja byc wyliczone zgodnie
z podanym wzorem. Sprawdzic dzialanie ustawiajac zalozona predkosc na komputerze.
Ad. 2
Mozna to osiagnac wprowadzajac dodatkowa flage, analogicznie do flagi NADAJE
w przykladzie 4. Jedno z mozliwych rozwiazan przedstawia przyklad 6 na dyskietce.
Ad. 3
Przy nacisnietym klawiszu [Enter] program glówny „w kólko” dopisuje do bufora
nadawczego ciag znaków. Bufor bardzo szybko sie zapelnia. Program glówny czeka az
wpisze do bufora caly ciag. W tym czasie napelniany jest bufor odbiorczy. Po wpisaniu
ostatniego znaku z ciagu, program glówny wybiera znaki z bufora odbiorczego, az wyczysci
caly bufor. Stad dopisywanie na wyswietlacz odbywa sie skokowo po kilka znaków.
Ad.4
Po odczytaniu bajtu z SBUF do akumulatora nalezy porównac flagi RB8 (odebrana
parzystosc) i P (faktyczna parzystosc akumulatora). Prawidlowo dzialajacy program jest
zamieszczony jako przyklad 7.
Kontrole dzialania tego programu mozna przeprowadzic nadajac z komputera bez parzystosc.
Wtedy odebrany bit parzystosci bedzie zawsze 1 (nadany bit stopu). Dla niektórych znaków
bedzie to prawidlowe, dla innych nie