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.