Dokumentacja

Transkrypt

Dokumentacja
Michał Ajduk
Tomasz Włodarczyk
Projekt UCYF
Sprzętowo – programowa implementacja systemu obsługi wyświetlacza LCD z
komputerem klasy PC wyposażonym w złącze USB
Część programowa systemu
Informacje wstępne
Część programową systemu stanowi program UsbAdvertiser. Program przeznaczony jest dla
środowiska Windows i jest nieprzenośny. Decyzja o takiej implementacji podjęta została ze
względu na fakt, iż dostarczona biblioteka przez producenta modułu USB biblioteka jest w
formie dynamicznie ładowanej biblioteki DLL, jak również ze względu na łatwość
implementacji aplikacji „okienkowej” w tym systemie za pomocą pakietu Borland C++
Builder, który to pakiet został zastosowany przy tworzeniu aplikacji.
Instrukcja użycia aplikacji
Przed pierwszym użyciem urządzenie musi zostać podłączone do komputera. Wymagane jest
również wcześniejsze zainstalowanie sterowników do części sprzętowej systemu. Sposób
instalacji zarówno sterowników jak programu jest standardowy. W tym drugim wypadku
polega na uruchomieniu programu setup.exe i postępowaniu zgodnie z pojawiającymi się na
ekranie wskazówkami.
Po zakończeniu procesu instalacji możliwe jest uruchomienie aplikacji. Przed rozpoczęciem
korzystania z wyświetlacza konieczne jest podłączenie urządzenia do komputera. Kiedy
wszystko jest gotowe, w oknie aplikacji należy kliknąć przycisk Podłącz. Następnie wpisać w
przeznaczonym do tego polu tekst do wyświetlenia i wybrać sposób wyświetlania.
W wypadku zwykłego przewijania w lewo tekst może być dowolnej długości. W wypadku
wystrzeliwania tekst musi mieć dokładnie 16 znaków, w wypadku nie przewijania tekst musi
mieć maksymalnie 32 znaki, ułożone po 16 w 2 liniach. We wszystkich wypadkach możliwe
jest stosowanie dowolnych znaków alfanumerycznych i białych oraz dodatkowych, jak na
przykład !@#$%^&*)(. Po wykonaniu tych czynności w wypadku przewijania w lewo oraz
wystrzeliwania należy podać czas opóźnienia pomiędzy wysyłaniem kolejnych znaków. Czas
opóźnienia zależny jest od komputera. Na maszynie Athlon XP 1700+ podanie wartości
100000 dawało opóźnienie o 1 sekundę. Następnym krokiem jest wciśnięcie przycisku
Ustaw, które rozpoczyna właściwe działanie systemu. Przerwanie działania następuje w
wypadku zakończenia programu bądź naciśnięcia przycisków Stop lub Reset.
Specyfikacja techniczna
¾ Pakiet UsbDevice
class UsbDevice
{
int UsbConnected;
FT_HANDLE ftHandle;
FT_STATUS ftStatus;
DWORD AmountInRxQueue;
DWORD AmountInTxQueue;
public:
int checkConnected();
void connect();
void close();
void reset();
void regWrite(char data);
AnsiString regRead();
UsbDevice();
~UsbDevice();
}
Klasa UsbDevice odpowiedzialna jest za dostarczenie interfejsu służącego komunikacji
z urządzeniem USB. Korzysta w tym celu z biblioteki FTD2XX. Nazwy metod określają ich
zastosowanie.
¾ Pakiety ScrollSender i BurstSender
Klasy ScrollSender oraz BurstSender dziedziczą po klasie Tthread ( klasa ta jest elementem
biblioteki VCL i implementuje wątek). Zadaniem tych klas jest wysyłanie kolejnych znaków
tekstu do wyświetlania na urządzenie USB. Tekst podawany jest w konstruktorze:
__fastcall ScrollSender(
bool CreateSuspended,
AnsiString text,
UsbDevice *receiver,
int del
);
Kolejnymi parametrami są: wskaźnik do urządzenia odbierającego oraz opóźnienie.
Implementacja tych klas jako oddzielnych wątków zapewnia, iż podczas wysyłania znaków
do urządzenia USB program nie przestanie odpowiadać.
¾ Pakiet gui
Pakiet ten jest głównym pakietem. Odpowiedzialny jest za tworzenie graficznego interfejsu
użytkownika programu oraz koordynację działania powyższych pakietów. Zastosowany został
model programowania zdarzeniowego dostępny w pakiecie C++ Builder.
Część sprzętowa systemu
Informacje wstępne
Do działania systemu konieczny jest zestaw urządzeń złożony z modułu USB opartego o
układ FT8U2XXAM, standardowego wyświetlacza LCD opartego o układ HD44780 firmy
Hitachi oraz układu FPGA EPF10K20RC240-3. W opisanej implementacji układ został
umieszczony na uniwersyteckiej płytce UP1 firmy Altera. Schemat podłączenia
poszczególnych modułów znajduje się poniżej:
GND
15
RXF
37
13 14
46 45
1 2
58 57
LCD
4
FLEX_EXPAN_B
PC
D0
FLEX10K20
Po prawidłowym podłączeniu konieczne jest skonfigurowanie układu fpga. Poniższa tabelka
przedstawia stopień zapełnienia układu:
Device
Input Output Bidir Memory Memory
Pins
Pins
Pins
Bits
%
EPF10K20RC240-3
11
13
0
0
0
Utilized
LCs
%
144
12
Specyfikacja techniczna
Obsługą całego systemu od strony układu fpga zajmuje się pojedynczy automat Mealy’ego
ster o 56 stanach, wśród których są stany odpowiedzialne za generowanie wysterowań do
wyświetlacza, generowanie koniecznych sygnałów „strobe” oraz odbieranie danych z USB.
Automat posiada asynchroniczny reset podłączony do odpowiedniego przycisku (PB_1) oraz
zegar taktowany częstotliwością 768.28Hz. Jest ona celowo ustawiona na tak niski poziom za
pomocą dzielnika częstotliwości, aby moduł LCD, posiadający stosunkowo długi czas reakcji,
nadążył odczytać i wykonać wpisywane komendy bądź zapisywać dane.
Podstawowe funkcje wykonywane przez układ:
¾ Odczyt danych z modułu USB
Kiedy dane z komputera dostępne są do odczytu (znajdują się w buforze urządzenia USB)
wyjście RXF ustawione zostaje ustawione w stan niski. Wtedy automat przechodzi do stanu,
w którym wyjście RD, normalnie ustawione na stan niski, zostaje ustawione na stan wysoki.
Przy takim przejściu dane z bufora modułu USB zostają wystawione i zapisane w
odpowiednim rejestrze układu.
¾ Wysyłanie danych do modułu LCD
Dane zostają wystawione na odpowiednie wyjścia układu. Znaki do wysłania kodowane są w
standardzie ASCII, natomiast komendy zgodne są z zawartymi w specyfikacji modułu LCD.
W zależności od tego, czy jest to komenda, czy dane wyjście RS ustawione zostaje
odpowiednio w stan niski lub wysoki. Następnie następuje przejście w stan „strobujący”, w
którym wyjście E, normalnie znajdujące się w stanie wysokim, przechodzi do stanu niskiego.
Powoduje to, że dane zostają wczytane przez moduł LCD.
¾ Działanie automatu ster
Działanie automatu rozpoczyna się od wysłania do modułu LCD sekwencji:
B"00110011"
B"00000001"
B"00000110"
B"00001100"
Powoduje ona ustawienie modułu do wyświetlania jednej linii złożonej ze znaków w
standardowym rozmiarze. Wyczyszczona zostaje pamięć modułu, kursor ustawiony na
inkrementowanie i dopisywanie. Na koniec włączone zostaje wyświetlanie, kursor zostaje
ustawiony na niewidoczny (podkreślenie).
Następnym krokiem jest wysłanie napisu powitalnego, na stałe ustawionego w kodzie.
Później automat przechodzi w stan oczekiwania na bajt danych z komputera. Bajt ten określa,
jaki program będzie wykonywany dalej, czyli jak potraktować dalsze dane i jak
zainicjalizować moduł LCD. Ponieważ w chwili obecnej dostępne są 3 programy, to
rozpoznawane są tylko bajty 0x00, 0x01, 0x02. Po otrzymaniu odpowiedniego bajta następuje
skok do stanu rozpoczynającego dany program. Działanie programu kończy się odebraniem
bajta 0xff. Powoduje on przejście do stanu początkowego.
¾ Program A – przewijanie w lewo
Program rozpoczyna się od sekwencji sterującej powodującej wyczyszczenie pamięci modułu
LCD, ustawienie kursora na inkrementowanie pozycji i przesuwanie zawartości oraz
ustawienie pozycji kursora na0x0f + 1, czyli jeden znak za końcem pierwszej linii. Powoduje
to, iż pierwszy znak odebrany z komputera zostaje wypisany na końcu pierwszej linii,
a kolejne pojawiają się w tym samym miejscu, powodując przesunięcie zawartości ekranu.
¾ Program B – zbieganie się napisu do środka wyświetlacza.
Na początku programu wysłana zostaje sekwencja powodująca wyczyszczenie ekranu. Kursor
zostaje ustawiony w tryb dopisywania. Następnie wczytywane znaki zostają wypisane na
pozycjach określonych przez ustawnie kursora. Pozycja kursora ustawiana jest
w odpowiednim stanie automatu w zależności od licznika, który jest inkrementowany po
odebraniu każdego znaku. Po wypisaniu całego napisu automat przez 8 stanów czeka czytając
znaki z USB, następnie przechodzi do stanu początkowego powodując reset napisu.
Szczegółowy schemat programu B znajduje się w załączniku.
¾ Program C – wypisanie napisu z rozpoznaniem znaków nowej linii.
Program rozpoczyna się podobną inicjalizacją, jak w poprzednim przypadku, jednak tutaj
zastosowane zostało wyświetlanie dwuliniowe. Wczytywane zostają kolejne znaki.
W wypadku odebrania znaku nowej linii lub zliczenia 16 znaków automat przechodzi do
stanu ustawiającego wskaźnik zapisu na początek drugiej linii. Jeżeli również ta linia zostanie
wypełniona to wskaźnik zapisu zostanie ustawiony znów na początek nowej linii. Schemat
programu znajduje się w załączniku.
Podsumowanie
Ogólnie projekt spełnia stawiane wstępnie założenia zarówno co do szybkości działania jak i
wielkości. Szybkość w tym wypadku powinna by dosyć niska, aby użytkownik był w stanie
odczytać komunikaty, co zostało uzyskane. Wielkość jak już wspomniano jest elementem,
który można by próbować minimalizować. Jak widać udało się uzyskać dosyć niewielką
zajętość układu FPGA. Metody optymalizacyjne dostępne w systemie Max Plus II przy
pomocy, którego wykonany został projekt nie zapewniły lepszego zużycia zasobów.
Przypuszczalnie byłaby możliwość zastosowania oddzielnego automatu do inicjalizacji
modułu LCD. Możliwość ta została jednak odrzucona gdyż inicjalizacje modułu LCD dla
każdego programu jest nieco inne. Co do odczytu i zapisu danych to sygnał strobe konieczny
do wykonania tych czynności implikuje użycie w każdym wypadku dwóch stanów. Jedynym
sposobem zmniejszenia układu wydaje się, zatem próba implementacji w formie układu
mikroprogramowalnego z pamięcią RAM. Spowodowałoby to jednakże znaczny wzrost
złożoności logicznej projektu i jego skomplikowania. Metoda ta jest jednak warta rozważenia
w wypadku gdyby urządzenie bez połączenia z komputerem miało wypisywać długie
komunikaty.
Schemat przebiegu programu B
progB_init0
progB_strobe0
progB_init1
progB_strobe1
progB_init2
progB_strob2
progB_read_wait
!rxf
0
1
progB_read0
usb!=0xff 0
1
s0
progB_read_strobe0
progB_init21
progB_strob21
progB_read_wait1
!rxf
0
1
progB_read1
usb!=0xff 0
1
progB_read_strobe1
licznik==0
0
1
s0
Schemat przebiegu programu C
progC_init0
progC_strobe0
progC_init1
progC_strobe1
progC_init2
progC_strobe2
progC_init3
progC_strobe3
progC_read_wait
!rxf
0
1
progC_read_strobe0
licznik==0
0
1
progC_init4
progC_strobe4