Instrukcja do ćwiczenia PE: Współpraca mikrokontrolera z klawiaturą

Transkrypt

Instrukcja do ćwiczenia PE: Współpraca mikrokontrolera z klawiaturą
Instrukcja do ćwiczenia:
Współpraca mikrokontrolera z klawiaturą
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. Klawiatura
W celu komunikacji z użytkownikiem, w układach wykorzystujących mikrokontrolery
stosuje się klawiatury (rys. 1).
Rys. 1. Klawiatura 16 przyciskowa [1].
Klawiatury są najczęściej zbudowane z łączników o działaniu chwilowym (przycisków),
zwierających 2 styki. Na wejścia mikrokontrolera podaje się napięcie 0 V lub 5V w zależności od
stanu styków łącznika (rys. 2).
Rys. 2. Sposób podłączenia 4 przycisków do mikrokontrolera
2
Oporniki R ograniczają prąd płynący ze źródła zasilania przy zwartych stykach łącznika. Liczba
łączników determinuje liczbę wejść mikrokontrolera, koniecznych do obsługi klawiatury.
W przypadku dużej liczby klawiszy (powyżej kilku) stosuje się tzw. klawiaturę matrycową.
Poszczególne łączniki zwierają linie zwane wierszami z liniami zwanymi kolumnami. Zarówno
wiersze jak i kolumny są podłączone do wyprowadzeń mikrokontrolera. Tym sposobem ilość
wyprowadzeń mikrokontrolera koniecznych do obsługi klawiatury jest mniejsza od liczby klawiszy
(rys. 3).
Rys. 3. Obsługa klawiatury matrycowej
2. Odczyt danych z wejść mikrokontrolera
W celu umożliwienia odczytu zmiany stanu łącznika klawiatury konieczne jest
skonfigurowanie wybranych wyprowadzeń mikrokontrolera jako wejść. Do rejestru DDRX należy
wpisać stan 0 (X = {A, B, C, D}) [2]. Np. zapisanie do 5 bitu rejestru DDRA zera logicznego
konfiguruje wyprowadzenie mikrokontrolera PA5 jako wejście. Na rys. 4 pokazano przykładowo
składniki rejestru DDRA.
Rys. 4. Składniki rejestru DDRA[3].
Rezystory R (20 … 50 kΩ) pokazane na rys. 2 i 3 (zwane podciągającymi) są wbudowane w
mikrokontroler [3]. Ich uaktywnienie uzyskuje się poprzez wpisanie do odpowiedniego bitu (x)
rejestru PORTx wartości logicznej jeden. Na rys. 5 pokazano poszczególne bity rejestru PORTA.
Rys. 5. Składniki rejestru PORTA [3].
3
Po skonfigurowaniu wyprowadzenia mikrokontrolera jako wejście, możliwy jest odczyt jego
stanu logicznego w rejestrze PINX. Na rys. 6 pokazano przykładowo składniki rejestru PINA.
Rys. 6. Składniki rejestru PINA [3].
Sterowanie funkcją i stanem logicznym wyprowadzeń mikrokontrolera w ramach
pozostałych portów odbywa się analogicznie. Literę A w nazwie rejestru należy zamienić na B, C
lub D.
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 WEJSCIE_0 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:
#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(...) [3]. 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ć:
4
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)
Odczyt stanu logicznego wejścia wykonuje się za pomocą makr:
bit_is_clear(PINX,PXx)
zwracającego wartość 1 jeżeli stan logiczny rejestru PINX, w polu x jest równy 0, oraz:
bit_is_set(PINX,PXx)
zwracającego wartość 1 jeżeli stan logiczny rejestru PINX, w polu x jest równy 1. Powyższe makra
będą dostępne w programie po dołączeniu biblioteki io.h:
#include <avr/io.h>
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ą:
#include <avr/delay.h>
b) Odczyt danych z klawiatury matrycowej
Do komunikacji z klawiaturą matrycową można wykorzystać funkcje z biblioteki
RKlibAVR autorstwa Roberta Krzysztofa [4]. Do projektu należy dołączyć plik kbd.h dyrektywą:
#include "kbd.h"
5
Ponadto należy dołączyć konfigurację części sprzętowej umieszczonej w pliku config.h:
// linie kolumn klawiatury
#define KBD_PORT_col1
#define KBD_BIT_col1
#define KBD_PORT_col2
#define KBD_BIT_col2
#define KBD_PORT_col3
#define KBD_BIT_col3
#define KBD_PORT_col4
#define KBD_BIT_col4
PORTX
x
PORTX
x
PORTX
x
PORTX
x
// linie wierszy klawiatury
#define KBD_PORT_row1
#define KBD_BIT_row1
#define KBD_PORT_row2
#define KBD_BIT_row2
#define KBD_PORT_row3
#define KBD_BIT_row3
#define KBD_PORT_row4
#define KBD_BIT_row4
PORTX
x
PORTX
x
PORTX
x
PORTX
x
W pliku makefile należy umieścić następujący kod (zastępując całkowicie istniejący tekst):
# Nazwa pliku z funkcją main() - BEZ ROZSZERZENIA!
TARGET = nazwa_pliku_bez_rozszerzenia
# 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)/kbd/sources
6
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
Do inicjalizacji klawiatury matrycowej służy funkcja:
void KBD_init (void)
Odczyt kodu wciśniętego klawisza można uzyskać za pomocą funkcji:
u08 KBD_read (void)
gdzie: u08 liczba całkowita ośmiobitowa (0 do 28 – 1).
Konwersję kodu klawisza na łańcuch znaków dla wyświetlacza LCD można uzyskać za pomocą
funkcji:
char* itoa (int wartosc, char *lancuch_zakow, int notacja)
gdzie: wartosc – liczba do konwersji, *lancuch_zakow – liczba przekształcona na łańcuch znaków,
notacja – system liczbowy (2, 8, 10, 16). Funkcja wymaga dołączenia do projektu biblioteki
stdlib.h:
#include <stdlib.h>
c) Sterowanie wyświetlacza LCD
Do sterowania wyświetlacza LCD zostaną wykorzystane funkcje z biblioteki tAvrLib
autorstwa Tomasza Wasilczyka [5]. 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 config.h 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
7
//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 config.h 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:
void hd44780_putStr (char *str, uint8_t length)
gdzie: *str – wskaźnik do tablicy znaków, lenght – ilość znaków do wyświetlenia.
lenght = -1 funkcja wyświetla wszystkie znaki z tablicy.
Jeżeli
4. Przebieg ćwiczenia
W zestawie uruchomieniowym ZL3AVR wyprowadzenia klawiatury są dostępne na
złączach JP23 i JP3. Pierwsze złącze obejmuje wyprowadzenia wierszy i kolumn (W1 … W4, K1
… K4). Klawiatura, składająca się z 16 przycisków (S1 … S16) znajduje się w prawej dolnej części
zestawu. Za pomocą złącza JP3 można ograniczyć liczbę klawiszy do 4 (S1, S5, S9, S13) zwierając
po jednym styku każdego z przycisków do masy (GND). Klawiatura nie ma wbudowanych
rezystorów podciągających, należy je uaktywnić na wejściach mikrokontrolera.
Przykładowe zadania do wykonania:
a) Napisać i uruchomić program, w którym naciśniecie przycisku spowoduje zaświecenie
diody LED.
b) Napisać i uruchomić program, w którym naciśniecie przycisku spowoduje zgaszenie diody
LED.
c) Napisać i uruchomić program, w którym cztery przyciski sterują dwiema diodami LED
(włącz / wyłącz).
8
d) Napisać i uruchomić program, który spowoduje wypisanie na wyświetlaczu LCD kodu
klawisza klawiatury matrycowej.
W p. c 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 c)). Potencjometr PR1 służy do regulacji kontrastu wyświetlacza.
5. Literatura
[1]
http://www.adatronik.com.pl/klawiatura4x4.jpg
[2]
„8-bit Microcontroller with 32K Bytes In-System Programmable Flash Atmega32
Atmega32L”, 2503O–AVR–07/09, www.atmel.com,
[3]
„avr-libc 1.6.7”, Generated by Doxygen 1.5.6 Wed Jan 6 12:08:48 2010,
c:\Winavr-20100110\doc\avr-libc\,
[4]
R. Krzysztof, Dokumentacja biblioteki RKlibAVR,
http://www.isaa.pl/download/doc_details/89-rklibavr-uniwersalna-biblioteka-dla-avr-gcc.
[5]
T. Wasilczyk, Dokumentacja biblioteki tAvrLib, http://tAvrLib.wasilczyk.pl.
Wersja z dn. 22.02.2011 r.

Podobne dokumenty