Tworzenie środowiska programistycznego

Transkrypt

Tworzenie środowiska programistycznego
Tworzenie środowiska programistycznego Arduino (2)
– o programowaniu mikrokontrolera słów kilka
Programowanie mikrokontrolera
Kontrola tego, co się dzieje w procesorze CPU
jest możliwa przy użyciu kodu programu. Procesor
CPU odczytuje instrukcje kodu programu, a następnie dokonuje krok po kroku określonych czynności.
Każdy typ procesora CPU ma swoje specyficzne
instrukcje, które „rozumie”, nazywane zestawem
instrukcji.
Zestaw instrukcji jest tym, co „mówi” procesorowi
CPU, które dane są do pobrania i w jaki sposób mają
być one przetworzone. To ma miejsce, w trakcie
programowania. Operacje takie jak odczyt danych,
wykonywanie operacji matematycznych lub wyprowadzania danych są zdefiniowane w zbiorze
instrukcji.
Ponieważ procesor CPU może jedynie odczytywać i zapisywać dane binarne, zestaw instrukcji składa się z grup binarnych danych, zwykle składających
się z komend 1- lub 2-bajtowych. Polecenia te są
nazywane kodem maszynowym (także powszechnie
nazywanych kodami operacji lub w skrócie „opcodes”). Każda instrukcja ma specyficzny kod binarny
dla wskazania instrukcji, jakich danych instrukcja
wymaga.
Zestaw instrukcji mikrokontrolera ATmega AVR
wykorzystuje 16-bitowe (2-bajtowe) instrukcje do
sterowania działaniem procesora CPU. Na przykład,
instrukcja dodania wartości danych przechowywanych w rejestrach R1 i R2, a następnie umieszczenia
wyniku w rejestrze R1, wygląda następująco:
0000 1100 0001 0010
Gdy procesor CPU przetwarza niniejszą instrukcję, to „wie”, że ma pobrać wartości danych z rejestrów, użyć ALU (Arithmetic Logic Unit – jednostka
arytmetyczno-logiczna ) do ich dodania, a następnie
umieścić wynik z powrotem w rejestrze R1.
Wiedza o tym, jakich kodów maszynowych oraz
jakich funkcji i potrzebnych do tego danych wydaje
się, że przekracza możliwości programistów, ale od
czego są podręczniki i poniższe informacje.
Wyjście poza kod maszynowy
Kod maszynowy jest wykorzystywany bezpośrednio przez mikrokontroler do przetwarzania danych, ale niestety nie jest to najłatwiejszy język
programowania do przeczytania i zrozumienia dla
przeciętnego śmiertelnika. Aby rozwiązać ten pro-
blem, programiści stworzyli kilka innych sposobów
tworzenia kodu programu. Popatrzmy na metody,
które wyjaśnią nam w jaki sposób mogą one pomóc
w programowaniu Arduino.
Kodowanie z językiem asemblera
Język asemblera jest ściśle związany z kodem
maszynowym; przydziela on tekst kodu mnemonicznego do indywidualnego reprezentowania poszczególnych instrukcji kodu maszynowego. Tekst
mnemoniczny jest to zwykle krótki ciąg znaków, który
symbolizuje spełnianą rolę (takich jak np. dodawanie «ADD» dwóch wartości). To sprawia, że pisanie
podstawowych programów mikrokontrolera staje się
dużo łatwiejsze.
Na przykład, jeśli pamiętamy z poprzedniego rozdziału, w kodzie maszynowym, aby dodać wartości
zapisane w rejestrze R1 do wartości zapisanych
w rejestrze R2 i umieścić wynik w rejestrze R1 kod
instrukcji powinien wyglądać następująco:
0000 1100 0001 0010
Jednak kod asemblera dla tej funkcji wygląda
następująco:
add r1, r2.
Prawda, że teraz ma to o wiele większy sens dla
„zwykłych” ludzi i jest o wiele łatwiejsze do zapamiętania dla procedur kodowania. Każda z instrukcji
kodu maszynowego dla rodziny mikrokontrolerów
ATmega AVR jest skojarzona przez język asemblera
z mnemoniką. Są one wymienione w instrukcjach
obsługi mikrokontrolerów AVR firmy Atmel.
Seria mikrokontrolerów ATmega AVR (których
używa Arduino) zawiera 282 oddzielnych rozpoznawalnych instrukcji, a więc istnieje 282 osobnych
mnemoników języków asemblerowych. Te instrukcje
można podzielić na sześć kategorii:
– ładowanie danych z lokacji pamięci do rejestru,
– wykonywanie operacji matematycznych na wartościach rejestrowych,
– porównywanie dwóch wartości rejestrów,
– kopiowanie wartości rejestru do pamięci,
– odgałęzienie do innego położenia kodu programu,
– interakcja z cyfrowym interfejsem I/O.
Istnieją osobne instrukcje dla każdego rejestru,
każdej operacji matematycznej i każdej metody kopiowania danych do i z pamięci. W tym momencie
nie jest trudno zrozumieć, dlaczego istnieje aż 282
osobnych instrukcji.
SERWIS ELEKTRONIKI
1
Programowanie mikrokontrolera Arduino
Chociaż język asemblera Atmel AVR został poprawiony, a raczej ulepszony w stosunku do kodowania
w języku maszynowym, tworzenie fantazyjnych programów dla Arduino z użyciem asemblera jest nadal
dość trudne i zazwyczaj pozostaje w gestii bardziej
zaawansowanych programistów. Na szczęście dla
nas, istnieje jeszcze prostszy sposób programowania urządzeń Arduino, co zostanie omówione
w następnym rozdziale.
Ułatwienie życia z językiem C
Nawet przy korzystaniu z języka asemblera Atmel
AVR, konieczność zapamiętania 282 oddzielnych
instrukcji może być nadal dość dużym wyzwaniem,
zwłaszcza w sytuacjach, gdy trzeba z tych oddzielnych 282 instrukcji wybrać i użyć tej jednej, właściwej
dla danej operacji. Na szczęście dla nas, jeszcze
jeden poziom programowania sprawia, że życie staje
się znacznie łatwiejsze dla programistów.
Języki programowania wyższego poziomu pomagają „wyrugować” znajomość wewnętrznego
funkcjonowania mikrokontrolera z kodu programowania. Języki programowania wyższego poziomu
„ukrywają” większość wewnętrznych części pracy
procesora z urządzeń programujących, dzięki czemu
programista może skupić się tylko na kodowaniu.
Na przykład, w językach programowania wyższego poziomu, można po prostu przypisać nazwy
zmiennych danym, a kompilator konwertuje te nazwy
zmiennych w odpowiednich miejscach pamięci lub
rejestrów do użycia przez procesor CPU. W języku
programowania wyższego poziomu, aby dodać dwie
liczby i zapisać wynik z powrotem w tym samym
miejscu, należy po prostu napisać coś takiego:
value1 = value1 + value2;
Teraz to jest nawet lepsze niż wersja kodu maszynowego.
Kluczem do używania języków programowania
2
wyższego poziomu jest to, że musi istnieć kompilator, który może konwertować kod programu przyjazny dla użytkownika na kod języka maszynowego,
który będzie działać w mikrokontrolerze. To się
wykonuje przez kombinację kompilatora i biblioteki
kodów.
Kompilator czyta kod języka programowania
wyższego poziomu i konwertuje go do kodu języka
maszynowego. Ponieważ musi on generować kod
języka maszynowego, kompilacja jest specyficzna
dla bazowego procesora CPU, dzięki czemu program będzie realizowany. Różne procesory CPU
wymagają różnych kompilatorów.
Oprócz tego, że musi on być w stanie przekształcić kod języka programowania wyższego poziomu
na kod maszynowy, większość kompilatorów musi
posiadać również zestaw typowych funkcji, które
ułatwiają programiście pisanie kodu specyficznego
dla procesora CPU. Jest to tak zwana biblioteka
kodów. W związku z tym, różne procesory CPU
mają różne biblioteki dające możliwość dostępu do
swoich możliwości.
Obecnie dostępnych jest wiele różnych języków
programowania wyższego poziomu, ale programiści
Atmel wybrali popularny język programowania C
jako język używany do tworzenia kodu dla rodziny
mikrokontrolerów AVR. Utworzyli oni kompilator
do konwersji kodu C na kod języka maszynowego
mikrokontrolera AVR i oprócz tego bibliotekę funkcji
do interakcji z określonymi portami cyfrowymi i analogowymi mikrokontrolera.
Gdy twórcy projektu Arduino wybrali mikrokontroler ATmega dla swojego projektu, chcieli również,
aby możliwe było łatwe kodowanie projektów bez
użycia programatorów. Aby to zrobić, wbudowali do
istniejącego języka Atmel C kompilator i bibliotekę
oraz utworzyli kolejną bibliotekę kodu specyficznego
dla używania mikrokontrolera AVR w środowisku
Arduino.
SERWIS ELEKTRONIKI