Wojskowa Akademia Techniczna
Sprawozdanie z przedmiotu
Systemy wbudowane
Temat: Port Szeregowy
Prowadzący: mgr inż. Józef Turczyn
Wykonał: Michał Sokołowski grupa I0Y3S1
Data wykonania ćwiczenia: 11 kwietnia 2012r
Treść zadania
Zaimplementować program obsługi transmisji kolejnych 32. znaków ASCII, począwszy od cyfry ‘0’ dla mikrokontrolera 89C52. Znaki mają pojawiać się na podłączonym do mikrokontrolera terminalu. Wysłanie znaku następuje z chwilą podłączonego do mikrokontrolera przycisku. Wysyłanie jest cykliczne tzn po przesłaniu 32 znaków program wysyła znak nowej linii i wypisywanie znowu wraca do cyfry ‘0’. Kody wysłanych znaków mają być także wyświetlone na dwóch 7-segmentowych wyświetlaczach. Rozszerzyć program z punktu a), tak aby umożliwiał wczytywanie znaków z terminala i wyświetlania ich kodów ASCII na dwóch 7-segmentowych wyświetlaczach.
Wstęp teoretyczny
Aby przeprowadzić transmisję szeregową przydatne są następujące rejestry mikrokontrolera:
1) Słowo określające tryb pracy układu czasowo licznikowego – TMOD addr. 98h
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
MSB LSB
GATE - służy do włączenia zewnętrznego bramkowania zliczania impulsów
- wybór funkcji licznika
„0” –taktowany zegarem wewnętrznym fXTAL/12
„1” –taktowany zegarem zewnętrznym z wejścia Ti
M1 | M0 | |
0 | 0 | tryb 0, licznik 8 bitowy taktowany dzielnikiem 5 bitowym |
0 | 1 | tryb 1, licznik 16 bitowy |
1 | 0 | tryb 2, 8 bitowy licznik TL z automatycznym przeładowaniem wartości początkowej z TH |
1 | 1 | dwa niezależne 8 bitowe liczniki TL0 i TH0 (licznik T1 nie pracuje) |
2) Słowo sterujące układem czasowo licznikowym i przerwaniami zewnętrznymi TCON addr. 88h
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
MSB LSB
TF1 (TCON.7)- znacznik przepełnienia licznika T1.
TR1 (TCON.6)- bit sterujący zliczaniem licznika T1.
TF0 (TCON.5)- znacznik przepełnienia licznika T0.
TR0 (TCON.4)- bit sterujący zliczaniem licznika T0.
IE1 (TCON.3)- znacznik zgłoszenia przerwania na INT1.
IT1 (TCON.2)- bit sterujący zgłoszeniem przerwania na INT1.
IE0 (TCON.1)- znacznik zgłoszenia przerwania na INT0.
IT0 (TCON.0)- bit sterujący zgłoszeniem przerwania na INT0.
3)Słowo sterujące SCON addr. 98h.
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
SM0 | SM1 | SM2 | REN | TB8 | RB8 | TI | RI |
MSB LSB
RI - znacznik odebrania danej, zgłoszenie przerwania
TI - znacznik wysłania danej, zgłoszenie przerwania
RB8 - dziewiąty bit odebranej danej
TB8 - dziewiąty bit danej nadawanej
REN - uaktywnienie odbiornika
SM2 - maskowanie odbioru transmisji (współpraca wieloprocesorowa)
SM0 | SM1 | |
0 | 0 | transmisja szeregowa synchroniczna, dane 8 bitowe taktowanie fXTAL/12 |
0 | 1 | transmisja asynchroniczna 8 bitowa, taktowanie przepełnieniami licznika T1 (8052-T2) |
1 | 0 | transmisja asynchroniczna 9 bitowa, taktowanie fXTAL/32 lub fXTAL/64 (bit SMOD w PCON) |
1 | 1 | transmisja asynchroniczna 9 bitowa, taktowanie przepełnieniami licznika T1 (8052-T2) |
4) System przerwań:
Słowo sterujące IE addr. A8h.
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
EA | - | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
MSB LSB
EA - uaktywnienie przerwań (ten bit powinien być ustawiony na „1” jeśli jakiekolwiek przerwanie ma być przyjmowane)
ET2 - maska przerwań od licznika T2 (uwaga bity zgłaszające w rejestrze T2CON nie są kasowane automatycznie w chwili przyjęcia przerwania należy wyzerować bit TF2 programowo)
ES - maska przerwań od nadawania i odbioru przez port szeregowy T2 (uwaga bity zgłaszające w rejestrze SCON nie są kasowane automatycznie w chwili przyjęcia przerwania należy wyzerować bity TI oraz RI programowo)
ET1 - maska przerwań od licznika T1
EX1 - maska przerwań zewnętrznych na INT1
ET0 - maska przerwania od licznika T0
EX0 - maska przerwań zewnętrznych na INT0
We wszystkich przypadkach: „0” maskuje przerwanie, „1” odmaskowuje przerwanie
Dodatkowo wykorzystywany był rejestr SBUF do którego nadajnik wysyła dane a odbiornik je odbiera. Każda transmisja szeregowa musi się odbyć za pośrednictwem tego bufora. Wykorzystane przerwania to przerwanie od Timera 1 oraz przerwanie INT 0. Przerwanie INT 0 będzie oznaczać że wciśnięty został przycisk i zwiększony zostanie licznik wciśnięć maksymalnie do 32 potem zostanie zresetowany i do odbiornika zostanie wysłana dana informująca że należy przejść do nowej linii.
Przerwanie Timera będzie oznaczać ze zmienna Odb służąca do wyświetlania ma mieć przypisaną wartość bufora SBUF w ten sposób widoczne jest jakie dane zostały przesłane/odebrane.
Schemat układu
Rys 1) Schemat podłączenie wyświetlaczy, terminala i przycisku do mikrokontrolera.
Do portu pierwszego mikrokontrolera zostały podłączone 2 wyświetlacze 7-segmentowe w celu odczytywania znaków ASCII. Terminal został podłączony zarówno dla nadawania jak i odbierania informacji. Nóżkę TXD (Transmission) mikrokontrolera połączono z nóżką RXD (Receiver) terminala a nóżkę RXD mikrokontrolera do TXD terminala. Przycisk podłączony do nóżki INT 0 służy do wypisywania kolejnych znaków.
Kod programu
#include <REGX52.H> // biblioteka rejestrów mikrokontrolera 8052
data unsigned char LiczB1 = 0; //licznik wciśnięć przycisku B1
data unsigned char Odb = 0; //odbierane lub wysyłane dane;
void IntSrv_Int0(void) interrupt 0 //obsługa przerwania z nóżki INT0
{
EA = 0; //wyłącz wszystkie przerwania
LiczB1++; //zwiększ licznik wciśnięć
if(LiczB1 == 32 ) //po 32 wciśnięciach pisz od nowej linii
{
TI = 0; //bit przerwania nadajnika informuje o zakończeniu transmisji(TI = 1)
SBUF = 0x0d; //SBUF = '\r' - wyślij CR czyli powrót karetki
while(TI == 0 ){;} //czekaj aż bajt zostanie wysłany TxBuffEmpty czyli kiedy TI = 1
TI = 0; // TI po każdym wysłanym bajcie musi być ręcznie resetowany
SBUF = 0x0a; //SBUF = '\n' wyślij LF czyli znak nowej linii
while(TI == 0 ){;} //czekaj aż bajt zostanie wysłany
TI = 0; // TI po każdym wysłanym bajcie musi być ręcznie resetowany
LiczB1 =0; //rozpocznij odliczanie od nowa
};
SBUF = 0x30 + LiczB1; //wysłanie do bufora SBUF wartości(od cyfry 1 i kolejne 32 ze zbioru ASCII)
EA = 1; //włącz wszystkie przerwania
}
void IntServ_Serial(void) interrupt 4 //obsługa przerwania od Timera1
{
EA = 0; //wyłącza wszystkie przerwania na czas obsługi tego przerwania
TI = 0; //resetowania wskaźnika przerwania nadajnika
Odb = SBUF ; //przypisanie do zmiennej Odb odebranej danej z bufora SBUF
RI = 0; //resetowania wskaźnika przerwania odbiornika
EA = 1; //włącza wszystkie przerwania
}
void InitInt0(void) //1 część zadania tylko obsługa nadawania
{
TH1 = TL1 = 0xFD; //ustaw prędkość T1 na 9600b/s
SCON = 0x40; //tryb1 portu S: tr asyn, 8b danych można zmieniać prędkość transmisji
TMOD = 0x20; //tryb 2 portu timera T1: T1 - 8 bitowy z auotreaload po przepełnieniu
TCON = 0x41; //TR = 1 Enable T1; IT0 = 1 INT0 aktywne zboczem H->L
EX0 = 1; //Zezwolenie na przerwania zewnętrzne
EA = 1; //Zezwolenie na wszystkie przerwania
}
void InitInt0_4(void) //2 część zadania nadawanie i odbiór
{
TH1 = TL1 = 0xFD; //ustaw prędkość T1 na 9600b/s
SCON = 0x50; // 0x50 nadawanie i odbiór a 0x40 tylko nadawanie z
TMOD = 0x20; //tryb 2 portu timera T1: T1 - 8 bitowy z auotreaload po przepełnieniu
TCON = 0x41; //TR = 1 Enable T1; IT0 = 1 INT0 aktywne zboczem H->L
ES = 1; //zezwolenie dla przerwań od transmisji szeregowej
EX0 = 1; //Zezwolenie na przerwania zewnętrzne
EA = 1; //Zezwolenie na wszystkie przerwania
}
void main(void) {
InitInt0_4(); // InitInt0 w przypadku 1 części zadania
for(;;) P1 = Odb;
}
Przykładowe zrzuty ekranu
Rys2) Kolejne wciśnięcia przycisku powodują pojawienie się na terminalu kolejnych znaków ASCII
Rys3) Wpisanie w terminalu znaku powoduje wyświetlenie jego kodu ASCII na 7 –segmentowym wyświetlaczu
Wnioski
Na zajęciach poznaliśmy techniki korzystania z portu szeregowego kontrolera 8052. Poznaliśmy przeznaczenie podstawowych rejestrów umożliwiających skonfigurowanie transmisji wg naszych potrzeb. Poznaliśmy kolejne narzędzie środowiska ISIS jakim jest Terminal, który umożliwia w prosty sposób przetestować port szeregowy. Obsługa portu okazała się niezbyt wymagająca. Wypisywanie danych odbywa się do rejestru SBUF z którego mikrokontroler wysyła dane na port szeregowy. Odbiór danych również odbywa się poprzez ten sam bufor. Podłączenie terminala do portu również jest proste, wystarczyło poprawnie zinterpretować przeznaczenie nóżek RXD i TXT. Pierwsza z nich jest odpowiedzialna za otrzymywanie danych a druga za odczytywanie(w transmisji asynchronicznej)