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