[an error occurred while processing this directive]
Jan Svenungson <jan.svenungson(at)linux.nu>
O Autorze:
Jan używa GNU/Linux'a od 1996 i do tej pory miał tylko 2 niechciane re-boot'y (nie licząc tych z powodu braku zasilania).
Tłumaczenie na język polski: :
Mariusz Kozłowski <sp3fxc/AT/linuxfocus.org>
Zawartość:
|
Zrozumieć HD44780 i kompatybilne wyświetlacze LCD
Notka:
Artykuł ten ma na celu nayczyć Cię kilku rzeczy o HD44780 i kompatybilnych wyświetlaczach LCD.
Poruszymy takie tematy jak podłączenie wyświetlacza do portu równoległego oraz jak go oprogramować
(na przykładzie małego programu o nazwie LCDInfo)
Powinieneś nie tylko podłączyć ten układ, uruchomić program i wyświetlić parę znaków ale także zrozumieć
jak ten sprzęt pracuje i jak zmusić go do zrobienia dokładnie tego co chcesz.
_________________ _________________ _________________
|
Wprowadzenie
Po pierwsze, bedziesz potrzebować trochę sprzętu i oprogramownia. Domyślam się, że już masz komputer wyposażony w standardowy port równoległy
(drukarki), na którym masz działajacą dystrybucję GNU/Linux wraz z gcc i glibc.
Będziesz również potrzebował wyświetlacz LCD kompatybilny z HD44780
, kable do podłączenia go do portu równoległego i potencjometr jeśli chcesz mieć możliwość regulacji kontrastu.
Do zasilenia układu będziesz prawie napewno potrzebował zródła napiecia o większej wydajności prądowej
niż może dać Ci port równoległy. Najlepszym sposobem jest wziąć je prosto z zasilacza komputera. Potrzebne będzie +5V
więc można z powodzeniem użyć standardowego +5V (tego do zasilania dysków twardych, stacji dyskietek, itp.).
Kiedy już podłączysz wyświetlacz LCD będziesz musiał wiedzieć jak to pracuje. Przeważnie tą część zostawia się na odrębne artykuły
dotyczące danego tematu ale postaram się przedstawić niektóre istotne części układu, o których wiedza pomoże Ci skutcznie go oprogramować.
Ostanią rzeczą jest właściwie wyświetlić coś uzytecznego na wyświetlaczu. Jako przykład użyję małego programu
zwanego LCDInfo który wspiera większość właściwości układu HD44780 ale nie wyświetla za wiele jak narazie. Jest to wersja
alpha, nad którą pracuję kiedy mam czas.
Jesli nigdy nie programowałeś w C lepiej żebyś najpierw wziął pod uwagę poczytać trochę na temat C. Zakładam, że jesteś początkujący w
C jako że jest to mój bieżący poziom.
Jak to podłączyć?
Po pierwsze,
spójrzmy na różne piny dostępne na płytce z LCD i do czego właściwie służą.
Pin 1 -> VSS słuzy do podłączenia GND.
Pin 2 -> VDD słuzy do podłączenia zasilania do układu czyli +5V.
Pin 3 -> VLC odpowiada za regulację kontrastu wyświetlacza.
Pin 4 -> RS zależnie od jego stanu wyświetlacz oczekuje na instrukcje lub dane.
Pin 5 -> R/W stan jego decyduje czy LCD wysyła czy odbiera.
Pin 6 -> Enable Kiedy stan tego pin'u zmienia się z niskiego na wysoki i znowu na niski
wtedy LCD czyta pin'y 4,5 i 7-14.
Pin'y 7-14 to szyna danych oznaczona DB0-DB7. Po niej wędrują dane
wysyłane do LCD, które kontrolują gdzie i co ma być wyświetlone na wyświetlaczu.
Pin'y 15 i 16 są używane tylko w wyswietlaczach z podswietlaniem i są to po prostu +5V i GND z rezystorem 3.8 Ohm pomiędzy pin'em 15 a +5V.
Aby dowiedzieć się gdzie poweinieneś podłączyć poszczególne pin'y z portu drukarki
możesz posłuzyć się schematem po prawej stronie, na którym starałem się wyjaśnić to tak prosto jak to możliwe. Kliknij na schemat aby obejreć jego większą wersję.
Ten schemat ma zastosowanie jeśli chcesz mieć możliwość regulacji kontrastu wyświetlacza LCD.
Ja po prostu podłączyłem pin 3 i pin 1 do GND. Jak dla mnie pracuje to dobrze. Ale jeśli masz nietypowe oświetlenie w pomieszczeniu
możesz potrzebować wtedy potencjometra regulacji kontrastu.
Bądz ostrożny podczas podpinania się do zasilacza PC'ta. Jeśli podłączysz zasilanie ze złego przewodu to na układzie może się pojawić +12V
co z kolei usmaży Twoj wyświetlacz LCD. Właściwy kabel to ten o kolorze czerwonym. Zółty to +12V, a czarny to GND.
Jeśli zrobiłeś to poprawnie LCD powinien mieć pierwszy (i trzeci o ile istnieje) rząd czarny kiedy włączysz PC'ta.
Jak pracuje LCD?
LCD nie robi kompletnie nic czekając aż mu nie powiesz ze ma cos zrobic.
Po prostu czeka aż wykryje zbocze narastające i opadające na sygnale enable (stanie się to gdy ustawimy sygnał enable na wysoki,
poczekamy chwile i potem spowrotem ustawimy niski.
W tym momencie wyświtlacz odczytuje czy będą przesyłane instrukcje lub dane dotyczące wyświetlania,
a potem odbiera lub wysyła informacje i ostatnie bity danych są wysyłane lub odbierane.
W naszym przypadku nigdy nie będziemy odczytywać informacji z LCD
więc sygnał R/W będzie zawsze w stanie niskim co oznacza zapis.
Pin RS będzie w stanie niskim poza momentem gdy chemy wyprowadzic znaki na LCD,
a reszta będzie traktowana jako instrukcje.
Powoduje to bardzo prostą obsługę wyświetlacza przez program.
Kiedy już wiemy co i jak chcemy zacząć od włączenia wyświetlacza
i przygotowania go do odbioru informacji. Zaimplementowane jest to
w sekwencji incjalizacyjnej gdzie mowimy wyświetlaczowi aby się włączył.
Zasilanie powinno być już dawno włączone jeśli pobieraz zasilanie z dodatkowego zródła w PC. W innym przypadku jest to pierwsza rzecz jaką musisz zrobić.
Następna jest funkcja "Function set", której wygląd zależy od rodzaju wyświetlacza jaki masz.
Zeby to uprościc wytłymaczę dokładnie co robimy gdy używamy "function set".
DB2 to bit rodzaju czcionki, który powinien być w stanie niskim co oznacza matrycę znaku typu 5x7.
DB3 to bit lini wyświetlania i powinien być w stanie wysokim
co oznacza 2 linie. A co jeśli masz 4 linie na wyświetlaczu? Nie martw się, pierwsza i trzecia linia zajmują tą samą przestrzeń w pamięci wyswietlacza
więc również powinieneś użyć stanu wysokiego.
DB4 to bit długości słowa danych, który decyduje czy słowo zawiera 4 czy 8 bitów. Jeśli podłączysz wyświetlacz zgodnie z moim schematem
powinieneś mieć ten bit w stanie wysokim.
Potem ustawiamy DB5 w stan wysoki aby poinformować wyświetlacz, że to co przesyłamy to rzeczywiście instrukcje "Function Set", a potem
upewniamy się, że RS i R/W są w stanie niskim i włączamy stan wysoki i następnie niski.
Aby odpowiednio dobrać czasy zajrzyj do manuala ukladu. Zakładami, że ustawiamy stan wysoki (pauzujemy) na czas pojedynczych mikrosekund
gdy czekamy na reakcję LCD co i tak jest dużo większą wartością niż potrzebujemy.
Co z kodem?
Omówię tu fragmenty programy LCDInfo, który jest niezbędny
aby zrozumieć jak pracuje interfejs układu HD44780. Możesz
ściągnąć program LCDInfo klikając na link na koncu artykułu lub spojrzeć bezpośrednio na kod C iolcd.c i lcdinfo.c klikając tutaj.
To czego teraz potrzebujemy to kod przedstawiony powyżej i uwierzcie
mi kiedy mowię, że jest to na prawdę proste. Omówię kod krok po kroku
więc nawet jeśli jesteś początkującym programistą w C zrozumiesz o czym tu będzie mowa.
Po pierwsze załączamy pliki nagłówkowe i definiujemy prototypy funkcji
(zajrzyj do zródeł programu). I tu zaczyna się zabawa.
#define D_REGISTER 0
#define I_REGISTER 2
#define WRITE_DATA 8
#define BASE 0x378
int main(void)
{
ioperm(BASE,3,1);
[CUT]
}
To pierwsza instrukcja w funkcji main, która nadaje nam uprawnienia do korzystania z portu równoległego.
BASE (adrez bazowy) powinien wynosić 0x378 lub
coś koło tego, a "3" oznacza, że mamy dostęp do adresów 0x378, 0x379
i 0x380 co w praktyce obejmuje cały port drukarki.
Powód dla którego są tam 3 adresy to jego podział na data, status i control. Dla nas oznacza to, że musimy
ustawić część data w pierwszej kolejności potem część control, a nie możemy wykonać tego w jednym kroku.
Następnym krokiem jest zaimplementowanie funkcji "function set" opisanej powyżej.
void function_set(void)
{
outb(56, BASE);
To ustawia nam: matrycę znaku typu 5x7, dwie linie wyświetlacza, itp.
outb(I_REGISTER + WRITE_DATA, BASE + 2);
To ustawia sygnał RS i R/W na wysyłanie instrukcji i zapis. Użyłem dwóch globalnych
zmiennych I_REGISTER i WRITE_DATA i wyoszą one odpowiednio 2 i 8.
Następnie pojawia się zbocze narastające i opadające na sygnale enable.
outb(ENABLE + I_REGISTER + WRITE_DATA, BASE + 2);
usleep(0);
outb(I_REGISTER + WRITE_DATA, BASE + 2);
}
To co ten kod czyni to w zasadzie ustawia 'enable' w stan wysoki, czeka i ustawia 'enable' w san niski.
Komenda usleep(0); nie jest idealna ale jecze nie skończyłem część kodu odpowiadającej za timingi wyświetlacza.
Kilkoro z Was może się zastanawiać dlaczego ustawiam sygnały RS i R/W
w stan wysoki kiedy mowiłem, że powinny one być w stanie niskim w czasie wysyłania instrukcji.
Dzieje się tak dlatego, że piny 1, 14 i 17 są sprzętowo zanegowane.
Hmmm... mowiłem, że to będzie proste... nieprawda?
Jak wyświetlać znaki?
Może masz zamiar użyć wyświetlacza do jakiś praktycznych celów np.: wyswietlanie tekstu? Zaden problem.
Kod (w sensie uzytych funkcji) jest identyczny niezależnie czy chcemy wyświetlać znaki cz też wysyłać instrukcje sterujące wyświetlaczem.
Jedyną rzeczą jaką musimy zmienić to zmiana pewnych zmiennych. Nie chcemy teraz aby sygnał RS mówił o wysyłaniu instrukcji tylko o wysyłaniu
danych do wyświetlania. Powoduje to, że funkcja print_character() wygląda tak:
void print_character(int character)
{
outb(D_REGISTER + WRITE_DATA, BASE + 2);
outb(character, BASE);
outb(ENABLE + D_REGISTER + WRITE_DATA, BASE + 2);
usleep(0);
outb(D_REGISTER + WRITE_DATA, BASE + 2);
}
Jak widać zmieniliśmy "I_REGISTER" na "D_REGISTER" i "56"
na "character" ale co to znaczy? Jeśli spojrzysz na kody znaków w manualucharacter to zrozumiesz.
trzeba tylko dostarczyć do funkcji znak (jako że uzywamy C więc nie musimy się nawet martwić zamianą typu na int) i
, który następnie pojawi się na LCD. Dalej, huh?
Ta część kodu to szkielet programu obsługi LCD. Użyj jej zgodnie ze swoimi potrzebami np.: wyświetlanie wolnej pamięci, aktywnych połączeń http
lub cokolwiek. Kilka przykładów jest w programie LCDInfo, który wyświetla pewne dane dostępne w /proc dostępnym w GNU/Linux.
Zródła informacji.
Dyskusja dotycząca tego artykułu
Komentarze do dyskusji:
<--, back to the index of this issue
2004-01-31, generated by lfparser version 2.45