Konfigurator MPLAB Code Configurator (cz. 1)

O przydatności mikrokontrolerów do konkretnych zadań decydują dwie podstawowe właściwości: wydajność obliczeniowa rdzenia oraz dostępna pamięć programu i danych, a także ilość i jakość układów peryferyjnych. Trudno jednoznacznie odpowiedzieć, która z nich jest bardziej istotna. Wydajność ma duże znaczenie w aplikacjach wymagających skomplikowanych obliczeń, na przykład w zaawansowanych algorytmach sterowania silnikami BLDC. Tam oprócz wydajnego rdzenia niezbędna jest sprzętowa jednostka obliczeń zmiennoprzecinkowych FPU, a czasami też jednostka DSP. W takim przypadku wymagana jest szybka jednostka z rdzeniem 32-bitowym. Jednak nawet bardzo szybki rdzeń w sporej części zadań będzie wymagał wsparcia sprzętowych układów peryferyjnych. Dopiero połączenie odpowiedniego rdzenia z właściwymi układami peryferyjnymi daje możliwość optymalnej pracy w wielu różniących się od siebie układach sterowania.

Jednym z ciekawszych producentów mikrokontrolerów jest firma Microchip. W portfolio firmy znajdziemy mikrokontrolery od prostych 8 bitowych ze starym rdzeniem PIC16F, poprzez zmodyfikowany 8-bitowy PIC18F i 16 bitowe jednostki PIC24, a także dsPIC30 i dsPIC33, aż do 32-bitowych układów PIC32. Po przejęciu firmy Atmel, ilość dostępnych opcji jest jeszcze większa. Microchip od zawsze poważnie traktował swoje układy peryferyjne. Jakiś czas temu pojawiła się ciekawa oferta mikrokontrolerów z bardzo prostym i tanim rdzeniem PIC16F “obudowanym” przez szereg zaawansowanych układów peryferyjnych. Te układy mogą pracować niezależnie od rdzenia (core independent). Rola rdzenia sprowadza się do zaprogramowania lub przeprogramowania w trakcie pracy układów peryferyjnych i wykonania prostych algorytmów sterowania. To rozwiązanie jest sukcesywnie przenoszone na rodziny z wydajniejszymi rdzeniami i na mikrokontrolery z rdzeniami Atmela.

Środowisko MPLAB X IDE

Rozbudowane układy peryferyjne wymagają zaawansowanej konfiguracji. Wykonuje się ją przez zapisywanie bitów rejestrów kontrolnych SFR. To żmudna i niewdzięczna praca, wymagająca dużego skupienia. Dlatego skonfigurowanie układów peryferyjnych zabiera dużo cennego czasu programistów i generuje dodatkowe koszty opracowania urządzenia. Żeby ten czas znacząco ograniczyć, stosuje się specjalne narzędzia – konfiguratory układów peryferyjnych zintegrowane ze środowiskami projektowymi IDE. Microchip udostępnia bezpłatnie świetne środowisko MPLAB X IDE integrujące sobie wszystkie narzędzia niezbędne w procesie tworzenia oprogramowania dla mikrokontrolerów:

  • Rozbudowany edytor kodu źródłowego,
  • Mechanizmy automatycznej integracji z kompilatorami języka C – MPLAB XC,
  • Symulację sprzętową i programową tworzonego kodu,
  • Obsługę firmowych programatorów i symulatorów ICD.

MPLAB X IDE oparto o platformę NetBeans i ma możliwość łatwego rozszerzania swoich funkcji przez dodawanie wtyczek (Plugins), również produkowanych przez firmy zewnętrzne. Jednym z takich rozszerzeń jest konfigurator układów peryferyjnych MPLAB Code Configurator (MCC). Wersja instalacyjna MPLAB X IDE nie instaluje automatycznie MCC i żeby używać plug-in, trzeba go pobrać i zainstalować. Na rysunku 1 pokazano jak to zrobić. W pasku narzędzi wybieramy ikonę Tools, następnie Plugins. W oknie Plugins zaznaczamy na liście MPLAB Code Configurator i klikamy na Install. Wtyczka zostanie automatycznie pobrana z serwera Microchipa i zainstalowana. Proces instalacji jest zakończony po zamknięciu i ponownym uruchomieniu MPLAB X IDE.

Rysunek 1. Wtyczka MCC na liście wtyczek do zainstalowania (plugins)

Każde zadanie wykonywane w MPLAB X IDE musi być ujęte w ramy projektu zawierającego wszystkie niezbędne pliki źródłowe, wynikowe i pomocnicze. Typowa praca nad projektem polega na edycji plików źródłowych, kompilacji, symulacji działania (usuwanie błędów) i zapisywania wyniku pracy do pamięci Flash mikrokontrolera. Wiele tych czynności jest zautomatyzowanych i w większości przypadków nie ma potrzeby bardziej zaawansowanych działań (na przykład modyfikacji skryptu linkera).

Konfigurator MPLAB Code Configurator

Konfigurator MPLAB Code Configurator pracuje w połączeniu z projektem środowiska MPLAB X IDE. Dlatego najpierw musimy utworzyć nowy projekt z menu File\New Project\Standalone Projectrysunek 2.

Rysunek 2. Wybór rodzaju projektu

W kolejnych krokach wybieramy mikrokontroler (rysunek 3) i programator/debugger (rysunek 4)

Rysunek 3. Wybór mikrokontrolera

Rysunek 4. Wybór programatora/debuggera

Ja do testów wybrałem mały moduł ewaluacyjny M(R)X PIC16F18446 z wbudowanym mikrokontrolerem i programatorem/debuggerem. Kreator projektu generuje wymaganą strukturę katalogów, ale bez plików źródłowych będących szkieletem programu.

Rysunek 5. Okno projektu dla modułu M(R)X PIC16F18446

Szkielet programu generuje wtyczka MPLAB Code Configurator w aktywnym projekcie. Uruchamia się ją z menu Tools/Embedded/MPLAB Code Configurator Open/Close lub przez kliknięcie na ikonę MCC – rysunek 6.

Rysunek 6. Uruchomienie wtyczki MCC

Przy pierwszym uruchomieniu MCC automatycznie tworzony jest plik o rozszerzeniu .mc3 z bazą danych zawierającą wszystkie informacje o bieżącym stanie konfiguracji. Ten plik jest zapisywany w katalogu Important Files i można mu nadać swoją unikalna nazwę. Przy każdym uruchomieniu MCC konfiguracja jest pobierana z tego pliku i przed zamknięciem wtyczki trzeba ponownie ją zapisać.

Rysunek 7. Plik z bazą danych konfiguracji

Jak już wspomniałem MCC uzupełnia szkielet programu o pliki źródłowe:

  • main.c
  • katalog MCC Generated Files z plikami źródłowymi zawierającymi definicje bitów konfiguracyjnych mikrokontrolera (c), układu taktowania, definicji przypisania wyprowadzeń mikrokontrolera do funkcji alternatywnych oraz pliki konfigurujące poszczególne układy peryferyjne.

Na rysunku 8 pokazano przykładowe pliki wygenerowane przez MCC.

Rysunek 8. Przykładowe pliki źródłowe wygenerowane przez MCC

Interfejs konfiguratora

Konfigurator składa się z kilku głównych okien:

  • Project Resources (zasoby projektu),
  • Device Resources (zasoby mikrokontrolera),
  • Okna konfiguracji wybranego modułu,
  • Menadżera wyprowadzeń (pin Manager) składającego się z okien konfiguracji wyprowadzeń i widoku obudowy z funkcjami wyprowadzeń.

W oknie zasobów projektu Project Resources umieszczono elementy poddawane konfiguracji. Oprócz modułów peryferyjnych, o których powiemy dalej, standardowo są tu elementy:

  • Interrupt module – przeznaczony do konfigurowania układu przerwań powiązanych z działaniem układów peryferyjnych i przerwań zewnętrznych,
  • Pin Module – przeznaczony do końcowej konfiguracji wyprowadzeń mikrokontrolera,
  • System module – przeznaczony do konfiguracji bitów konfiguracyjnych bezpieczników (fuse bits).

Konfiguracja fuse bits

Zacznijmy od konfigurowania bitów konfiguracyjnych fuse bits. W oknie Project Resources wybieramy System module. Pojawia się wtedy okno ustawień System Module z dwoma zakładkami: Easy Setup i Register. Mikrokontrolery Microchip, nawet te z prostym rdzeniem PIC16F, mogą mieć wiele bitów konfiguracyjnych programujących oscylator taktujący rdzeń, licznik watchdoga, układy generowania sekwencji zerowania po włączeniu zasilania (POR), układy kontroli napięcia zasilającego BOR (Brown Out Reset), a także protekcji odczytu pamięci Flash itp. Najlepiej jest, kiedy definicje fuse bits są umieszczone w kodzie źródłowym języka C, bo nie trzeba wtedy za każdym razem ustawiać ich przed programowaniem pamięci mikrokontrolera.

Rysunek 9. Konfiguracja systemu – fuse bits

Na rysunku 9 pokazano okno System module z zakładką Easy Setup. Twórcy MCC uznali, że najbardziej potrzebne jest szybkie i proste skonfigurowanie taktowania mikrokontrolera, układu watchdoga i włączenie lub wyłączenie układu programowania niskonapięciowego. Po wybraniu zakładki Registers można dowolnie zaprogramować również pozostałe bity konfiguracyjne zależnie od potrzeb. Trzeba tu się posiłkować jednak dokumentacją techniczna mikrokontrolera, bo nie zawsze domyślne ustawienia wtyczki MCC będą dla nas odpowiednie.

Po kliknięciu na Generate w oknie Project Resources wtyczka na podstawie wybranych ustawień wygeneruje odpowiednie definicje fuse bits w pliku źródłowym device_config.crysunek 10.

Rysunek 10. Ustawienia fuse bits w pliku device_config

Od ustawień taktowania zależą definicje rejestrów automatycznie umieszczane przez MCC w funkcji OSCILLATOR_Initialize (plik mcc.c) – rysunek 11.

Rysunek 11. Konfiguracja taktowania

Konfiguracja układów peryferyjnych

Przejdźmy teraz do przykładów konfigurowania układów peryferyjnych i połączonym z tym konfigurowaniem funkcji wyprowadzeń i systemu przerwań. Lista układów peryferyjnych dostępnych dla wybranego mikrokontrolera PIC16F18446 widnieje w oknie Device resourcesrysunek 12.

Rysunek 12. Lista układów peryferyjnych mikrokontrolera PIC16F18446

Przykładowo skonfigurujemy licznik Timer0 zliczający impulsy podawane na wejście T0CKI. Rozwijajmy listę dostępnych liczników/timerów w oknie Device Resources i klikamy na TMR0. Licznik TMR0 przenosi się z okna Device Resources do okna Project Resources i jpojawia się w liście Peripherials – pokazano to na rysunku 13.

Rysunek 13. Wybranie licznika TMR0 do konfiguracji

Okno konfiguracji ma znane już z ustawień System dwie zakładki: Easy Setup i Register.

W zakładce Easy Setup możemy konfigurować:

  • Taktowanie licznika: wartości wpisywane do preskalera, postskalera, długość licznika 8/16 bitów i źródło taktowania. W przypadku zegara zewnętrznego można wpisać jaką częstotliwość podajemy na dedykowane wejście T0CKI i czy włączamy synchronizację zegara zewnętrznego z zegarem taktującym układów peryferyjnych.
  • Włączenie lub wyłączenie zgłaszania przerwania przy przepełnieniu licznika.
  • Ustawienie okresu zliczania w milisekundach.

Na potrzeby testu przyjmijmy, że licznik będzie taktowany zewnętrznym sygnałem zegarowym o częstotliwości 100 kHz podawanym na wejście T0CKI i będzie zgłaszał przerwanie co jedną milisekundę. Funkcja callback będzie wywoływana w procedurze obsługi przerwania co 1 sekundę. Na rysunku 14 pokazano zakładkę Easy Setup z ustawieniami.

Rysunek 14. Konfiguracja TMR0 w zakładce Easy Setup

Odblokowanie przerwań

Ponieważ zaznaczyliśmy Enable Timer Interrupt, to w elemencie Interrupt Module okna Project Resource automatycznie na liście pojawia się odblokowane przerwanie od licznika TMR0 – rysunek 15.

Rysunek 15. Okno Interrupt Module z aktywnym przerwaniem od modułu TMR0

Przy okazji MCC przypomina w oknie Interrupt Module o konieczności ręcznego odblokowania globalnego systemu przerwań i zbiorczego systemu przerwań od układów peryferyjnych. Te przerwania nie są odblokowywane automatycznie przez kod generowany przez MCC, ale odpowiednie makra są umieszczane w pliku main.c. Na koniec konfiguracji TMR0 musimy się jeszcze zająć wejściem T0CKI. Moduł peryferyjny przypisujący funkcje alternatywne układów peryferyjnych pozwala na przypisane funkcji wejścia zliczanych impulsów licznika TMR0 do różnych wyprowadzeń naszego mikrokontrolera. Można to zrobić na dwa sposoby: w oknie Pin ManagerPackage View, a także Pin ManagerGrid View.

Konfiguracja pinoutu mikrokontrolera

Okno Package View pozwala przypisać funkcję alternatywną przez klikniecie prawym klawiszem myszy na wyprowadzeniu wyświetlanej obudowy mikrokontrolera i wybraniu z listy funkcji alternatywnej tak, jak to pokazano na rysunku 16. W tym przypadku zmieniamy przypisanie T0CKI z wyprowadzenia RA2 na RC2. Po zmianie definicji wyprowadzanie zostanie oznaczone na zielono z opisem RC2|T0CKI.

Rysunek 16. Definicja przypisania wyprowadzenia RC2 do funkcji wejścia T0CKI

Okno Package View pozwala konstruktorowi na wygodne definiowanie funkcji wyprowadzeń w widoku obudowy. Pomaga to na przykład w projektowaniu płytki PCB. Drugie okno, Grid View (rysunek 17) pokazuje, jakie są możliwości przypisania funkcji alternatywnych do linii portów. Nie każdą funkcję można przypisać do dowolnej linii. Poza tym widać tu, które linie są już zajęte. Przypisanie realizuje się przez klikniecie na symbol otwartej kłódki na niebieskim tle na przecięciu funkcji alternatywnej (wiersz) z linią portu (kolumna). Oznaczone jest symbolem zamkniętej kłódki na zielonym tle, a pozostałe symbole w wierszu funkcji alternatywnej przebarwiają się na żółto i są blokowane.

Rysunek 17. Okno Grid View

Gdybyśmy próbowali zaznaczyć w kolumnie linii RC2 drugą funkcję, na przykład linii GPIO Out, to MCC zgłosi błąd z oknie Notifications [MCC] i zaznaczy to odpowiednimi symbolami w oknie Grid View na przecięciach kolumn funkcji T0CKI i GPIO Out. MCC wygeneruje kod źródłowy, ale będzie zgłaszał ostrzeżenia i funkcja alternatywna nie będzie działać.

W oknie Grid View można wybrać obudowę mikrokontrolera w okienku Package. Jest to o tyle ważne, że różne obudowy mają inaczej rozmieszczone wyprowadzenia. Wszelkie ustawienia w oknach Pakage View i Grid View są wzajemnie uaktualniane.

O autorze