Wielopoziomowe Menu W C

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

K U R S

Wielopoziomowe menu w C
Opisane w†artykule funkcje wykona- Jednym z†najwiÍkszych ìpoøeraczyî czasu i†energii
³em jako demonstracjÍ sposobu imple-
mentacji menu. Nie s¹ one zwi¹zane programisty, obok uruchomienia programu, jest tak zwany
z†øadnym konkretnym urz¹dzeniem. Do
interfejs uøytkownika. Mikrokontroler nie potrzebuje do pracy
ich uruchomienia uøy³em p³ytki ekspe-
rymentalnej w³asnej konstrukcji, zbliøo- wyúwietlacza, klawiatury, diod úwiec¹cych LED i†temu
nej funkcjonalnie do AVR Starter Kit
i†zawieraj¹cej mikrokontroler AT89S8252,
podobnych elementÛw, o†ile nie jest to úciúle zwi¹zane
programator oraz z³¹cza doprowadzaj¹ce z†operacjami zapisu lub odczytu danych. Wszystkie te
sygna³ do wyprowadzeÒ mikrokontrole-
ra. Do p³ytki pod³¹czy³em wyúwietlacz drobiazgi s¹ potrzebne nam, ludziom, abyúmy mogli
LCD (pracuje z†interfejsem 4-bitowym) wprowadzaÊ parametry i†poznaÊ rezultat wykonania przez
oraz klawiaturÍ wykonan¹ jako matrycÍ
3†wierszy i†4†kolumn (w sumie 12 kla- mikrokontroler okreúlonego programu.
wiszy). Port P2, do ktÛrego pod³¹czy- W†artykule przedstawiÍ sposoby tworzenia jedno-
³em klawiaturÍ, dodatkowo wyposaøy³em
w†rezystory pull-up o†wartoúci 47 kΩ. i†dwupoziomowych menu, wyúwietlanych na typowym
Uøy³em ich ze wzglÍdu na d³ugie kable
wyúwietlaczu LCD 4†linie po 20 znakÛw.
³¹cz¹ce klawiaturÍ z†portem mikrokont-
rolera. W†tab. 1 i†na rys. 1 zawarto
opis po³¹czeÒ elektrycznych. numer 0†argumentu (argument wywo³a- ki) poleceniem curr &= Row_mask (ilo-
nia np. 0xFE), drugiej bitu numer czyn bitowy). WartoúÊ maski rÛwnieø
Odczyt klawiatury 1†itd. W†pliku nag³Ûwkowym KBD3X4.H zdefiniowana zosta³a w†pliku nag³Ûwko-
Funkcje odczytuj¹ce klawiaturÍ za- za pomoc¹ dyrektywy #define zdefinio- wym. Bit aktywny przyjmuje stan niski.
deklarowa³em jako zewnÍtrzne funkcje wano w³aúciwe wartoúci argumentu wy- W†zwi¹zku z†tym, øe ³atwiej jest porÛw-
biblioteczne i†umieúci³em w†module wo³ania funkcji KBD_Read (Co- nywaÊ bity znajduj¹ce siÍ w†stanie wy-
o†nazwie KBD3X4. Pierwsza z†nich char lumn_1...3), ktÛre pÛüniej uøywane s¹ sokim, wartoúÊ zwracanej zmiennej jest
KBD_Read(char column) s³uøy†do obs³u- przez funkcjÍ Key_Number. negowana (polecenie return(~curr), ì~î
gi klawiatury na poziomie sprzÍtu, ope- SposÛb funkcjonowania KBD_Read to operator dope³nienia jedynkowego).
ruj¹c na portach mikrokontrolera. Dru- jest nastÍpuj¹cy: argument column jest Funkcja Key_Number przyporz¹dko-
ga - char Key_Number(void) - przydzie- zapisywany do portu klawiatury i†tym wuje kombinacjom bitÛw odczytanych
la klawiszom odpowiednie kody. samym linia ktÛrejú z†kolumn przyjmu- z†portu mikrokontrolera okreúlone kody.
Funkcja KBD_Read w†wyniku dzia- je stan niski. Na skutek przyciúniÍcia Konstrukcja programu zbliøona jest do
³ania zwraca unikatow¹ dla kaødego (zwarcia) klawisza linia wiersza - bÍ- budowy klawiatury. Warunki if tworz¹
z†wciúniÍtych klawiszy, odpowiadaj¹c¹ d¹ca normalnie w†stanie wysokim - rodzaj matrycy, na ktÛrej przeciÍciach
mu wartoúÊ lub 0†- jeúli øaden z†kla- przejdzie w†wymuszony stan niski. Stan znajduj¹ siÍ kody klawiszy. Wartoúci
wiszy nie jest wciúniÍty. Nie pracuje ten jest dwukrotnie odczytywany przez Row_1...4 rÛwnieø predefiniowane s¹
ona poprawnie, jeúli wciúniÍto wiÍcej mikrokontroler: za drugim razem po 50 w†pliku nag³Ûwkowym. Jedynka na po-
niø jeden klawisz. Zawsze zwracana milisekundach. Zrobi³em tak, aby zycji bitu wiersza odpowiada wciúniÍ-
jest jako pierwsza kombinacja klawiszy upewniÊ siÍ, øe klawisz zosta³ naciú- ciu klawisza. W†przypadku, gdy øaden
z†kolumny bÍd¹cej pierwsz¹ odczytan¹. niÍty celowo i†by³o to zamiarem uøyt- z†klawiszy nie jest naciúniÍty, funkcja
Jako argument wywo³ania spodziewane kownika. Jest to rÛwnieø bardzo prosty zwraca wartoúÊ 0.
jest wyzerowanie bitu odpowiadaj¹cego filtr zak³ÛceÒ mog¹cych pojawiÊ siÍ na
odczytywanej kolumnie. W†zwi¹zku doprowadzeniu portu. Menu jednopoziomowe
z†tym, øe kolumna pierwsza klawiatury Aby zapobiec wp³ywowi na wynik Najprostszym rodzajem menu jest me-
pod³¹czona jest do P2.0, druga do P2.1 dzia³ania funkcji bitÛw innych niø przy- nu jednopoziomowe. Charakteryzuje siÍ
a†trzecia do P2.2, odczytowi pierwszej porz¹dkowane wierszom klawiatury, s¹ ono tym, øe po wybraniu opcji nastÍpu-
kolumny odpowiada wyzerowanie bitu one maskowane (ustawiane w†stan nis- je bezpoúrednie wywo³anie akcji. Menu
takie jest ³atwe do wykonania, jeúli
Tab. 1. Przypisanie funkcji wyprowadzeniom mikrokontrolera w†ca³oúci mieúci siÍ na ekranie LCD.
Nazwa portu Oznaczenie Funkcja Znacznie gorzej jest, gdy ma ono na
przyk³ad 8†pozycji, a†na ekranie mamy
P2.0 PC0 Doprowadzenie pierwszej kolumny matrycy klawiszy do dyspozycji 2†czy 4†linie. WÛwczas
P2.1 PC1 Doprowadzenie drugiej kolumny matrycy klawiszy musimy nie tylko okreúliÊ nazwy po-
P2.2 PC2 Doprowadzenie trzeciej kolumny matrycy klawiszy szczegÛlnych opcji, ale rÛwnieø sposÛb
P2.3 PC3 Doprowadzenie drugiego wiersza matrycy klawiszy wyúwietlania menu po przekroczeniu roz-
miaru ekranu. Wyliczenie tych wszyst-
P2.4 PC4 Doprowadzenie trzeciego wiersza matrycy klawiszy
kich zmiennych zajmuje duøo pamiÍci
P2.5 PC5 Doprowadzenie czwartego wiersza matrycy klawiszy programu oraz czasu mikrokontrolera.
P2.6 PC6 Doprowadzenie pierwszego wiersza matrycy klawiszy Pocz¹tek programu (czÍúÊ deklara-
P3.4 PD4 Sygna³ RS wyœwietlacza LCD cyjna zmiennych) zawiera definicjÍ ty-
P3.5 PD5 Sygna³ READ wyœwietlacza LCD pu o†nazwie menuitem. Jest to struktu-
ra pojedynczego rekordu opisuj¹cego li-
P3.6 PD6 Sygna³ ENABLE wyœwietlacza LCD
niÍ menu. Rekordy te s¹ nastÍpnie
P1.4 PB4 Bit 5 szyny danych wyœwietlacza LCD zgrupowane w†tabeli menus, tam teø
P1.5 PB5 Bit 6 szyny danych wyœwietlacza LCD nadawana jest im wartoúÊ. Kilku s³Ûw
P1.6 PB6 Bit 7 szyny danych wyœwietlacza LCD omÛwienia wymaga rola poszczegÛlnych
P1.7 PB7 Bit 8 szyny danych wyœwietlacza LCD pÛl rekordu.

Elektronika Praktyczna 9/2003 77


K U R S

menu pos³ugujÍ siÍ zmienn¹ globaln¹


o†nazwie actpos. Jest to zmienna typu
signed char (z zakresu od -128...127).
Jej wartoúÊ ulega zmianie po naciúniÍ-
ciu klawiszy umownie przyjÍtych jako
kierunek dÛ³ (8) lub gÛra (2). Dodatko-
wo wartoúÊ tej zmiennej porÛwnywana
jest z†liczbami okreúlaj¹cymi jej maksi-
mum i†minimum. W†przypadku przekro-
czenia maksimum, zmiennej actpos na-
dawana jest wartoúÊ minimum i†vice
versa: gdy jej wartoúÊ jest mniejsza niø
wartoúÊ minimalna, zmiennej nadawana
jest wartoúÊ maksimum. Tu jedna uwa-
ga: wartoúÊ maksymaln¹ stanowi liczba
elementÛw tablicy menus. Jej elementy
numerowane s¹ od 0. W†zwi¹zku z†tym
numer ostatniego elementy tablicy to
rozmiar-1, a†pierwszego to 0. Na sku-
Rys. 1. Schemat klawiatury matrycowej 3 (kolumny) x 4 (wiersze) wykorzystywanej tek tak przyjÍtej konwencji rÛwnieø
w modelu i†zmiennej actpos naleøy w†przypadku
dolnej granicy zakresu nadaÊ wartoúÊ
Pole o†nazwie name to ³aÒcuch spowoduje przesuniÍcie wskazaÒ na po- maksymalnej liczby opcji pomniejszon¹
znakÛw wyúwietlany na ekranie i†sta- zycjÍ 4†w†tablicy (pozycje numerowane o†1. Odpowiada za to polecenie if (--
nowi¹cy nazwÍ (etykietÍ) danej pozy- s¹ od 0), a†nie na literÍ ìcî w†napisie actpos < 0) actpos=maxoptions-1. Po-
cji menu. Jest on widziany przez uøyt- ìopcja 1†.î, co odpowiada³oby dodaniu dobnie jest w†przypadku gÛrnej grani-
kownika dokonuj¹cego wyboru opcji. do wartoúci wskaünika 3†bajtÛw. Tyle cy. Wskaünik adresuje obszar leø¹cy
Pole ptr to offset dodawany do adre- s³owem przypomnienia o†arytmetyce poza tablic¹ juø wÛwczas, gdy przyj-
su pocz¹tku tablicy - wykazu menu. wskaünikÛw. WrÛÊmy do sposobu defi- muje wartoúÊ jej rozmiaru. Z†mojej
Jego rola polega na wskazaniu miejs- niowania menu. praktyki wynika, øe mimo faktycznie
ca, od ktÛrego maj¹ byÊ wyúwietlane Po uruchomieniu funkcji wyúwietla- zachodz¹cej rÛwnoúci, w†takiej sytuacji
etykiety menu. I†tak dla przyk³adu j¹cej, wskaünik do wykazu ustawiany bezpieczniej jest uøyÊ znaku ìwiÍksze
ptr=4 spowoduje, øe w†linii numer jest na jego pocz¹tek (pozycja 0). Na- lub rÛwneî. W†zwi¹zku z†tym linia
1†wyúwietlacza LCD znajdzie siÍ ety- stÍpnie pobierane s¹ wartoúci programu przyjmuje postaÊ if (++actpos
kieta menu spod adresu menus+4. Ko- menus[0].y0 oraz menus[0].ptr. WartoúÊ >= maxoptions) actpos=0.
lejne pole - y0 - to numer linii, ptr dodawana jest do adresu pocz¹tku Program g³Ûwny wykonuje czynnoú-
w†ktÛrej ma siÍ znajdowaÊ znak wy- tablicy (w tym przypadku ptr=0) i†od ci zwi¹zane z†obs³ug¹ wyúwietlacza
boru w†momencie, gdy wskaünik aktu- wyliczonego w†ten sposÛb adresu wy- (inicjalizacja trybu 4-bitowego oraz de-
alnej pozycji w†tabeli-wykazie wskazu- úwietlane s¹ na ekranie LCD 4†etykiety finicja znakÛw uøytkownika), a†nastÍp-
je na rekord zwi¹zany z†tym paramet- menu. nie wywo³uje funkcjÍ obs³ugi menu.
rem. Kombinacja dwÛch ostatnich pa- Parametr pobrany z†tablicy y0 to ar- Zwracana przez tÍ funkcjÍ wartoúÊ roz-
rametrÛw umoøliwia efektywne i†czy- gument funkcji wyúwietlaj¹cej znaczni- patrywana jest nastÍpnie przez wyraøe-
telne wyúwietlanie zawartoúci menu. ki wyboru. W†tym przypadku, poniewaø nie switch - case. Oczywiúcie moøna
SpÛjrzmy dla przyk³adu na deklaracjÍ y0=0, znaczniki bÍd¹ wyúwietlone na uøyÊ instrukcji if lub chociaøby zbudo-
menu pochodz¹c¹ z†prezentowanego wspÛ³rzÍdnych (0,0) oraz (19,0). Podob- waÊ tablicÍ z†wykazem wywo³ywanych
programu: nie bÍdzie, gdy wskaünik pokaøe pozy- funkcji, a†zwrÛcon¹ w†wyniku dzia³ania
//deklaracja tablicy-wykazu cjÍ 2, 3†i†dalsze. Za kaødym razem wartoúÊ potraktowaÊ jako offset lub
//opcji menu wartoúci y0 i†ptr okreúlaj¹ pozycjÍ zna- wskaünik do tejøe tablicy.
code menuitem menus[maxoptions] = ku wyboru oraz tÍ etykietÍ menu, ktÛ-
{{“opcja 1 . ”, 0, 0}, ra znajdzie siÍ w†pierwszej linii wy- Menu dwupoziomowe
{“opcja 2 . ”, 0, 1}, úwietlacza. Rozbudowuj¹c menu o†dodatkowy
{“opcja 3 . ”, 0, 2}, Do wyliczenia wartoúci wskaünika poziom, zawsze naleøy liczyÊ siÍ
{“opcja 4 . ”, 0, 3}, do aktualnej pozycji w†tabeli-wykazie z†tym, øe zajmie ono duøo miejsca
{“opcja 5 . ”, 1, 3},
{“opcja 6 . ”, 2, 3},
List. 1. Sposób budowania definicji menu
{“opcja 7 . ”, 3, 3},
{“opcja 8 . ”, 4, 3}} code menuitem mainmenus[6] =
{{name = “opcja menu głównego 1”, |--> code submenu submenu1[3] =
ptr = 0, | {{“podmenu 1.1”,0,0,11},
//deklaracja wskaźnika do pozycji y0 = 0, | {“podmenu 1.2”,0,1,12},
//w tablicy-wykazie menu nextmenu = &submenu1, ----------------| {0,0,0,0}}
retval = 0},
code menuitem *ptrmenus = &menus;
{name = “opcja menu głównego 2”, --> code submenu submenu2[7] = {
Wskaünik ptrmenus jest tego same- ptr = 0, | {{“podmenu 2.1”,0,0,21},
go typu, co element tablicy - wykazu. y0 = 1, | {“podmenu 2.2”,0,1,22},
nextmenu = &submenu2, ----------------| {“podmenu 2.3”,0,2,23},
W†zwi¹zku z†tym operacje arytmetyczne retval = 0}, {“podmenu 2.4”,0,3,24},
wykonywane na wskaüniku dodaj¹ (lub {“podmenu 2.5”,1,3,25},
odejmuj¹) do (od) jego wartoúci liczbÍ {“podmenu 2.6”,2,3,26},
bajtÛw identyczn¹ z†rozmiarem pojedyn- {0,0,0,0}}
{name = “opcja menu głównego 3”,
czego elementu tablicy. Na przyk³ad ptr = 0,
wykonanie poleceÒ: y0 = 2,
ptrmenus = &menus nextmenu = 0,
retval = 3},
ptrmenus = ptrmenus+3 //równoważne ............
//polecenie to ptrmenus += 3

78 Elektronika Praktyczna 9/2003


K U R S

w†pamiÍci mikrokontrolera. Sytuacja menu i†jego opcje. WrÛÊmy do sposobu Ogranicza ona od gÛry wartoúÊ zmien-
wygl¹da zupe³nie inaczej, gdy tworzo- tworzenia definicji menu g³Ûwnego. Na nej globalnej POS_IN_SUBMENU, ktÛra
na jest aplikacja dla komputera PC list. 1 przedstawiono schemat budowy nie moøe byÊ wiÍksza niø maxsubopt-1
niø†gdy dla mikrokontrolera. Ten pier- definicji menu g³Ûwnego oraz odpowia- i†jest sprawdzana po kaødym naciúniÍciu
wszy w†porÛwnaniu z†drugim posiada daj¹cych mu opcji podmenu. klawisza w†gÛrÍ czy w†dÛ³.
niewyobraøalne wrÍcz zasoby do wyko- Tablica mainmenu zawiera wykaz Po wejúciu do podmenu zaczyna
rzystania, istne ìmorze pamiÍciî, przy definicji etykiet i†parametrÛw menu rÛwnieø dzia³aÊ klawisz o†kodzie 0x0B
dodatkowo bardzo duøej szybkoúci dzia- g³Ûwnego. Polu wskaünikowemu o†na- pe³ni¹cy rolÍ podobn¹ do ESCAPE
³ania. Pewnych nawykÛw†i†przyzwycza- zwie nextmenu nadawana jest wartoúÊ w†komputerze PC. Jego naciúniÍcie powo-
jeÒ (o ile takie s¹) nie da siÍ po pros- adresu - wskazania do wykazu opcji duje, øe nastÍpuje powrÛt do menu
tu w†tym momencie wykorzystaÊ, cho- podmenu, jeúli takie istnieje. Kolorami g³Ûwnego bez podejmowania jakiejkolwiek
ciaø nowe, pojawiaj¹ce siÍ na rynku wyrÛøniono te przypisania. W†takim akcji i†moøna wÛwczas dokonaÊ innego
mikrokontrolery imponuj¹ wrÍcz swoi- przypadku pole retval ma wartoúÊ 0. wyboru. WybÛr zawsze potwierdzany jest
mi zasobami sprzÍtowymi. Zostawmy Gdy podmenu nie istnieje (moøe to byÊ przez naciúniÍcie klawisza ENTER.
jednak rozwaøania i†wrÛÊmy do opisu na przyk³ad opcja ìUruchomî, ìObliczî Podobnie jak w†poprzednim przyk³a-
sposobu wykonania menu. itp.), polu retval nadawana jest war- dzie, program g³Ûwny zawiera inicjaliza-
Przy jego budowie pos³uøy³em siÍ toúÊ, ktÛr¹ ma zwrÛciÊ funkcja, a†polu cjÍ wyúwietlacza, wywo³anie funkcji ob-
rozwi¹zaniami z†pierwszego przyk³adu nextmenu naleøy†przypisaÊ wartoúÊ 0. s³ugi menu oraz konstrukcjÍ switch -
programowania, jednak wyraünie zosta- Wymagane jest, aby kaøda tablica- case w†celu rozpoznania wybranej opcji.
³y rozgraniczone menu g³Ûwne od me- wykaz etykiet podmenu by³a zakoÒczo-
nu podrzÍdnego. Rozgraniczaj¹ je za- ny rekordem, w†ktÛrym co najmniej po- Uwagi na temat programu
rÛwno funkcje realizuj¹ce wyúwietlanie le name ma wartoúÊ 0. Rekord ten jest Funkcje w†moich przyk³adach czÍsto
etykiet i†wybÛr spomiÍdzy nich, jak niezbÍdny, poniewaø na podstawie jego pos³uguj¹ siÍ wskaünikami do struktur.
i†typy rekordÛw uøytych do deklaracji. po³oøenia obliczana jest przez funkcjÍ Ich konstrukcja oraz sposÛb zapisu jest
Rozpocznijmy analizÍ od menu g³Ûwne- wyúwietlaj¹c¹ podmenu d³ugoúÊ wyka- specyficzny i†wymaga kilku s³Ûw omÛ-
go. Dla potrzeb budowy tablicy-wykazu zu opcji, a†tym samym liczba etykiet wienia zw³aszcza dla tych osÛb, ktÛre
opcji menu g³Ûwnego zadeklarowa³em do wyúwietlenia. spotykaj¹ siÍ z†nimi po raz pierwszy.
typ o†nazwie menuitem. Zawiera on Menu g³Ûwne wyúwietlane jest Definicja tabeli zawieraj¹cej rekordy
pola poznane juø wczeúniej (name, ptr w†identyczny sposÛb jak to by³o robio- jest doskona³ym mechanizmem zw³asz-
i†y0) i†oprÛcz nich nowe, o†nazwach ne w†przypadku menu jednopoziomowe- cza przy tworzeniu baz danych i†pli-
nextmenu oraz retval. go. Jego obs³ug¹ zajmuje siÍ funkcja kÛw dyskowych. I†chociaø w†tych przy-
Pole nextmenu to wskaünik do ob- Main_Menu i†jej funkcje us³ugowe. Jako k³adach programÛw nie s¹ uøywane
szaru wykazu opcji odpowiadaj¹cego rezultat zwraca ona liczbÍ jednobajto- øadne zbiory znajduj¹ce siÍ na dysku,
mu podmenu. W†przypadku, gdy na- w¹ bÍd¹c¹ kodem wybranej opcji. to jednak tablica rekordÛw do z³udze-
stÍpny poziom nie jest dostÍpny, Po naciúniÍciu klawisza o†kodzie nia przypomina strukturÍ bazy danych,
wskaünikowi nadawana jest wartoúÊ 0. 0x0C umownie funkcjonuj¹cego jako EN- a†leø¹cy gdzieú w†obszarze code pamiÍ-
Z†tym polem úciúle zwi¹zana jest za- TER, funkcja sprawdza, czy pole next- ci mikrokontrolera wykaz - plik dysko-
wartoúÊ pola retval. Zawiera ono licz- menu przyporz¹dkowane bieø¹cej pozy- wy. Istniej¹ dwie podstawowe metody
bÍ zwracan¹ przez funkcjÍ w†przypad- cji zawiera jak¹ú wartoúÊ. Jeúli tak, fun- odwo³ywania siÍ do pozycji w†takiej
ku wyboru opcji. Jak ³atwo siÍ domyú- kcja wywo³uje obs³ugÍ podmenu jako strukturze:
liÊ, wartoúÊ wpisana do retval nie ma parametr, podaj¹c zawartoúÊ odpowied- - z†zastosowaniem indeksÛw (np. me-
øadnego znaczenia w†przypadku, gdy niego pola nextmenu. W†zwi¹zku z†tym, nus[1], menus[5] itd.),
wywo³ywane jest podmenu. WÛwczas øe chcia³em napisaÊ funkcjÍ uniwersal- - z†zastosowaniem wskaünika (wskaüni-
to, funkcja obs³ugi menu zwrÛci war- n¹, zdoln¹ do wyúwietlenia podmenu kÛw).
toúÊ zapisan¹ w†polu retval w³aúciw¹ o†rÛønych iloúciach etykiet, przy wywo- Ta pierwsza metoda jest bardzo
dla danej opcji (etykiety) podmenu. ³aniu funkcja musi obliczyÊ, jaka jest prosta. Ilustruje j¹ przyk³ad umieszczo-
Wskaünik nextmenu jest typu sub- liczba pozycji wykazu przekazanego ja- ny na list. 2. Indeks to po prostu nu-
menuitem. Ten typ zmiennych zosta³ ko argument wywo³ania. Minimalna mer pozycji w†tabeli, do ktÛrego ø¹da
utworzony dla potrzeb tablic-wyka- wartoúÊ to 1, maksymalna 127. Koniec dostÍpu aplikacja. Jeúli mamy do czy-
zÛw†opcji menu drugiego poziomu. Jest wykazu rozpoznawany jest po tym, øe nienia z†tabel¹ zawieraj¹c¹ 10 elemen-
on prawie taki sam, jak uøywany do pole name (etykieta menu) ma wartoúÊ tÛw, to indeks moøe przyj¹Ê wartoúci
potrzeb menu g³Ûwnego. ale oprÛcz pod- znaku o†kodzie 0. Wynik obliczeÒ zapa- od 0†do 9. Gdy mamy do czynienia
stawowych pÛl (etykieta name, po³oøe- miÍtywany jest w†zmiennej maxsubopt. z†tablic¹ struktur, dostÍp do pola moø-
nie znaku wyboru y0, offset wskaünika
ptr oraz wartoúci zwracanej przez menu
List. 2. Odwołanie do tablicy rekordów poprzez indeksy
retval) nie zawiera øadnych wskaünikÛw
typedef struct //definicja typu - struktury (rekordu) danych
do nastÍpnych wykazÛw opcji. {
£atwo jest rozbudowaÊ podmenu char x; //struktura zawiera 3 pola typu char: x, y, colour
o†nastÍpne poziomy. Wystarczy uøyÊ po- char y;
dobnych mechanizmÛw jak dla budowy char colour;
} attr;
poziomu 2. Jest w†tym jednak drobna
trudnoúÊ: naleøy w†jakiú sposÛb podaÊ data attr points[10]; //deklaracja tablicy zawierającej rekordy danych
uøytkownikowi informacjÍ, z†ktÛrego me-
void main()
nu wybierana jest opcja, ot chociaøby {
przez wyúwietlenie úcieøki - opisu miej- char temp;
sca, w†ktÛrym siÍ znajduje. Trudno jest attr pt;
znaleüÊ to miejsce na ekranie LCD
points[0].x = 1; //nadanie wartości polu x tablicy wskazywanemu
o†niewielkich rozmiarach. W†praktyce //przez indeks 0
ograniczam wiÍc menu budowanych temp = points[8].y; //pobranie wartości pola y wskazywanemu przez indeks 8
przez siebie urz¹dzeÒ co najwyøej do //do zmiennej temp
pt = point[2]; //przepisanie rekordu danych z tablicy (indeks=2)
2...3 poziomÛw i†zazwyczaj nie ma po-
//do zmiennej pt będącej
trzeby tworzenia dalszej hierarchii. Za- } //tego samego typu, co element tablicy
miast tego warto jest przemyúleÊ uk³ad

Elektronika Praktyczna 9/2003 79


K U R S

List. 3. Odwołanie do tablicy rekordów poprzez wskaźnik Odwo³anie do pola struktury umoø-
liwia operator wygl¹daj¹cy jak strza³ka
typedef struct //definicja typu - struktury (rekordu) danych
{ skierowana w†prawo, utworzony ze
char x; //struktura zawiera 3 pola typu char: x, y, colour znaku wiÍkszoúci oraz odejmowania (-
char y; >) nastÍpuj¹cego bezpoúrednio po nim.
char colour; Stosuj¹c go, naleøy†pamiÍtaÊ, øe ma
} attr;
bardzo wysoki priorytet. Operacje
data attr points[10]; //deklaracja tablicy zawierającej rekordy danych (pointer+temp)->x oraz temp+pointer->x
data attr *pointer = &points; //deklaracja wskaźnika oraz nadanie mu wartości nie s¹ rÛwnowaøne. Jednak bardziej
//początkowej: wskazania na początek tablicy points
jaskrawy przyk³ad stanowi porÛwnanie
void main() sposobu funkcjonowania wyraøeÒ
{ ++pointer->x oraz (++pointer)->x.
char temp; W†tym pierwszym przypadku wyraøe-
attr pt;
nie zwiÍksza zmienn¹ x o†1, a†nie
pointer->x = 1; //nadanie wartości polu x tablicy wskazywanemu wskaünik do struktury. W†drugim
//przez indeks 0 wskaünik jest zwiÍkszany przed odwo-
temp = (pointer+8)->y; //pobranie wartości pola y wskazywanemu przez
//indeks 8 do zmiennej temp
³aniem do struktury i†na skutek tego
pt = pointer+2; //przepisanie rekordu danych z tablicy (indeks=2) nastÍpuje przejúcie do nastÍpnego
//do zmiennej pt będącej w†kolejnoúci elementu tablicy.
} //tego samego typu, co element tablicy Na tej samej zasadzie wyraøenie:
- *pointer->x udostÍpnia coú, na co
wskazuje x,
na uzyskaÊ podaj¹c po kropce jego na- pointer_1++; //spowoduje przesunię- - *pointer->x++ zwiÍksza x†po udostÍp-
zwÍ: zmienna = menu[1].ptr. //cie wskazania zmiennej nieniu obiektu wskazywanego przez
Inaczej ma siÍ sytuacja, gdy odwo- //points[0].x na points[0].y x,
³anie do struktury odbywa siÍ przez //(o 1 bajt) - (*pointer->x)++ zwiÍksza coú, na co
wskaünik. Pos³uømy siÍ tym samym pointer_2++; //spowoduje przesunię- wskazuje x,
przyk³adem - na list. 3 umieszczono //cie wskaźnika z rekordu - *pointer++->x zwiÍksza zmienn¹
program zmodyfikowany w†taki sposÛb, //points[0] na points[1] i jest pointer po udostÍpnieniu obiektu
aby odwo³ania do pÛl nastÍpowa³y //równoważne wyrażeniu wskazywanego przez x.
przez wskaünik a†nie przez indeks. //pointer_1 = Jak wspomnia³em wczeúniej, wyko-
Wskaünik powinien byÊ tego same- //pointer_1 + sizezeof(attr) rzystuj¹c mechanizmy uøyte do budowy
go typu, co wskazywany obszar da- pointer_1 += 8; //spowoduje przesu- drugiego poziomu menu ³atwo jest do-
nych. W†konsekwencji wszelkie opera- //nięcie wskaźnika o 8 bajtów, to daÊ nastÍpne poziomy. Wystarczy, øe
cje arytmetyczne na nim wykonywane //jest na zmienną points[2].y typ submenuitem bÍdzie zawiera³†wskaü-
powoduj¹ jego zmianÍ o†tak¹ liczbÍ baj- pointer_2 += 8; //spowoduje przesu- nik do nastÍpnego wykazu menu, a†fun-
tÛw, jaki jest rozmiar wskazywanego //nięcie wskaźnika o 8 rekordów, kcja Sub_Menu zapamiÍta i†przechowa
elementu. Ilustracj¹ tej zasady jest po- //to jest na pozycję 9 w tabeli stan zmiennej POS_IN_SUBMENU. Praw-
niøszy przyk³ad: pointer_1 += temp; //spowoduje dopodobnie bÍdzie rÛwnieø wymagaÊ
//przesunięcie wskazania o 2 baj- s³owa kluczowego reentrant (kompilator
data char *pointer_1 = &points; //ty, to jest na zmienną RC-51) powoduj¹cego, øe funkcja moøe
data attr *pointer_2 = &points; //points[0].colour byÊ wywo³ywana rekurencyjnie. Rozbu-
data char temp = 2; pointer_2 += temp; //spowoduje dowÍ pozostawiam jednak inwencji
... //przesunięcie wskaźnika o 2 re- w³asnej Czytelnika.
... //kordy, to jest na pozycję Jacek Bogusz, AVT
... //3 w tabeli jacek.bogusz@ep.com.pl

80 Elektronika Praktyczna 9/2003

You might also like