Duże kolorowe wyświetlacze LCD wykonane w technologii TFT były drogie. Jak należało się spodziewać, rozwój technologii spowodował, że ceny spadły i warto zainteresować się wyświetlaczami o dużej rozdzielczości. Przykładem takiego produktu jest wyświetlacz kolorowy TFT320240C256 z matrycą TFT o rozdzielczości 320x240 pikseli.
Wbudowany sterownik wyświetlacza zapewnia uzyskanie 8-bitowej głębi kolorów. Ekran jest podświetlany za pomocą wbudowanych białych diod LED i ma zintegrowany panel dotykowy. Obszar wyświetlanych informacji ma wymiary 56 mm×73 mm.
Sterownik matrycy jest zbudowany w oparciu o układ Actel Igloo. Jest to programowany układ logiczny FPGA z pamięcią Flash. Producent wyświetlacza nie podaje właściwie żadnych technicznych szczegółów pracy sterownika poza opisem wyprowadzeń i przebiegów czasowych na magistrali sterującej. Do tych przebiegów dodano tabelkę z liczbowymi zależnościami czasowymi przy przesyłaniu danych.
Zamiast klasycznej dokumentacji w danych technicznych umieszczono krótki program napisany w języku C dla mikrokontrolerów rodziny 8051. To dość nietypowe, ponieważ szczegółowa dokumentacja była tym, czego się spodziewałem i co w praktyce jest bardzo potrzebne. Jednak z drugiej strony, funkcje w C wyjaśniają właściwie wszystkie wątpliwości dotyczące sterowania wyświetlaczem na poziomie komunikacji z mikrokontrolerem.
Ideałem byłoby połączenie opisu sterownika z przykładowymi procedurami. Jednak w końcowym efekcie analiza prostych procedur w C dała wyczerpująca odpowiedź na wszystkie wątpliwości i można uznać, że dokumentacja spełnia swoje zadanie.
Interfejs Komunikacyjny
Sterownik wyświetlacza do komunikacji z mikrokontrolerem wykorzystuje równoległą 8-bitową magistralę pracująca w przemysłowym standardzie Intel 8080. Przebiegi czasowe na magistrali pokazano na rysunku 1. Interfejs jest aktywowany po wyzerowaniu linii CS. Kierunkiem przesyłu danych na magistrali sterują linie WR (zapis do sterownika) i RD (odczyt ze sterownika). Dane są wpisywane z mikrokontrolera do sterownika wyświetlacza przy narastającym zboczu na linii WR, a odczytywane z pamięci obrazu sterownika przy opadającym zboczu na linii RD. Stan dodatkowej linii sterującej RS określa czy dane są przesyłane do pamięci obrazu sterownika (RS=1), czy do rejestrów sterujących (RS=0).
Programowa obsługa wyświetlacza
Trzy 8-bitowe rejestry adresowe (RS=0) określają współrzędne x, y na ekranie wyświetlacza (rejestr adresu x jest 2-bajtowy bo zawiera liczbę z zakresu 0.... 319). Brak innych rejestrów oznacza, że nie trzeba sterownika wstępnie konfigurować. Wynika to pewnie z tego, że jest to rozwiązanie zoptymalizowane dla zastosowanej matrycy i wszystko zoptymalizowano pod kątem właściwości użytego wyświetlacza. Z drugiej strony, nie ma tu na przykład sprzętowego wsparcia wyświetlania ograniczonych bitmap. To wsparcie przydaje do wyświetlania znaków w trybie tekstowym. Jednak jak pokażę dalej, można sobie bez problemu z tym poradzić programowo.
Do testów wyświetlacza użyłem modułu ewaluacyjnego STM32F0 Discovery. Jeżeli nie chcemy wyświetlać pełnowymiarowych bitmap, to jest to zestaw zupełnie wystarczający. Dla bitmap o pełnym wymiarze 240×320 pikseli potrzeba pamięci o pojemności 76800 bajtów i jest to więcej, niż całkowita pojemność pamięci Flash użytego mikrokontrolera. W aplikacjach wymagających wielu bitmap najlepiej jest je umieścić w zewnętrznej pamięci np. na karcie SD.
Obsługa magistrali jest emulowana programowo. Linie magistrali danych D0...D7 są połączone z liniami GPIOC0....GPIOC7. Jako linie sterujące są wykorzystano porty GPIOB8....GPIOB12 (tabela 1). Oprócz linii interfejsu komunikacyjnego niezbędny jest sygnał zerowania sterownika RESET (aktywny poziom niski).
Wszystkie linie portów w STM32 muszą być przed użyciem zainicjowane. Na listingu 1 pokazano inicjalizację linii GPIO0....GPIOC7, a na listingu 2 - inicjalizację linii sterujących.
Do emulowania magistrali będą potrzebne procedury wysyłania 8-bitowej danej na port (listing 3) i do manipulowania pojedynczymi wyjściami I/O (listing 4).
Teraz można napisać właściwe procedury emulowania magistrali. Będziemy potrzebowali funkcji zapisu do sterownika komendy WrCmd i zapisu danej WrData. Funkcje te można zobaczyć na listingu 5.
Funkcję ustalającą pozycję zapisu pozycji na ekranie (adres piksela) pokazano na listingu 6. Jej argumentami są współrzędne x (z zakresu 0...319; liczba 16-bitowa) i y (z zakresu 0...239; liczba 8 bitowa).
Nie ma tu zabezpieczeń przed przekroczeniem zakresu i użytkownik sam musi zadbać o poprawność określenia pozycji piksela.
Dana określająca kolor piksela ma format pokazany na rysunku 2. Kolor czerwony i zielony są kodowane na 3 bitach, a kolor niebieski na 2 bitach. Mając do dyspozycji funkcje zapisu danych i ustalenia pozycji na ekranie zapisywanej danej, można napisać funkcje zapisującą bitmapę do wyświetlacza. W Elektronice Praktycznej opisywałem już narzędzia i sposób konwertowania bitmap na tablice w języku C. W czasie testów użyłem programu bmp2c.exe do konwersji bitmapy z 8-bitową głębią koloru. Na listingu 7 zamieszczono funkcję umożliwiającą wyświetlenie bitmapy o wymiarach 240×320 pikseli zapisanej w tablicy bmp[].
Wynik działania tej procedury został pokazano na fotografii 3.
Pełnowymiarowe bitmapy są używane rzadko. Dużo częściej trzeba wyświetlać mniejsze obiekty graficzne. Dlatego potrzebujemy procedur wyświetlających bitmapy o dowolnym rozmiarze i w dowolnym miejscu wyświetlacza. Oczywiście ta dowolność jest ograniczona rozdzielczością matrycy. Procedura z listingu 8 wyświetla bitmapę od pozycji określonej w argumentach x i y, o wymiarach określonych w argumentach dx i dy. Ponieważ na ekranie można umieścić kilka bitmap, to argument bmp przekazuje wskaźnik tablicę z wyświetlaną bitmapą.
Ważnym elementem graficznego interfejsu użytkownika jest wyświetlanie informacji tekstowych. Jak napisano na początku, sterownik nie zapewnia żadnego wsparcia poza możliwością zapalenia/zgaszenia pojedynczego pikseli o zadanym kolorze. Dlatego wyświetlanie znaków alfanumerycznych trzeba wykonać całkowicie programowo. Zaczniemy od generatora znaków. Tablicę z wzorcami znaków można sobie samemu zdefiniować, ale jest to żmudne zajęcie. Ja wykorzystałem gotową tablicę wykonaną przez Jamesa P. Lyncha dla wyświetlacza telefonu Nokia 6100. Tablica zawiera wzorce znaków o 3 wielkościach: 6×8 pikseli (small), 8×8 pikseli (medium) i 8×16 pikseli (large). W praktyce, najbardziej przydatne okazały się największe znaki. Nic nie stoi na przeszkodzie, aby sobie zdefiniować jeszcze większe znaki.
Pierwsze 3 bajty w tablicy generatora dla każdej z wielkości znaków zawierają informację o liczbie kolumn, wierszy i bajtów na znak. Na tej podstawie jedna uniwersalna procedura potrafi wyświetlić znaki o różnych wielkościach. Procedurę umożliwiającą wyświetlanie pojedynczego znaku pokazano na listingu 9.
Argumentami procedury są : kod ASCII wyświetlanego znaku, położenie na ekranie (współrzędne x i y), rozmiar znaku, kolor znaku i kolor tła. W zmiennej pFont jest umieszczany wskaźnik na początek tablicy generatora znaków. Do zmiennych nCols, nRows i nBytes są zapisywane pierwsze 3 bajty z tablicy generatora znaków. Ponieważ wzorce znaków nie są umieszczane w tablicy zgodnie z kodami ASCII, to trzeba kod ASCII wyświetlanego znaku przekształcić na pozycję w tablicy generatora. Po przekształceniu wskaźnik pChar wskazuje na ostatni bajt wzorca znaku w tablicy generatora. Program pobiera kolejne bajty z tablicy (od ostatniego do pierwszego). Każdy bit tego bajtu jest analizowany. Jeżeli jest ustawiony, to bit jest wyświetlany w kolorze znaku określonym argumentem fColor. Gdy bit jest wyzerowany, to jest wyświetlany w kolorze określonym argumentem bColor. W ten sposób można wyświetlać znaki o dowolnym kolorze na tle dowolnego koloru o głębi 8-bitowej.
Tryb tekstowy uzupełnimy procedurą wyświetlania tekstu w jednym z trzech rozmiarów( argument size). Pozycja początku ciągu znaków jest ustalana argumentami x i y, a kolor znaków oraz tła argumentami fColor i bColor.
Wynik działania tej funkcji pokazano na fotografii 5.
Sposób dołączenia wyświetlacza
Wszystkie sygnały elektryczne łącznie z zasilaniem sterownika, diod podświetlania i 4-rzewodowym wyprowadzeniem panelu dotykowego są dołączone 20-przewodowa taśmą zakończoną płaskimi złoconymi stykami. Podłączenie wyświetlacza do układu wymaga specjalnego złącza zaciskowego do styków kończących tasiemkę (fotografia 6). Do celów testowych zaprojektowałem płytkę-przejściówkę pozwalającą na połączenie wyprowadzeń wyświetlacza do modułu STM32F0 Discovery (fotografia 7).
Tomasz Jabłoński, EP