Obsługa LCD (HD44780) #1: wprowadzenie

Obsługa LCD HD44780

Wyświetlacze oparte na sterowniku kompatybilnym z HD44780 to od lat najpopularniejsze wyświetlacze wśród programistów mikrokontrolerów. Są one stopniowo wypierane przez wyświetlacze TFT, ale ciągle znajdują zastosowanie w mniejszych urządzeniach.

Ich obsługa nie jest skomplikowana, ale zdarza się, że sprawiają sporo kłopotów. Mi na początku napsuły trochę krwi, dlatego, mimo, że w sieci jest bardzo dużo materiałów na ich temat, zdecydowałem się napisać ten artykuł. Wierzę, że w jakimś stopniu będzie on Tobie pomocny.

Opisywane wyświetlacze są wyświetlaczami alfanumerycznymi, co oznacza, że nie umożliwiają sterowania poszczególnymi pikselami, a pozwalają wyświetlać odpowiednio zakodowane znaki. Wystarczy, że wyślemy do sterownika kod ASCII danego znaku.

Wyświetlacze tego typu możemy spotkać w wielu konfiguracjach. Różnić się mogą m.in:

  • ilością wierszy i kolumn, jak np. 1×8, 2×16, 4×20 (wiersz x kolumna),
  • napięciem zasilania,

ale jeśli są oparte na sterowniku kompatybilnym z HD44780, to zasada ich działania jest identyczna. Co więcej, zazwyczaj każdy z nich ma takie same wyprowadzenia, więc nie różni się także ich podłączanie.

Opis wyprowadzeń

Wyprowadzenia LCD HD44780
Wyprowadzenia wyświetlacza

Przed podłączaniem zwróć uwagę, czy kolejność wyprowadzeń w Twoim wyświetlaczu jest taka sama. Poniżej ich opis:

Opis rejestrów

Sterownik posiada dwa rejestry: DR (data register) i IR (instruction register), które wybieramy za pomocą pinu RS.

Rejestr IR (instruction register)

W rejestrze IR przechowywane są informacje o adresach dla pamięci DDRAM i CGRAM.

W DDRAM (display data RAM) umieszczamy kody znaków, które chcemy wyświetlić. Adresy pamięci DDRAM są przyporządkowane polom wyświetlacza w następujący sposób:

  • dla wyświetlacza 2×16:

Adres DDRAM dla LCD 2x16

 

 

  • dla wyświetlacza 4×16:

Adres DDRAM dla LCD 4x16

 

Niezależnie od wielkości wyświetlacza, zawsze mamy do wykorzystania 80 bajtów pamięci DDRAM, więc jeśli nasz wyświetlacz ma mniej pól, to pozostałą część pamięci możemy wykorzystać do przechowywania innych informacji lub na potrzeby przesuwania tekstu na wyświetlaczu. Wszystkie znaki możliwe do wyświetlenia oraz odpowiadające im kody znajdziesz w nocie katalogowej sterownika HD44780 – co ważne, kody podstawowych znaków odpowiadają kodom ASCII, więc nie trzeba ich sprawdzać.

W CGRAM (character generator RAM) przechowywane są kody znaków zdefiniowanych przez użytkownika (max. 8). Jest to przydatne, kiedy potrzebujemy np. polskich znaków.

Oprócz informacji o adresach dla pamięci DDRAM i CGRAM, w IR przechowywane są jeszcze kody komend, które służą np. do czyszczenia LCD lub ustawienia kursora na początku wyświetlacza. Kody poszczególnych komend zostaną przedstawione dalej, gdy będziemy zajmować się implementacją.

Rejestr DR (data register)

W rejestrze DR tymczasowo przechowywane są dane, które mają być odczytane lub wpisane do pamięci DDRAM/CGRAM.

Kombinacje RS i RW

Jeśli chcemy wysłać komendę do sterownika ustawiamy stan niski na pinie RS, natomiast, jeśli chcemy wysłać dane (znaki do wyświetlenia) do pamięci DDRAM/CGRAM ustawiamy na tym pinie stan wysoki. W obu przypadkach na pinie RW musi być ustawiony stan niski, bo zapisujemy dane do wyświetlacza.

Jeśli chcemy odczytać informacje od sterownika ustawiamy na pinie RW stan wysoki. Jeśli na pinie RS ustawimy stan wysoki to odczytujemy dane z pamięci DDRAM/CGRAM. W przypadku, gdy na pinie RS ustawimy stan niski to odczytujemy stan wyświetlacza, tzw. busy flag i adress counter. Busy flag informuje nas o tym czy sterownik jest zajęty wykonywaniem poprzedniej instrukcji czy może jest już wolny i możemy mu wysłać kolejne komendy lub dane. Adress counter przechowuje aktualny adres w pamięci DDRAM/CGRAM. Jeśli zapisujemy dane do DDRAM/CGRAM adress counter jest automatycznie inkrementowany, dzięki czemu po wysłaniu znaku kursor automatycznie przeskakuje nam na następne pole wyswietlacza. Poniżej przedstawiam jeszcze tabelę z noty katalogowej sterownika HD44780:

5v vs 3.3v

Najczęściej spotykane są wyświetlacze pracujące w standardzie 5v – odnosi się to zarówno zasilania jak i logiki. Jeśli korzystamy z mikrokontrolera pracującego przy takim napięciu (np. AVR) to nie ma problemu. Komplikacje pojawiają się, gdy korzystamy z mikrokontrolera pracującego w standardzie 3.3v (np. STM32). Mamy kilka rozwiązań takiego „problemu”. Najprościej jest kupić wyświetlacz pracujący przy napięciu 3.3v. Nie są one tak popularne, ale znajdziesz je bez problemu w różnych sklepach internetowych. Jeśli jednak chcesz wykorzystać wyświetlacz pracujący przy napięciu 5v to też jest to możliwe. Mamy wtedy następujące opcje:

  • dwukierunkowa konwersja stanów logicznych 5v – 3.3v. W tym celu można wykorzystać jakiś gotowy układ scalony, np. 74LVC245.
  • komunikacja ze sterownikiem wyświetlacza tylko w jednym kierunku. Przesyłamy dane z mikrokontrolera do sterownika LCD i nic z niego nie odczytujemy, więc nie musimy się obawiać, że na pinach uC pojawi się stan wysoki 5v od sterownika i spali nam wejścia. Co istotne, w przypadku wysyłania danych do LCD też wszystko działa poprawnie, ponieważ sterownik rozpoznaje poziom 3.3v jako stan wysoki. Wadą takiego rozwiązania jest to, że komunikacja trwa dłużej. Wynika to z tego, że nie możemy odczytać informacji od sterownika o tym, że nie jest już on zajęty i możemy mu wysłać kolejny bajt. Zamiast tego, po każdym zapisie musimy odczekać jakiś okres czasu, po którym mamy pewność, że sterownik „przetrawił” poprzednią porcję danych, więc musimy wprowadzić opóźnienie, które będzie wystarczające dla najgorszego możliwego przypadku. Wszystkie zależności czasowe możemy oczywiście znaleźć w nocie katalogowej sterownika. Czasami możemy sobie pozwolić na takie spowolnienie transmisji i mimo tej wady sposób ten jest często wykorzystywany. Ponadto, komunikacja jednokierunkowa jest prostsza, dlatego zacznę od jej opisu:

 Obsługa LCD (HD44780) #2: komunikacja jednokierunkowa