Programowanie
cześć 5
+PB<
Uwaga
RS.T
W dniu dzisiejszym zmierzymy się z wyświetlaczem alfanumerycznym LCD, co jest znakomitą okazją do poznania kolejnych elementów języka C.
AVR-GCC nic posiada niestety wbudowanych funkcji obsługi wyświetlacza LCD takich, jakie znajdziesz w BASCOM-ie. Konieczne jest napisanie ich całkowicie od postaw: poczynając od najniższego poziomu wysterowania wyprowadzeń procesora, kończąc na funkcjach, których proste wywołanie spowoduje wykonanie całego zespołu czynności mających na celu inicjację wyświetlacza, jego czyszczenie, ustawienie kursora czy pisanie. Może to wydawać się trudne, jednak mam nadzieję, że uda mi się dziś pokazać dwie rzeczy:
1. Przy odrobinie wprawy, siadając 7 dokumentacją w ręku, bardzo łatwo w C obsłużyć dowolne urządzenie, dzieląc interfejs niejako na kolejne warstwy. W ten sposób podążamy za opisem od wysterowania wyprowadzeń, przez kolejne komendy, aż do całych procedur wysyłających odpowiednie ich sekwencje
2. Raz napisany zestaw funkcji według powyższej zasady może być wykorzystany wielokrotnie. Konieczne może okazać się jedynie dostosowanie naszej „najniższej warstwy”, czyli zestawu funkcji zajmujących się wysterowaniem wyprowadzeń.
Zanim zajmiemy się obsługą samego wyświetlacza, poświęćmy chwilę uwagi obsłudze portów. Zauważyłeś może, że juz w poprzednim programie, gdy chcieliśmy stworzyć jakąś nazwę symboliczną dla wyprowadzenia, definiowaliśmy oddzielne nazwy dla trzech rejestrów:
DDRx, PORTx, PlNx. Sposób taki jest może i prosty, ale na pewno niewygodny. Może myślisz teraz podobnie jak ja. żc wygodniej byłoby zdefiniować tylko, że interesuje nas na przykład port D i na tej podstawie odnosić się do potrzebnych w danym momencie rejestrów. Analizując zestawienie rejestrów, wydawać by się mogło, że dobrym rozwiązaniem jest wykorzystanic faktu, iż odpowiednie rejestry są umieszczone zawsze (?) jeden za drugim. Kolejno, dla narastających adresów: PINx, DDRx, PORTx. Jednak analiza rodziny AVR ujawni elementy odbiegające od tej zasady. Sytuację taką mamy przykładowo dla AVRmegal28. Odpowiedni dostęp można zrealizować znacznie pewniej, korzystając z możliwości preprocesora języka C.
W ramce ABC... C ,,makra" zawarłem informacje, które umożliwią zrozumienie rozwiązania naszego problemu zawailego na listingu 20. Po przeczytaniu informacji we wspomnianej ramce program powinien być już zrozumiały. Celem jego napisania było wypróbowanie, w możliwie prosty sposób, działania wszystkich makr upraszczających dostęp do portów. Zauważ, żc teraz definicja odpowiednich portów składa się z odpowiedniej litery. Nie musimy tak jak poprzednio definiować oddzielnie wszystkich potrzebnych nam rejestrów.
Rysunek 25 przedstawia przypoi/ądko-wanie wyprowadzeń na płytce prototypowej przy konfiguracji do pracy z wyświetlaczem LCD. W pierwszej wersji programu obsługi wyświetlacza wykorzystamy fakt, że wyprowadzenia danych wyświetlacza połączone są kolejno z wyprowadzeniami portu mikrokontrolera. Założenie takie zmniejszy uniwersalność programu.
D131 konfiguracja wyprowadzeń
-rDl| ma micjwc yrty spełnionych r
następująocli warunkach:----------
tJ. Wyjęte wyświetlacze LED, włotoay wyświetlacz LCD. b/. W programie zastosowano
konfigurację gdzie J3 znajduje slf w pozycji I ^7
Ustawienie pozostałych zworek nie m» znaczenia
JeśM obraz aie jest widoczny przyczyną mota* być nieprawidłowe ustawienie kontrastu. Zmiana kontrastu jest mail iwa za pomocą PHI.
GND
z drugiej strony jednak umożliwi jego uproszczenie. Dodatkowo musimy wziąć pod uwagę, że płytka AYT3500 nie umożliwia odczytu danych z wyświetlacza Sprawia to, że nie będziemy w stanic sprawdzić zajętości modułu wyświetlacza. Konieczne będzie czekanie przez najdłuższy czas, w którym dana instrukcja może być wykonywana
W zrozumieniu dalszych listingów pomocny może być opis działania sterownika HD44780 Ja posługiwałem się opisem umieszczonym w „Elektronice dla Wszystkich’* 11/97-1/98.
Kod programu będę przedstawiał po kawałku, jednocześnie omawiając przedstawiony fragment. Tak się składa, że program ma taką formę, bo był pisany . od góry do dołu”. Ponieważ opis będzie przebiegał tak samo jak pisanie, aby odtworzyć pełny program, wystarczy zapisać kolejno listingi 21 - 27.
10
Rys. 25 Przyporządkowanie wyprowadzeń.
Listing 20 makru dostępu do portów
Ainclude <avr\io.h> tfinclude <inttypes.h>
// Makra upraszczające dostęp do portów // *** port
#define P0RT(x} <PORTCx)
#define xport(x) Cport##x)
// *** Pin
#define ptn(x) xpin(x)
#define xpin(x) (pin##x)
// *** ODR
tfdefine DDR(x) XDDR(x)
#define xddr(x) (DDR#*x)
// Definicje wyprowadzeń #define led_port d #define sw_port d #define SWl 0 tfdefine SW2 1
// START
int main(vo1d)
{
(/ Konfiguracja portu
ddr(led^eort) a 0x7c;
Ił Podciąganie przycisków ?ort(sw_port) I- 1«swi | 1«sw2;
for(;;)
{
// włączenie wszystkich diod port(led_pcrt) ~0x7c;
// Wyłączenie lewej strony whileO (prN(sw_P3PT) & l«swi)) PORT(LED_POfVl) |- 0x0C;
U wyłączenie prawej strony while(!(pin(sw_port) & 1«SW2)) port(lel« port) I* 0x60;
}
return 0;
36 Październik2005 Elektronika dla Wszystkich