Mikrokontroler – Jak to działa?

Mikrokontroler to jedno z najistotniejszych urządzeń w robotyce. Ten niewielki mikrokomputer jednoukładowy, zwany też scalonym systemem mikroprocesorowym, zawiera między innymi podzespoły takie jak pamięć RAM, jednostkę CPU i różne układy wejścia/wyjścia, a także pamięć napisanego programu ROM lub Flash (lub FRAM i MRAM). Urządzenie służy bezpośrednio do sterowania urządzeniami elektronicznymi, co w robotyce ma oczywiście ogromne znaczenie. Warto go poznać z bliska i istotę jego działania na podstawie praktycznych danych z zakresu robotyki.

Czym jest mikrokontroler?

Mikrokontroler to niewielki komputer o równie niewielkiej mocy obliczeniowej, która jest jednak wystarczająca do sterowania większością urządzeń elektronicznych w podstawowym zakresie. W większości przypadków system mikroprocesorowy jest autonomiczny, lecz można go uzupełnić również urządzeniami peryferyjnymi, które zapewniają rozszerzenie jego możliwości. Mikrokontroler dzieli się na bloki funkcjonalne, a te zapewniają wykonanie różnego rodzaju pracy. Charakterystyczną cechą mikroprocesora jest jego taktowanie, które zazwyczaj osiąga nie więcej niż kilkaset MHz, co bywa w większości przypadków przerostem formy nad treścią. Zazwyczaj optymalne taktowanie mikrokontrolera wynosi nie więcej niż kilkadziesiąt MHz, a dostosowuje się je względem zapotrzebowania na moc obliczeniową.

Historia mikrokontrolera

Historia mikrokontrolera sięga 1976 roku, kiedy to pierwszy układ noszący nazwę Intel 8048 został seryjnie wyprodukowany w technologii NMOS. Model ten był wykorzystywany w konsoli gier komputerowych Magnavox Odyssey, w serii Korg Trident, w analogowych syntezatorach Roland Jupiter-4 i ProMar, a także w oryginalnej wersji klawiatury komputerowej popularnej marki IBM. Wynalazcą mikrokontrolera Intel 8048, zgodnie z ustaleniami urzędu patentowego w Stanach Zjednoczonych,  jest Gary Boone pracujący w firmie Texas Instruments. Przedsiębiorstwo z siedzibą w stanie Teksas od lat zajmuje się produkowaniem profesjonalnych półprzewodników.

Wraz z rozwojem technologii zaczęły powstawać coraz bardziej zaawansowane technicznie mikrokontrolery, które charakteryzowały się większą niezawodnością, lepszymi zasobami i parametrami. Zmieniły się także architektury tych układów. Jak powszechnie wiadomo, do mikrokontrolerów wprowadza się rozbudowane i nowoczesne układy peryferyjne, wśród których można wymienić sterowniki wyświetlaczy LCD, sterowniki magistrali ATA, radiomodemy, dekodery MP3 i wiele, wiele innych. Poza klasycznymi rozwiązaniami 8- i 16-bitowymi modelami na rynku dostępne są również mikrokontrolery 32-bitowe. Natomiast w przypadku prostych i niewymagających aplikacji wykorzystuje się uproszczone wersje mikrokontrolerów zamkniętych w niewielkich obudowach, co przekłada się na znaczne obniżenie generowanych kosztów. Aktualnie można spotkać również rozwiązania polegające na wbudowaniu gotowych rdzeni popularnych mikrokontrolerów do bardziej złożonych układów, co pozwala na ujednolicenie standardów programowania poszczególnych urządzeń i umożliwia realizację dowolnych układów wejścia-wyjścia w postaci sprzętowej.

Wśród najpopularniejszych i najczęściej stosowanych mikrokontrolerów można wymienić układy pochodzące od firmy AtmelInfineon, Espressif Systems, STMicroelectronics, Freescale Semiconductor (dawniej znanej jako Motorola), Analog Devices, Hitachi, a także NXP, która do 2006 roku była jednym z oddziałów marki Philips. Zdecydowanie wiodącym producentem w przypadku mikrokontrolerów jest przedsiębiorstwo Intel, narzucające standardy dla masowego rynku.

Co wchodzi w skład mikrokontrolera?

Mikrokontroler to autonomiczny system mikroprocesorowy i składa się z wielu podzespołów, które mają uzupełnić jego pracę. Cała budowa jest dość skomplikowana, lecz koniec końców rozbija się o kilka podstawowych elementów elektronicznych, a zrozumienie ich funkcjonalności oraz cech praktycznych znacznie ułatwia pracę z nimi. W uproszczonej budowie mikrokontrolera znajdziemy między innymi procesor CPU (Central Processing Unit), który odpowiada za wykonanie danego programu, pamięć flash, pamięć RAM oraz ewentualnie układy peryferyjne. Wszystkie te elementy stale ze sobą ściśle współpracują za pomocą napisanego programu, realizowanego przez CPU.

Dane są przesyłane dwiema szynami – szyną adresową oraz szyną danych. Szyna adresowa przesyła dane wyłącznie w jednym kierunku, mianowicie z procesora do innych podzespołów (pamięci RAM, flash oraz układów peryferyjnych), a w drugiej szynie w obu kierunkach, dzięki czemu procesor może wykorzystywać do pracy dane pochodzące właśnie z nich. Z szyny danych w jednej chwili korzysta wyłącznie jeden układ przesyłając bajty (najmniejsza jednostka informacji), ten aktualnie potrzebny, pozostała zaś czeka na zakończenie aktualnego przesyłu. Do tego dochodzi także taktowanie, czyli układ sygnału zegarowego. Polega na generowaniu impulsów o stałej częstotliwości w określonym czasie.

W kontrolerach AVR szyna ma szerokość 8 bitów, co oznacza, iż niektóre informacje będą musiały zostać rozdzielone na kilka “transportów”, co w dość znacznym stopniu spowolni pracę całego układu. Co ciekawe, nowoczesne komputery wykonane w technologii 64-bitowej charakteryzują się szyną ośmiokrotnie szerszą, co ma przełożenie na szybkość wykonywanej przez nie pracy.

Procesor w mikrokontrolerze

Procesor, zwany także centralną jednostką obliczeniową, jest urządzeniem, które steruje całym układem przy pomocy programu komputerowego (w formie rozkazów), zapisanego przeważnie w pamięci FLASH. Jeden rozkaz zawiera informacje na temat rodzaju operacji oraz argumenty. CPU to układ zarówno cyfrowy, jak i sekwencyjny oraz synchroniczny, dlatego charakteryzuje się dość dużym stopniem skomplikowania.

Układ cyfrowy oznacza, w przeciwieństwie do analogowego, iż procesor rozróżnia wyłącznie przeciwstawne stany napięcia (niski lub wysoki), zaś sekwencyjny, że każdy stan nowy jest zależny wyłącznie od poprzedniego stanu oraz aktualnego wejścia. Tryb synchroniczny oznacza z kolei, że cała jego praca jest wykonywana w rytmie zegara częstotliwości (megaherz). Za wykonywanie prostych i złożonych obliczeń arytmetycznych odpowiada Arithmetic Logic Unit (ALU)

Procesor CPU wykonuje takie polecenia matematyczne jak dodawanie, odejmowanie, mnożenie oraz operacje bitowe i jest zbudowany z kilku elementów, które pracują od siebie zależnie. W rejestrach 8-bitowych przechowuje się większość niezbędnych danych, takich jak IP (Instruction Pointer) przechowujący adres pobrania następnego rozkazu, IR (Instruction Register), który służy do przechowywania kodu aktualnego przekazu. Ponadto w 8-bitowych rejestrach znajdziemy również SP (Stock Pointer), do wskazania wierzchołka stosu, a także rejestr statusowy i rejestry ogólnego przeznaczenia. W rejestrze statusowym przechowywane są flagi, głównie tyczące się operacji arytmetycznych, w postaci bitów kontrolnych niezbędnych podczas programowania. Z kolei rejestry przeznaczenia ogólnego (ponumerowanych od R0 do R31) stanowią dla procesora pamięć operacyjną (podręczną) o znacznie krótszym czasie dostępu niż dane z pamięci RAM. Dlatego wczytywanie z niej danych i przetwarzanie informacji jest praktycznie natychmiastowe. 

Pamięć operacyjna RAM

Pamięć RAM (Random Access Memory) przechowuje informacje jedynie podczas ich pracy, dlatego po wyłączeniu zasilania z układu, pamięć całkowicie się wyczyszcza. W przeciwieństwie do pamięci FLASH, pamięć RAM charakteryzuje się bardzo krótkim czasem dostępu do danych oraz brakiem limitu zapisów. Pamięć SRAM (Static RAM) w mikrokontrolerach AVR składa się z 32 adresów rejestrów przeznaczenia ogólnego CPU (od R0 do R31) i zawiera rejestry kontrolne peryferiów, a przy tym działa niezależnie od pamięci FLASH. 

Pamięć masowa flash

W pamięci FLASH (o największej pojemności z całego mikrokontrolera) znajdziemy przechowywane rozkazy, które nie są z niej usuwane po odłączeniu zasilania, co stanowi jedną z wielu różnic względem pamięci RAM. Kolejną jest fakt, iż CPU nie może zapisywać danych na pamięci FLASH, a jedynie je odczytywać, co powoduje, że pamięć ta jest używana głównie do przechowywania programu i tablic stałych oraz kilku innych informacji. Charakterystyczną cechą pamięci FLASH w AVR jest 8-bitowy podział komórek oraz podział na sekcje aplikacji i bootloadera. 

Pamięć EEPROM

Pamięć EEPROM (z ang. electrically erasable programmable read-only memory) służy do przechowywania niewielkiej ilości danych, których zadaniem jest przetrwanie wyłączenia zasilania. Ponadto pozwala mikroprocesorowi na zapis i wymazywanie danych, jednak trwa to znacznie dłużej niż w przypadku pamięci RAM, a sam dostęp do pamięci EPROM jest bardziej skomplikowany. Liczba zapisanych danych jest ograniczona do około 100 tysięcy – ta graniczna wartość została określona przez firmę ATMEL, jednak ciekawostką jest fakt, iż jeden z użytkowników był w stanie zapisać do pamięci EEPROM ponad 4 miliony zapisów i dopiero po przekroczeniu tej liczby mikroprocesor odmówił dalszej współpracy. Warto również wiedzieć, że EEPROM jest rodzajem nieulotnej pamięci komputerowej i w odróżnieniu od pamięci EPROM może być kasowana tylko i wyłącznie przy użyciu prądu elektrycznego. 

Porty wejścia/wyjścia

Porty wejścia/wyjścia są wprowadzone na nóżki układu scalonego mikrokontrolera. Służą one do komunikacji ze światem zewnętrznym, dlatego do portów można podłączyć różnego rodzaju urządzenia. Co ciekawe, mogą one pracować dwukierunkowo, co oznacza dwa sposoby działania – porty mogą wyprowadzać informację wpisaną do nich przez mikroprocesor lub odczytywać dane pojawiające się na linii portu z zewnętrz. Z pewnością opanowanie całego zakresu działania portów wejścia/wyjścia, a także wszelkich podstaw związanych z ich pracą, zapewni sukces w prawidłowym programowaniu mikrokontrolera, dlatego warto szczególnie skupić się na tej wiedzy, by przyswoić z niej jak najwięcej informacji.

Ważną ciekawostką jest fakt, iż im więcej portów wejścia/wyjścia, tym większa możliwość podłączenia w wygodniejszy i łatwiejszy sposób większej ilości urządzeń do mikrokontrolera, bez konieczności stosowania dodatkowych układów scalonych. Najczęściej w robotach korzysta się ze standardowych portów równoległych wejściowo-wyjściowo, które mogą odbierać sygnały cyfrowe z PINów. 

Warto wiedzieć, że alternatywą dla portów wejścia/wyjścia mogą być też inne układy,  wśród których można wymienić między innymi komparatory, generatory przerwań zewnętrznych czy też różnego rodzaju timery.

Układy peryferyjne w robotyce

Nawiązując do powyższego akapitu każdy układ peryferyjny, który może być alternatywą dla portów wejścia/wyjścia cechuje się własnymi rejestratorami konfiguracyjnymi, których zadaniem jest określenie sposobu jego działania. Dla przykładu w przypadku standardowego portu w ATmegach można wymienić trzy rejestry – DDRx, określający kierunek przepływu danych, PORTx wymuszający stan na wyjściu oraz PINX, który odpowiada za odczytywanie stanu na wejściu.

Gdzie stosuje się mikrokontrolery?

Mikrokontrolery należą do grupy urządzeń o szerokim zastosowaniu. Powszechnie można je wykorzystać w różnego typu wbudowanych układach. Ich zadaniem jest sterowanie pracą innych urządzeń lub ich częścią. Mikrokontrolery najczęściej stosuje się w przypadku sprzętu RTV i AGD, nowoczesnych elektronarzędzi, częściach i peryferiach komputerowych, infrastrukturze sieciowej i telekomunikacyjnej, a także w sprzęcie medycznym. Ponadto mikrokontrolery znajdują swoje zastosowanie również w szeroko pojętej automatyce przemysłowej, jak i w sprzętach medycznych, implantach, a nawet w zabawkach. Można je także spotkać w komputerach sterujących pracą silników znajdujących się w pojazdach mechanicznych.

Czym jest ISP?

ISP jest to układ programowania (z ang. In System Programming) pozwalający na programowanie mikrokontrolera bez konieczności wyjmowania go z układu aplikacyjnego. Jest to bardzo wygodne rozwiązanie, gdyż starsze generacje mikrokontrolerów wymagały programowania w specjalnie przeznaczonych do tej czynności programatorach, oczywiście po wyjęciu urządzenia z danej aplikacji. Właśnie z tego względu układ ISP znacznie usprawnił i ułatwił programowanie, gdyż wystarczy podłączyć sygnały z programatora do elementów mikrokontrolera (nóżki), bezpośrednio w układzie, i rozpocząć pracę. Gdy cały proces dobiegnie końca urządzenie zostanie zresetowane, a następnie zacznie wykonywać program, który został wcześniej zapisany w pamięci FLASH.

Mikrokontroler – pisanie programów

Procesor po restarcie rozpoczyna pracę od wczytania i wykonania instrukcji z IP, po czym zmienia ją w celu wczytania kolejnej. Wartości IP nie muszą zmieniać się w skoku co 1, dlatego program nie musi być realizowany zawsze w tej samej kolejności. Pozwalają na to skoki w postaci pętli oraz instrukcje warunkowe. Program po zainicjowaniu układów peryferyjnych przechodzi do pętli nieskończonej lub (jeśli taka nie istnieje) wykonuje wszystkie funkcje i po dojściu do ostatniego adresu w pamięci FLASH inicjalizuje proces od nowa. Głównym językiem używanym do programowania mikrokontrolerów jest asembler, który wyróżnia się względną prostotą. Większość komend to skróty angielskich wyrazów, dzięki czemu są stosunkowo łatwe do zrozumienia dla konstruktorów-amatorów, np. INC oznacza Increment, czyli przyrost. Jedna instrukcja przypada na jeden cykl zegara.

Zatrzymanie pętli – przerwania

Podczas wykonywania programu może się zdarzyć sytuacja, w której powinna nastąpić prawidłowa reakcja mikrokontrolera. Zwykle tego typu wydarzenia są związane z działaniem całego układu, w którym pracuje urządzenie. Z uwagi na to stosuje się tak zwane przerwania. Są to zdarzenia, które mają na celu przerwanie wykonywania głównego programu i uruchomienie specjalnej funkcji obsługi przerwania. Gdy opcja ta obsłuży przerwanie, nastąpi powrót do głównego programu i wznowienie jego wykonywania od miejsca, w którym został przerwany. Jednak aby wykorzystać zatrzymanie pętli w swoich programach, należy wiedzieć, co jest ich źródłem. Przerwania mogą być wewnętrzne lub zewnętrzne. Pierwsze z wymienionych pochodzą od wewnętrznych części mikrokontrolera, natomiast drugie są generowane przez urządzenia zewnętrzne sterowane za pomocą mikrokontrolera.

Działania arytmetyczne CPU

Procesor dysponując jedynie podstawowymi działaniami matematycznymi w postaci dodawania, odejmowania, mnożenia i operacji bitowych musi przeprowadzić tysiące mniej i bardziej skomplikowanych obliczeń. Co ciekawe, brak możliwości dzielenia powoduje, że procesor w celu obliczenia wyniku musi wykonać znacznie więcej pracy, a zakończenie obliczenia może wymagać wielu rejestrów procesora. Inaczej sprawa się ma w przypadku dzielenia przez potęgi dwójki, która polega w systemie binarnym na przesunięciu liczby w prawo lub w lewo, podobnie jak w systemie dziesiętnym. W przypadku bardziej skomplikowanych funkcji logarytmicznych czy całkach sprawa ma się zupełnie inaczej. Aby przyspieszyć obliczenia stosuje się aproksymację funkcji, która ma usprawnić całą pracę mikrokontrolera. Działanie to polega na przybliżaniu (approximate) wartości w danych przedziałach. W funkcjach trygonometrycznych warto wykorzystać tablice obliczonych wartości, po czym dokonać ich precyzyjnego skalowania.

Dodaj komentarz