mikrokontrolery.net

 

   

Procedury obsługi alfanumerycznego wyświetlacza LCD w trybie 4-bitowym z dowolnym przypisaniem linii sterujących

Czasem zachodzi konieczność podłączenia wyświetlacza LCD do dowolnie wybranych portów mikrokontrolera (każda linia do różnych portów, bądź też nie do kolejnych wyprowadzeń). Chciałbym przedstawić w tym miejscu moje procedury obsługi wyświetlacza LCD, które wykorzystuję do programowania PECEL-a. Autor tego projektu poprowadził linie sterujące wyświetlaczem w dość nietypowy sposób. W większości układów linie danych są podłączone do kolejnych wyprowadzeń jednego portu, co pozwala na łatwe sterowanie tak podłączonym wyświetlaczem. Natomiast w tym układzie prawie każda linia jest podłączona do innego portu, co komplikuje sterowanie takiego wyświetlacza. Co prawda programując w Bascomie mamy swobodę w wyborze linii sterujących ale nie każdy chce pisać program akurat w Bascomie.

W pliku lcdbit.h znajdują się definicje wyprowadzeń mikrokontrolera przypisanych do danej linii sterującej wyświetlacza, komend sterujących oraz funkcji znajdujących się w pliku lcdbit.c i stanowiących podstawowe funkcje obsługi wyświetlacza. Jedną linię sterującą definiujemy za pomocą 3 makrodefinicji :

#define DDR_DB4 DDRB
#define PORT_DB4 PORTB
#define DB4 PB4

Natomiast do prostego sterowania każdą linią zdefiniowano następujące makroinstrukcje (znajdujące się w pliku lcdbit.c) :

#define SET_DB4 PORT_DB4 |= (1 << DB4)
#define CLR_DB4 PORT_DB4 &= ~(1 << DB4)

Dzięki takiemu rozwiązaniu wystarczy zmodyfikować definicje znajdujące się w pliku lcdbit.h aby zmienić wyprowadzenia przypisane danym liniom sterującym wyświetlacz.

Podstawową funkcją zawartą w pliku lcdbit.c jest funkcja out_nibble(char x) wystawiająca na linie DB4-DB7 połówkę bajtu danych :

void out_nibble(char x)
{
CLR_DB4;CLR_DB5;CLR_DB6;CLR_DB7;
if(x & (1 << 0)) SET_DB4;
if(x & (1 << 1)) SET_DB5;
if(x & (1 << 2)) SET_DB6;
if(x & (1 << 3)) SET_DB7;
}

Na początku są zerowane wszystkie linie danych, a następnie w zależności od stanu danego bitu są ustawiane odpowiednie linie danych. Jest to trochę oszczędniejsze rozwiązanie jeśli chodzi o zajęte miejsce w pamięci programu w porównaniu do konstrukcji :

if(x & (1 << 0)) SET_DB4; else CLR_DB4;

Gdy już mamy funkcję zapisującą połówkę bajtu możemy napisać funkcję wysyłającą cały bajt do wyświetlacza :

void write_to_lcd(char x)
{
SET_E;
out_nibble(x >> 4); // wystawienie na szynę danych starszej połówki bajtu
CLR_E; // opadające zbocze na E powoduje zapis do wyświetlacza
SET_E;
out_nibble(x); // wystawienie na szynę danych młodszej połówki bajtu
CLR_E; // opadające zbocze na E powoduje zapis do wyświetlacza
_delay_ms(1); // opóźnienie ok 1 ms
}

W pierwszej kolejności należy zapisać starszą połówkę bajtu danych a następnie młodszą. Zapis danych jest wywoływany opadającym zboczem na linii E. Po zapisaniu całego bajtu należy odczekać ok 1ms.

Ponieważ do wyświetlacza możemy zapisać dane lub rozkazy postanowiłem napisać oddzielną funkcję do zapisu danej i oddzielną do zapisu rozkazu :

// funkcja zapisująca do LCD rozkaz
void write_command(char x)
{
CLR_RS; // niski stan na RS -> zapis instrukcji
write_to_lcd(x); // zapis do LCD
}

// funkcja zapisujaca do LCD znak
void write_char(char x)
{
SET_RS; // wysoki stan na RS -> zapis danej
write_to_lcd(x); // zapis do LCD
}

Zapis instrukcji następuje przy niskim stanie linii RS a zapis danej (znaku) następuje przy wysokim stanie na tej linii. Kolejną bardzo ważną funkcją jest funkcja zapisująca do wyświetlacza tekst (łańcuch znaków) :

// funkcja zapisu tekstu do wyświetlacza LCD
void write_text(char * s)
{
while(*s) // do napotkania 0
{
write_char(*s); // zapisz znak wskazywany przez s na LCD
s++; // zwiększ s (przygotuj następny znak)
}
}

Funkcja ta jako argument przyjmuje wskaźnik do tablicy znaków zakończonej znakiem 0 (czyli typowy łańcuch znaków w języku C)

Pliki do pobrania / Files to download :
lcdbit.c lcdbit.h

 

 

 

 

 

 

 

 

 

 

 
 
 
 

(c) 2004-2008 Radosław Kwiecień
Polityka prywatności