Współpraca mikrokontrolera z wyświetlaczami: ciekłokrystalicznym i
Transkrypt
Współpraca mikrokontrolera z wyświetlaczami: ciekłokrystalicznym i
Instrukcja do ćwiczenia: Współpraca mikrokontrolera z wyświetlaczami: ciekłokrystalicznym i siedmiosegmentowym Materiał do samodzielnego opracowania: elementy języka C: typy danych i ich deklarowanie, operatory, instrukcje, pętle, funkcje – definiowanie, deklarowanie i wywoływanie, tablice i wskaźniki, pliki nagłówkowe, dyrektywy kompilatora: include, define. 1. Wyświetlacz ciekłokrystaliczny Jednym z najczęściej stosowanych urządzeń zewnętrznych w układach wykorzystujących mikrokontrolery są wyświetlacze ciekłokrystaliczne (LCD). Swoistym standardem przemysłowym stały się wyświetlacze z wbudowanym sterownikiem opartym o układ scalony HD44780. W uŜywanym na zajęciach zestawie ZL3AVR znajduje się taki wyświetlacz posiadający 2 linie po 16 znaków kaŜda (rys.1). Rys. 1. Wyświetlacz LCD 2 x 16 znaków źródło: www.kamami.pl Wysyłanie znaków do wyświetlacza musi być poprzedzone procedurą inicjalizacji. NaleŜy wybrać czcionkę, ilość linii tekstu, tryb pracy wyświetlacza: sterowanie z cztero- lub ośmiobitową szyną danych, zainicjować port sterujący wyświetlaczem, itd. Do sterowania wyświetlacza potrzeba min. 6 wyprowadzeń mikrokontrolera. 2. Wyświetlacz siedmiosegmentowy LED Oprócz wyświetlaczy LCD do wizualizacji wyników liczbowych i niektórych liter (A – F) stosuje się wyświetlacze LED. Pojedynczy wyświetlacz składa się z siedmiu diod LED ułoŜonych na kształt cyfry „8” oraz dodatkowej diody LED symbolizującej punkt dziesiętny (kropka, przecinek) - rys. 2. Wyświetlacz tego typu, ze względu na emisję światła zapewnia lepszą czytelność w trudnych warunkach oświetleniowych, oraz w przeciwieństwie do wyświetlaczy LCD moŜe być odczytany praktycznie z dowolnego kierunku. Nazwy poszczególnych segmentów (a... h) są znormalizowane (rys. 3). Występują dwa wykonania wyświetlacza: ze wspólną anodą i ze wspólną katodą. W pierwszym przypadku wszystkie anody składowych diod LED są połączone razem i wyprowadzone jako dodatkowa końcówka na obudowie wyświetlacza, w drugim - są to katody. 2 Rys. 2. Wyświetlacz siedmiosegmentowy LED źródło: http://en.wikipedia.org/wiki/Seven-segment_display Rys. 3. Oznaczenie segmentów wyświetlacza LED źródło: http://en.wikipedia.org/wiki/Seven-segment_display Ze względu na liczbę segmentów do sterowania pojedynczego wyświetlacza LED (1 cyfra) potrzeba 8 wyprowadzeń mikrokontrolera. Do sterowania np. 4 cyfr – aŜ 32 wyprowadzeń. Ogranicza to w znacznym stopniu moŜliwość realizacji innych funkcji przez mikrokontroler: układ ATMega32 ma 40 wyprowadzeń (nowocześniejsze mikrokontrolery mają ok. 100 wyprowadzeń). W związku z powyŜszym opracowano specjalny algorytm sterowania wyświetlaczy LED, tzw. multipleksowanie. Polega on na sekwencyjnym zaświecaniu poszczególnych cyfr z odpowiednio duŜą częstotliwością (np. 250 Hz). Zmysł wzroku człowieka nie rozróŜnia takich szybkich bodźców i widać ciągłe świecenie wszystkich cyfr. 3. UŜyteczne funkcje języka C a) Wiadomości podstawowe W celu poprawienia przejrzystości programu za pomocą dyrektywy kompilatora „define” moŜna nadać dowolnemu elementowi programu własną nazwę: #define zastępujący_ciąg_znaków zastępowany_ciąg_znaków np.: #define SEGMENT_A PB0 Zamiast odwoływać się w programie do małointuicyjnej nazwy PB0 oznaczającej 0 wyprowadzenie portu B, moŜna stosować nazwę SEGMENT_A jednoznacznie określającej co jest sterowane z tego wyprowadzenia. Przy stosowaniu w programie funkcji generujących opóźnienie czasowe wymaga się podania kompilatorowi częstotliwości taktowania procesora. SłuŜy do tego makro: 3 #define F_CPU 16000000 Liczba występująca powyŜej to częstotliwość rezonatora kwarcowego w [Hz]. Z praktyki programowania mikrokontrolerów wynika, Ŝe wszelkie konfiguracje części sprzętowej mikrokontrolera (wejścia, wyjścia, przetwornika A/C, itd.) powinny być umieszczone w oddzielnym pliku (tzw. nagłówkowym *.h) i dołączane w momencie kompilacji do właściwego pliku z tekstem programu. Owo dołączanie uzyskuje się stosując dyrektywę kompilatora: #include ”nazwa.pliku” Nazwa pliku obejmuje jego rozszerzenie (*.h). Do zapisywania w rejestrze zera lub jedynki logicznej słuŜy makro _BV(...). Aby z niego skorzystać naleŜy na początku programu dołączyć plik nagłówkowy io.h znajdujący się w katalogu z bibliotekami /avr: #include <avr/io.h> Ustawienie jedynki logicznej na wyprowadzeniu x portu X uzyskuje się za pomocą: PORTX |= _BV(PXx) Dla kilku wyprowadzeń jednocześnie instrukcja powinna wyglądać: DDRX |= _BV(PXx1)|_BV(PXx2)|_BV(PXx3) gdzie: X = {A, B, C, D}, x = {0 … 7}, np. PORTB |= _BV(PB0) ustawia stan 1 na wyjściu 0 portu B. Stan niski ustawia się za pomocą instrukcji PORTX &= ~(_BV(PXx)) dla kilku wyprowadzeń jednocześnie: PORTX &= ~(_BV(PXx1)) & ~(_BV(PXx2)) & ~(_BV(PXx3)) Konfigurację wyprowadzenia x portu X jako wejścia uzyskuje się instrukcją: DDRX &= ~(_BV(PXx)) jako wyjścia: DDRX |= _BV(PXx) Do odmierzania czasu i uzyskiwania opóźnienia czasowego przydatna jest funkcja: void _delay_ms(float liczba_ms) Aby z niej skorzystać naleŜy dołączyć plik delay.h dyrektywą: 4 #include <avr/delay.h> b) Sterowanie wyświetlacza LCD Do sterowania wyświetlacza LCD zostaną wykorzystane funkcje z biblioteki tAvrLib autorstwa Tomasza Wasilczyka [1]. Biblioteka objęta jest licencją GNU LGPL v3. W folderze z zadaniem muszą być dostępne pliki hd44780.c, hd44780.h i macros.h – naleŜy je skopiować z katalogu tAvrLib. Drugi z plików naleŜy dołączyć do programu dyrektywą: #include "hd44780.h" W pliku zawierającym konfigurację części sprzętowej naleŜy umieścić następujący kod: // pod którym portem jest szyna danych #define HD44780_DATA_GPIO X //port wyświetlacza X = {A, B,C, D} // jaką część portu zajmuje szyna danych: // jeŜeli wyświetlacz dołączono do wyprowadzeń portu 4 … 7 to Y = 1 // jeŜeli wyświetlacz dołączono do wyprowadzeń portu 0 … 3 to Y = 0 #define HD44780_DATA_HIGHHALFBYTE Y //Do jakiego portu X i nr wyprowadzenia x podłączono linię RS wyświetlacza: #define HD44780_RS_GPIO X #define HD44780_RS_BIT x //j. w. ale llinia E wyświetlacza: #define HD44780_E1_GPIO X #define HD44780_E1_BIT x //parametry wyświetlacza w znakach #define HD44780_WIDTH 16 #define HD44780_HEIGHT 2 Plik konfiguracyjny powinien być dołączony w programie (#include...) wcześniej niŜ plik hd44780.h. Inicjalizacji wyświetlacza dokonuje się na początku programu za pomocą funkcji: void hd44780_init(void) Kasowanie znaków z wyświetlacza umoŜliwia funkcja: void hd44780_clear (void) Wyświetlenie znaków na konkretnym polu wyświetlacza umoŜliwia funkcja: void hd44780_goto (uint8_t x, uint8_t y) gdzie: x - Ŝądana kolumna, y - Ŝądany wiersz, uint8_t – liczba całkowita bez znaku (typ danej). Wyświetlenie ciągu znaków (łańcucha znaków zdefiniowanego jako tablica znaków) uzyskuje się dzięki funkcji: 5 void hd44780_putStr (char *str, uint8_t length) gdzie: *str – wskaźnik do tablicy znaków, lenght – ilość znaków do wyświetlenia. JeŜeli lenght = 1 funkcja wyświetla wszystkie znaki z tablicy. c) sterowanie wyświetlacza LED Zaświecenie dowolnej cyfry po podłączeniu pojedynczego wyświetlacza LED do mikrokontrolera moŜliwe jest dzięki zadawaniu na wybranym porcie odpowiednich stanów logicznych za pomocą funkcji opisanych w podpunkcie a). Do sterowania czterech cyfr wyświetlacza w trybie multipleksowania naleŜy wykorzystać bibliotekę RklibAVR autorstwa Roberta Krysztofa [2]. Biblioteka jest dostępna na stronie http://diy.exxl.pl/avr.elektroda.eu/index0f22.html?q=node/4. Musi zostać dołączona do programu za pomocą dyrektywy: #include <led7seg.h> W pliku zawierającym konfigurację części sprzętowej naleŜy umieścić następujący kod [2]: #define LED7SEG_F_MUX 250 // częstotliwość multipleksowania w Hz //#define LED7SEG_DIGITS_H // Odkomentować gdy wybieranie cyfr stanem wysokim //#define LED7SEG_SEGMENTS_H // Odkomentować gdy wybieranie segmentów stanem wysokim // ----- definicje dotyczące cyfr wyświetlacza ----#define LED7SEG_DIGIT1_PORT #define LED7SEG_DIGIT1_BIT #define LED7SEG_DIGIT2_PORT #define LED7SEG_DIGIT2_BIT #define LED7SEG_DIGIT3_PORT #define LED7SEG_DIGIT3_BIT #define LED7SEG_DIGIT4_PORT #define LED7SEG_DIGIT4_BIT PORTX // port cyfry 1 x // bit cyfry 1 PORTX // port cyfry 2 x // bit cyfry 2 PORTX // port cyfry 3 x // bit cyfry 3 PORTX // port cyfry 4 x // bit cyfry 4 // ----- definicje dotyczące segmentów wyświetlacza ----#define LED7SEG_SEGMENTS PORTX // port segmentów wyświetlacza // bity segmentów na wyświetlaczu: #define LED7SEG_A 0 #define LED7SEG_B 1 #define LED7SEG_C 2 #define LED7SEG_D 3 #define LED7SEG_E 4 #define LED7SEG_F 5 #define LED7SEG_G 6 #define LED7SEG_H 7 // bit segmentu A // bit segmentu B // bit segmentu C // bit segmentu D // bit segmentu E // bit segmentu F // bit segmentu G // bit segmentu H (kropki) Ponadto w pliku makefile naleŜy umieścić następujący kod (zastępując istniejącą treść) [2]: # Nazwa pliku z funkcją main() - BEZ ROZSZERZENIA! TARGET = nazwa_bez_rozszerzenia 6 # Lista plików, których zmiana powoduje przebudowanie projektu CONFIG = config.h # Lista plików źródłowych w języku C SRC = $(TARGET).c # Lista plików źródłowych w asemblerze (rozszerzenie S - DUśE S !) ASRC = # typ mikrokontrolera MCU = atmega32 # Format pliku wyjściowego (srec, ihex) FORMAT = ihex # Poziom optymalizacji (0, 1, 2, 3, s) # (Uwaga: 3 nie zawsze jest najlepszym wyborem) OPT = s # Katalog z bibliotekami uŜytkownika USRLIB = C:/WinAVR-20100110/lib # Lista plików źródłowych bibliotek w języku C SRCLIB = include $(USRLIB)/led7seg/sources include $(USRLIB)/delay/sources # Dodatkowe biblioteki # # Minimalna wersja printf #LDFLAGS += -Wl,-u,vfprintf -lprintf_min # # Zmiennoprzecinkowa wersja printf (wymaga biblioteki matematycznej) #LDFLAGS += -Wl,-u,vfprintf -lprintf_flt # # Biblioteka matematyczna #LDFLAGS += -lm include $(USRLIB)/avr_make Inicjalizacja wyświetlacza LED odbywa się poprzez jednokrotne wywołanie sekwencji dwóch funkcji: void LED7SEG_init (void) sei() Kasowanie wyświetlacza: void LED7SEG_clear (void) Wyświetlanie łańcucha znaków: 7 void LED7SEG_putstr (char *s) Wyświetlanie liczby całkowitej: void LED7SEG_putU16 (u16 liczba ) gdzie: u16 – liczba całkowita 16 – bitowa ( 0 – 65535, czyli 216-1). W celu uzyskania ciągłego świecenia wyświetlacza dwie wyŜej wymienione funkcje muszą być powtarzane w pętli. Przesuwanie zawartości wyświetlacza o jedną pozycję w lewo: void LED7SEG_shift_left (void) Przesuwanie zawartości wyświetlacza o jedną pozycję w lewo: void LED7SEG_shift_right (void) 4. Przebieg ćwiczenia W ćwiczeniu naleŜy wykorzystać wyświetlacz LCD znajdujący się w prawej, górnej części zestawu ZL3AVR. Jego wyprowadzenia są dostępne na złączu JP29 (LCD4bit). Wyprowadzenia złącza JP29 naleŜy podłączyć do wyprowadzeń wybranego portu mikrokontrolera. Następnie naleŜy poinformować kompilator o dokonanym wyborze wpisując odpowiednie ustawienia w pliku z konfiguracją sprzętową (patrz p. 3 b)). Potencjometr PR1 słuŜy do regulacji kontrastu wyświetlacza. Przykładowe zadania do wykonania: a) Napisać i uruchomić program, który spowoduje wypisanie na wyświetlaczu LCD tekstu w 1 linii. b) J. w. ale w drugiej linii. c) Napisać i uruchomić program, który spowoduje wypisanie na wyświetlaczu LCD liczby zmiennoprzecinkowej. Złącze wyświetlacza LED oznaczone jest jako JP24 (Cyfra) i JP28 (Kolumna). Pierwsze z nich odpowiada za sterowanie poszczególnych segmentów wyświetlacza, drugie – sterowanie cyfr. Wyprowadzenie C1 złącza JP28 steruje cyfrą pierwszą od prawej. Na wstępie naleŜy zidentyfikować jaki stan logiczny powoduje świecenie wybranego segmentu cyfry wyświetlacza, łącząc po jednym wyprowadzeniu złączy JP24 i JP28 z polami +VCC (stan wysoki) lub GND (stan niski) złącza JP9. Tylko jedna z czterech kombinacji spowoduje zaświecenie się wyświetlacza. Stosownie do ustaleń naleŜy zmodyfikować plik nagłówkowy z konfiguracją części sprzętowej (p. 3 c)). Przykładowe zadania do wykonania: d) Napisać i uruchomić program, który spowoduje wypisanie na pojedynczym wyświetlaczu LED wybranej dowolnej cyfry. e) Napisać i uruchomić program, który spowoduje wypisanie na wyświetlaczu LED wybranej liczby 4 cyfrowej w trybie multipleksowania. f) Napisać i uruchomić program, który spowoduje odliczanie na wyświetlaczu LED kolejnych cyfr z opóźnieniem 1 s. 5. Literatura [1] T. Wasilczyk, Dokumentacja biblioteki tAvrLib, http://tAvrLib.wasilczyk.pl, [2] R. Krzysztof, Dokumentacja biblioteki RKlibAVR, http://www.isaa.pl/download/doc_details/89-rklibavr-uniwersalna-biblioteka-dla-avr-gcc. Wersja z dn. 27.01.2012 r.