Prezentowane materiały są przeznaczone dla uczniów szkół ponadgimnazjalnych Autor artykułu: mgr Jerzy Wałaszek |
©2015 mgr
Jerzy Wałaszek
|
Projekt płytki aplikacyjnej APP001 |
|||||||||||||||||||||||||||||||||||||||||||||
Następnym krokiem po zbudowaniu
płytki bazowej
z mikrokontrolerem ATTiny13 będzie budowa dla niej różnych
przystawek, które posłużą nam do nauki programowania oraz
dostarczą wiele zabawy i radości. Pierwsza płytka aplikacyjna
APP001 będzie zawierała 5 diod LED oraz dwa przyciski. Zbudujemy
ją w wersji z elementami przewlekanymi oraz z elementami SMD.
Najpierw schemat:
Zworki J0 i J1 służą do dołączania do linii PB0 i PB1 diod D0, D1 lub przycisków W0, W1. Dzięki temu rozwiązaniu płytka APP001 stanie się bardziej uniwersalna. Dioda DP sygnalizuje gotowość płytki do pracy. Jako diody D0...D4 możesz zastosować LED'y czerwone jasne lub niebieskie jasne. Oporniki są tak dobrane, aby zbytnio nie obciążać linii PB0...PB4. Linia PB5 nie jest używana. Złącze kątowe męskie będzie wpinane w złącze żeńskie na płytce bazowej. Patrząc na nie od przodu mamy następujące przypisania sygnałów:
Projekt płytki aplikacyjnej APP001Uruchom aplikację Eagle. W panelu sterowania otwórz Projects, kliknij prawym przyciskiem myszki w katalog eagle i z menu kontekstowego wybierz opcję New Project. Utwórz nowy projekt o nazwie APP001. Nadaj mu odpowiedni opis. Kliknij prawym przyciskiem myszki w projekt APP001 i z menu wybierz New → Schematic. Na ekranie pojawi się znany ci już edytor schematów. Zapisz schemat pod nazwą app001.sch. Dodaj do niego ramkę jak w poprzednich projektach. Na schemacie umieść następujące elementy biblioteczne:
pinhead PINHD-2X4
PINHD-2X4/90
x 1 (goldpiny kątowe męskie do połączenia
z płytką bazową)
pinhead PINHD-1X3 PINHD-1X3 x 2 (zworki) switch-omron 10-XX x 1 (przyciski) supply1 Vcc x 1 (zasilanie) supply1 GND x 4 (masa) led LED LED3MM x 6 (diody LED) rlc R-EU R-EU_0204/7 x 6 (oporniki)
Teraz rozmieść elementy zgodnie ze schematem i połącz je przewodami (goldpiny kątowe JP1 obróć do góry nogami i odbij lustrzanie). Nadaj elementom odpowiednie nazwy i wartości: Zapisz schemat i przełącz się do edytora PCB. Ułóż elementy jak poniżej i dopasuj odpowiednio wielkość płytki PCB:
Uruchom narzędzie Autorouter, warstwę górną (Top) ustaw na nieaktywną (N/A) i każ utworzyć ścieżki.
Za pomocą poznanych narzędzi porozsuwaj odpowiednio ścieżki i pogrub je. Niektóre ścieżki poprowadź inaczej. Postaraj się wyeliminować przejścia ścieżek pomiędzy niektórymi polami lutowniczymi.
Projekt płytki jest gotowy. Poniżej masz odpowiednie grafiki, do obróbki i do wydruku na drukarce laserowej.
|
Funkcje logiczne |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Programując mikrokontrolery, działasz na poziomie
bitów. Dlatego operacje na bitach muszą stać się twoją drugą naturą.
W rozdziale tym omówimy sposoby przetwarzania bitów. Wiedza ta jest
wręcz kluczowa, upewnij się zatem, że wszystko rozumiesz. W języku C mamy dwa rodzaje funkcji. Pierwszy rodzaj to funkcje operujące na wartościach logicznych (ang. logic functions) – traktują one swoje argumenty jak wartości logiczne. W języku C istnieją dwie wartości logiczne:
true (prawda) –
dowolna wartość różna od zera
false (fałsz) – wartość równa zero
Język C nie ogranicza cię co do typu argumentu. Argumentem może być dowolne wyrażenie liczbowe lub logiczne. W wyrażeniach logicznych stosuje się zwykle różne operatory porównań, np.:
Funkcji logicznych mamy trzy:
Negacja (zaprzeczenie logiczne) tworzy zaprzeczenie swojego argumentu. Jeśli argument jest fałszywy, to wartością negacji będzie prawda i na odwrót. Alternatywa (suma logiczna) ma wartość prawdy, jeśli chociaż jeden z jej argumentów jest prawdziwy. Inaczej otrzymujemy fałsz. Koniunkcja (iloczyn logiczny) ma wartość prawdy, jeśli wszystkie jej argumenty są prawdziwe. Inaczej otrzymujemy fałsz.
Funkcje logiczne pozwalają tworzyć złożone warunki, które często wykorzystujemy w programach. Na przykład:
Drugim rodzajem funkcji logicznych są funkcje operujące na poszczególnych bitach (ang. bitwise functions). Funkcje te traktują swoje argumenty nie jako wartości logiczne, lecz jako ciągi bitów. Operacja jest wykonywana na odpowiadających sobie bitach w argumentach funkcji. Wynikiem jest również ciąg bitów, w którym bity zostały ustawione zgodnie z definicją funkcji. Logicznych funkcji bitowych mamy cztery:
Przykłady:
Zwróć szczególną uwagę na funkcję bitowej sumy symetrycznej. Jeśli bit jednego z argumentów ma wartość 1, to w wyniku na tym miejscu pojawi się zawsze zaprzeczenie bitu drugiego argumentu. Własność ta jest często wykorzystywana do zmiany stanu wybranych bitów na przeciwny. Funkcje logiczne i logiczne bitowe można ze sobą łączyć. Na przykład:
Jak widzisz, funkcje logiczne pozwalają mikrokontrolerowi testować różne skomplikowane warunki. |
Manipulacje bitami |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
W operacjach na bitach pojawia się pojęcie maski
bitowej (ang. bit mask). Jest to po
prostu jeden z argumentów bitowej funkcji logicznej, w którym w
odpowiedni sposób zostały ustawione bity, tak aby otrzymać pożądany
wynik operacji. Cechą wspólną wszystkich przedstawionych tutaj
operacji bitowych będzie to, że zmianie ulegną wybrane bity.
Pozostałe będą niezmienione. Jest to bardzo istotne, ponieważ w
rejestrach mikrokontrolera, co zobaczymy później, bity mogą posiadać
różne znaczenia i zwykle chcemy zmienić stan określonych bitów,
które kontrolują jakąś funkcję. Pozostałe bity powinny pozostać w
swoim stanie. Ustawianie bitów na 1Operacja ta jest bardzo prosta do wykonania. Tworzymy maskę bitową, w której pożądane bity. Następnie wykonujemy bitową operację alternatywy argumentu z maską. W wyniku otrzymujemy wartość, w której zostaną ustawione na 1 bity odpowiadające bitom maski 1. Pozostałe bity zachowają swój stan z argumentu. Przykład:
Podłącz do płytki bazowej APP000 płytkę APP001, płytkę bazową połącz z programatorem, a programator z gniazdem USB twojego komputera. Ustaw obie zworki J0 i J1 na płytce APP001 w położenie górne (diody D0 i D1 mają być dołączone do linii PB0 i PB1). Następnie uruchom środowisko Eclipse, utwórz w nim nowy projekt dla ATTINY13, skopiuj poniższy program do edytora, skompiluj go i prześlij do programatora. Program tworzy w zmiennej licznik liczący w górę. Stan licznika z ustawionym na 1 bitem b2 jest przesyłany do rejestru PORTB. W ten sposób dioda D2 zawsze świeci.
W programie pojawiła się nowa konstrukcja: stała. Stała jest nazwą, której przypisano stałą wartość. Stałe definiujemy za pomocą konstrukcji:
#define nazwa wyrażenie
Nie umieszczaj za definicją stałej średnika. Powodem jest to, że powyższa deklaracja tworzy nazwę, która w programie zostanie zastąpiona podanym wyrażeniem wraz ze wszystkimi znakami, które to wyrażenie zawiera. Tak zdefiniowanej stałej nie możesz w programie zmieniać, ponieważ nie jest ona zmienną. Jeśli bity maski muszą się zmieniać, to maskę tworzymy dynamicznie lub w zmiennej. Zerowanie bitówW tym przypadku tworzymy maskę, w której bity do wyzerowania są ustawione na 0. Następnie wykonujemy bitową operację koniunkcji argumentu z maską. Wynikiem jest wartość, w której zostaną wyzerowane bity odpowiadające bitom o stanie 0 w masce. Pozostałe bity zachowają swój stan z argumentu. Przykład:
Program tworzy w zmiennej licznik liczący w górę. Stan licznika z wyzerowanym bitem b2 jest przesyłany do rejestru PORTB. W ten sposób dioda D2 zawsze jest zgaszona.
Kolejny program działa identycznie jak poprzedni. Pokazujemy w nim jedynie jak utworzyć maskę dynamicznie bezpośrednio w wyrażeniu:
Przeanalizujmy to wyrażenie:
Widzisz zatem, że została utworzona maska z wyzerowanym bitem PB2. Negacja bitówOperacja jest równie prosta jak ustawianie bitu na 1. Tworzymy maskę bitową z ustawionymi na 1 bitami, które mają zostać zanegowane. Następnie wykonujemy operację bitowej sumy symetrycznej argumentu z maską. W wartości wynikowej bity argumentu odpowiadające bitom maski 1 zostaną zanegowane. Przykład:
Program tworzy w zmiennej licznik liczący w górę. Stan licznika z zanegowanym bitem b2 jest przesyłany do rejestru PORTB.
Operacje złożoneWykorzystując podane tutaj operacje bitowe, możemy tworzyć różne skomplikowane wyrażenia. W następnym programie tworzymy licznik, który zlicza w górę co 1/10 sekundy. Następnie przenosimy do rejestru PORTB bity b3 i b4 licznika (na linie PB0 i PB1). Po tej operacji bity PB1...PB3 przesuwamy o 1 pozycję w lewo na bity PB2...PB4. Otrzymujemy w ten sposób dosyć ciekawy efekt świetlny.
|
Modyfikacja |
||||||||||||||||||||||||||||||||||||||||||
Modyfikacja rejestru lub zmiennej polega na zmianie
zawartości na podstawie tego, co dana zmienna lub rejestr zawiera.
Brzmi to może i skomplikowanie, lecz w rzeczywistości jest bardzo
proste. Wyobraźmy sobie, że chcemy dodać do zmiennej np. liczbę 3.
Możemy wykonać to następująco:
zmienna = zmienna + 3;
A gdybyśmy chcieli ją pomnożyć przez 3, to zastosowalibyśmy polecenie:
zmienna = zmienna * 3;
To właśnie jest modyfikacja, czyli zmiana zawartości, lecz nie na zupełnie nową, oderwaną od poprzedniej, tylko na wartość, która w jakiś sposób jest powiązana z poprzednią zawartością. Ponieważ tego rodzaju konstrukcje programowe są często wykorzystywane, w języku C istnieją specjalne operatory modyfikacji zmiennych i rejestrów. Jeden z operatorów modyfikacji już
poznałeś:
zmienna++ ++zmienna
Jeśli takie wyrażenie stosujesz samodzielnie, to nie ma znaczenia, który z nich wybierzesz. W obu wypadkach zmienna zwiększy swoją zawartość o 1. Różnica pojawia się, gdy użyjesz takiej konstrukcji w wyrażeniu. Np.:
a = b++; a = ++b;
W pierwszym przypadku wartością wyrażenia b++ jest pierwotna zawartość zmiennej b. Dopiero później b zostaje zwiększone o 1. Czyli do zmiennej a trafi b sprzed modyfikacji. W przypadku drugim zmienna b jest najpierw zwiększana, a następnie wynik (czyli b zwiększone o 1) staje się wartością wyrażenia. Czyli do zmiennej a trafi wartość b już zwiększona o 1. Istnieje prosty sposób zapamiętania działania operatora ++. Wyrażenie czytamy od strony lewej do prawej, jeśli natkniemy się najpierw na zmienną, to wartością wyrażenia jest zawartość zmiennej (mówimy wtedy o tzw. późnej modyfikacji). Jeśli natkniemy się na operator ++, to wartością wyrażenia jest zwiększona o 1 zawartość zmiennej (mówimy o tzw. wczesnej modyfikacji). W
podobny sposób działa operator
zmienna-- --zmienna
Dla każdej operacji dwuargumentowej mamy odpowiednie operatory modyfikacji:
zmienna = zmienna
operator wyrażenie; → zmienna operator= wyrażenie;
Na przykład operator
zmienna += wyrażenie; a += 5; // do zmiennej a dodaj 5 a += b-1; // do zmiennej a dodaj b-1
W poniższej tabeli zebraliśmy operatory modyfikacji dla poznanych dotychczas operacji arytmetycznych, logicznych i bitowych:
Ciekawą cechą operacji przypisania i modyfikacji w języku C jest to, że posiadają one wartość i mogą uczestniczyć jako argumenty w wyrażeniach. Wyrażenie z operatorem przypisania = ma wartość przypisywaną. Na przykład wyrażenie:
a = 5;
ma wartość 5, ponieważ tyle przypisujemy zmiennej a. Pozwala to wykonywać łańcuchowe przypisania:
a = b = c = d = 10;
Do wszystkich zmiennych a, b, c i d trafi liczba 10. A całość wyrażenia dalej ma wartość 10. Wartością wyrażenia z operatorem modyfikacji jest wartość zmodyfikowanej zmiennej. Jeśli np. zmienna a zawiera 10, to wyrażenie:
a += 5;
Przyjmie wartość 15, ponieważ taką wartość będzie posiadać zmodyfikowane a. Jeśli teraz użyjemy tej operacji w wyrażeniu:
b = 5 * (a += 5);
to do zmiennej a trafi 15, a do zmiennej b trafi 15 x 5, czyli 75. Możliwości te mogą kusić początkujących programistów, jednakże ja preferuję czytelny, zrozumiały kod od poniższego horroru:
a *= ++b - (d %= (a /= c++ + --d)) * (b &= --c - d++); Poniższy program tworzy w rejestrze PORTB licznik zwiększający swą zawartość o 3 przy każdym obiegu pętli (co 1 sekundę). Licznik zlicza od 0 do 30. Program jest przeznaczony dla płytki APP001. Zworki J0 i J1 na płytce APP001 ustaw w górnym położeniu.
|
I Liceum Ogólnokształcące |
Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl
W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe