|
|
mikrokontrolery.net |
||||||||||||||||||||||
|
Programowanie mikrokontrolerów 8051 w jezyku C - część 3 Instrukcja switch i preprocesor.
zmienna może byc dowolnym wyrażeniem bądź zmienną, pod warukiem że wartość tej zmiennej lub wyrażenia jest typu całkowitego. Nasz przykładowy program niech realizuje następującą funkcję : po nacisnięciu przycisku zapal przeciwną diodę LED (tzn "od drugiej strony"). Przyjrzyjmy sie kodowi naszego programu :
Jak zapewne zauważyłeś, pojawiła się nowa dyrektywa preprocesora - #define - jak nazwa wskazuje służy ona do definiowania. W rzeczywistości ma ona dwojakie zastosowanie. Po pierwsze służy do prostego przypisania do ciągu znaków bądź stałęj wartości liczbowej lub, jak w naszym przypadku, do określenia "wygodniejszej" nazwy jakiejś zmiennej. Po drugie do definiowania symboli kompilacji warunkowej. Z drugim zagadnieniem spotkamy się w dalszej części kursu, więc teraz nie zaprzątajmy nim sobie uwagi. Tak więc za pomocą dyrektywy #define przypisaliśmy do napisu klawiatura napis P2. W tym miejscu należy wyjaśnić co to takiego jest preprocesor. Tak więc słowo "preproesor" jest połączeniem słów "pre" - przed oraz "procesor" - w tym przypadku kompilator. Tak więc preprocesor jest programem uruchamianym przed uruchomieniem właściwego kompilatora. Preprocesor służy do wstępnej obróbki pliku źródłowego. Gdy preprocesor przegląda plik źródłowy i natrafi na ciąg znaków zdefiniowany przez dyrektywe #define, to zastąpi ten ciąg, ciągiem do niego przypisanym. Dzięki temu mozemy zamiest niewiele znaczących nazw portu uzywać w programie jasnych i jednoznacznie mówiących o ich przeznaczeniu nazw zmiennych i stałych. Po nadaniu portom naszego mikrokontrolera wygodnych i przejrzystych nazw nadchodzi czas na właściwy program. I znowu będzie on wykonywany w pętli nieskończonej while(1). Na początku tej pętli przypiszemy do portu diody liczbę 0xFF czyli 255. Spowoduje to wygaszenie diod po zwolnieniu przycisku, a także w sytuacji gdy naciśniemy więcej niż jeden przycisk. Następnie pojawia się instrucka switch. Jako zmienną tej instrukcji wykorzysatmy naszą klawiaturę. Teraz należy sprawdzić przypadek naciśnięcia każdego z przycisków osobno. Ponieważ naciśnięcie przycisku jest sygnalizowane wymuszeniem na linii, do której jest podłączony stanu niskiego, to po naciśnięciu przycisku S1 klawiatura przyjmie wartość 11111110 binarnie, czyli 254 dziesiętnie. Jeżeli naciśnięcie tego przycisku zostanie stwierdzone, to naley zapalić diodę D8 - przez przypisanie do portu diody liczby 01111111 dwójkowo, czyli 127 dziesiętnie. Po wykonaniu założonego zadania należy opuścić isntrukcję switch za pomocą słowa kluczowego break. W podobny sposób sprawdzamy pozostałe siedem przypadków. W powyższym przykładzie niezbyt elegancko wygląda zarówno sprawdzanie który klawisz został naciśnięty, jak i zapalanie odpowiedniej diody LED. Podczas pisania programu nie należy podawać stałych liczbowych (ani żadnych innych) bezpośrednio, tylko nalezy wcześniej zdefioniować stałą o nazwie jasno mówiącej o jej przeznaczeniu. Pozatym, w sytuacji gdy będziemy musieli zmienić stałą (oczywiście na etapie pisania programu, a nie w czasie jego działania) to w bardziej rozbudowanych programach zmienienie tej liczby w miescach w których nalezy ją zmienić będzie bardzo kłopotiwe. Tym bardziej, że nie będziemy mogli użyć machanizmu "znajdż/zamień", ponieważ łatwo zmienimy nie ten znak co trzeba. Bardziej elekgancka (oczywiście nie najbardziej - ta będzie za chwile) wersja programu jest przedstawiona poniżej :
Jako "nazwy jasno mówiące o przenaczeniu stałej" wybrałem pozx, gdzie x = 1..8. Jak łatwo można sie domysleć "poz" to skrót od "pozycja". Ponieważ stałe liczbowe odpowiadające przyciskom, jaki diodm LED sa identyczne nie zastosowałem rozróżnienia czy chodzi o pozycję przycisku czy diody LED. Jednak już naprawde elegancko będzie, gdy użyjemy odpowiednich stałych dla diod i przycisków osobno.
Teraz nasz program wygląda juz bardzo przejrzyście. Ja wybrałem nazwy identyczne
z numerami elementów na mojej płytce uruchomieniowej, Ty możesz je dowolnie
zmienić. Gdyby porównać kod wynikowy powyższych trzech programów to dla każdego
z nich byłby identyczny. Dzieje się tak, że z punktu widzenia kompilatora
te trzy programy są identyczne, ponieważ w "miejscach strategiczych"
występują te same dane. Jest to kolejnym objawem preprocesora - kod źródłowy
programu przed kompilacją został doprowadzony do postaci zrozumiałej przez
kompilator (gdyby pominąć proces przetwarzania pliku przez preprocesor, to
kompilator zgłosiłby mnóstwo błedów).
|
||||||||||||||||||||||
|
|
|||||||||||||||||||||||
|
|
|||||||||||||||||||||||
|
|
|||||||||||||||||||||||
|
(c) 2004-2008 Radosław Kwiecień |