Laboratorium: Układy Mikroprocesorowe
Rok akademicki
Termin
Rodzaj studiów
Kierunek
Prowadzący
Grupa Sekcja
2008/2009
Środa
16:15 - 17:45
Wieczorowe
INF
OA
2
1
Sprawozdanie z ćwiczenia numer 7 i 9
Data wykonania ćwiczenia: 26-11-2008
Skład sekcji:
Robert Piekorz
Sylwester Bednorz
Piotr Hankiewicz
Grzegorz Kwiatkowski
Henryk Nycz
Rafał Pacan
Mariusz Podjasek
Rafał Pulnar
Wojciech Rak
Anna Randak
Paweł Sadowski
Rafał Skowron
Wojciech Szymoszek
Robert Uszok
Ireneusz Zydroń
Paweł Owczarek
Zadanie
Na laboratorium nr. 7 i 9 zadaniem dla sekcji było napisanie trzech programów.
Celem pierwszego ćwiczenia było napisanie programu komunikującego się z
modemem poprzez port szeregowy przy wykorzystaniu pollingu. Program na drugie
ćwiczenie należało otrzymać poprzez zmodyfikowanie pierwszego tak aby program
do komunikowania się z modemem przez port RS232 wykorzystywał przerwania.
Trzecie ćwiczenie polegało na napisaniu programu wyświetlającego aktualny czas.
1. Komunikacja z modemem za pomocą RS232 metodą pollingu:
#include <stdio.h>
#include <dos.h>
void wyslij(char s)
{
while(!(inportb(0x3FD) & 0x40)); // oczekiwabie na możliwosc przeslania
outportb(0x3F8,s); // przesłanie bajtu
}
char odbierz(void)
{
char s;
while(!(inportb(0x3FD) & 0x1)); // oczekiwanie na bajt
s = inportb(0x3F8);
return s;
}
int main(void)
{
char wysylane[255];
char c;
int i;
printf("Wprowadz dane do wyslania: ");
scanf("%s",wysylane);
getchar();
outportb(0x3FB,0x80); // podamy predkosc transmisji
outportb(0x3F8,24); // dla 24 częstotliwość 4800
outportb(0x3F9,0); // Odblokowanie odbierania danych
outportb(0x3FB,3); // Długość słowa 8bit
i=0; // Przesłanie danych wej.:
while(wysylane[i])
{
wyslij(wysylane[i]);
i++;
}
wyslij('\r');
wyslij('\n');
printf("\r\nWysłano: %s\r\nOdbieram: ",wysylane);
// Pobieranie danych:
while(1){
c = odbierz(); // Odebranie znaku
putchar(c); // Wyświetlenie odebranego znaku
}
return 0;
}
2. Komunikacja z modemem z wykorzystaniem przerwań:
#include <stdio.h>
#include <dos.h>
char bufor;
int buforflag;
// Wskaźnik przechowujący adres starej funkcji obsługującej przerwanie
void interrupt (*stary)();
// Nowa funkcja obsługująca przerwanie
void interrupt przerwaj(void)
{
bufor = inportb(0x3F8);
buforflag = 1;
outportb(0x3EC, 0x0B);
outportb(0x20, 0x20);
}
// Funkcje wysyłająca znak do modemu
void wyslij(char s)
{
while(!(inportb(0x3FD) & 0x40)); // oczekiwabie na możliwosc
przeslania
outportb(0x3F8,s); // przesłanie bajtu
}
// Funkcje odczytująca znak przesłany z modemu
char odbierz(void)
{
char s;
while(!(inportb(0x3FD) & 0x1)); // oczekiwanie na bajt
s = inportb(0x3F8);
return s;
}
int main(void)
{
char wysylane[255];
int i;
buforflag = 0;
//adres funkcji do wektora przerwan
disable();
// zapamiętanie starego adresu przerwania
stary = getvect( 0x0C );
setvect( 0x0C, przerwaj );
printf("Wprowadz dane do wyslania: ");
scanf("%s",wysylane);
outportb(0x3FB,0x80); // podamy prędkość transmisji
outportb(0x3F8,24); // dla 24 częstotliwość 4800
outportb(0x3F9,0); // Odblokowanie odbierania danych
outportb(0x3FB,3); // Długość słowa 8bit
outportb(0x3F9,1); // Odblokowanie intr dla danych odbieranych
outportb(0x3FC,8);
outportb(0x21,0);
enable();
i=0;
while(wysylane[i])
{
wyslij(wysylane[i]);
i++;
}
wyslij('\r');
wyslij('\n');
printf("\r\nWyslano: %s\r\nOdbieram: ",wysylane);
// Pobieranie danych:
while(1){
if(buforflag == 1)
{
putchar(bufor);
buforflag=0;
}
}
// Przywrócenie adresu przerwania
disable();
setvect(0x0C,stary);
enable();
return 0;
}
3. Wyświetlanie aktualnego czasu
#include <stdio.h>
#include <conio.h>
#include <dos.h>
int licznik = 0;
// licznik inkrementowany w każdym z wywołań
// nowej 1Ch
void interrupt nowa(void);
// nowa funkcja obslugi przerwania 1Ch
void interrupt far (*stara)();
// zmienna do zapamiętania adresu starej
// proc. obsługi przer 1Ch
struct dostime_t czas;
//---------------------------------------------------------------------------------
void interrupt nowa(void)
{
licznik++;
// inkrementacja licznika ; zerowanie po 10 wywolaniach
stara(); // wywolanie pierwotnej procedury obsl. przerw. 1Ch
}
//---------------------------------------------------------------------------------
void main(void)
{
int h1,h2,m1,m2,s1,s2;
disable();
stara = getvect(0x1C); // podmiana procedury obslugi
setvect(0x1C,nowa);
enable();
while(!kbhit())
if(licznik == 9 )
// wyświetlenie co około 0.5 sekundy (1Ch
// zgłaszane co 54.9 ms)
{
clrscr();
_dos_gettime(&czas); // pobranie czasu
h1 = (int)(czas.hour / 10);
h2 = (int)(czas.hour % 10);
m1 = (int)(czas.minute / 10); // przygotowanie do wyświetlenia
m2 = (int)(czas.minute % 10);
s1 = (int)(czas.second / 10);
s2 = (int)(czas.second % 10);
printf("%d%d:%d%d:%d%d",h1,h2,m1,m2,s1,s2);
// wyświetlenie czasu
licznik = 0;
}
disable();
setvect(0x1C,stara); // przywrócenie oryginalnej proc. obsl. przerw. 1Ch
enable();
}
Wnioski
W trakcie laboratorium 7 i 9 dowiedzieliśmy się jak można odwoływać się do
układów wejścia/wyjścia z programu. Zapoznaliśmy się również z mechanizmem
przerwań które pracują wydajniej niż w przypadku metod pollingu. Przerwania
pozwalają na wykonywanie przez procesor innych zadań, bez potrzeby ciągłego
odpytywania urządzeń wejścia/wyjścia i sprawdzania gotowości.