Systemy wbudowane Mikrokontrolery AVR Wprowadzenie do programowania w C dr inż. Maciej Piechowiak Wprowadzenie język C jest językiem strukturalnym wysokiego poziomu, jednak działającym blisko sprzętu i generującym kod zbliżony do kodu tworzonego w asemblerze, optymalizacja kodu pozwala na uzyskanie zwartego kodu wynikowego, można dopisywać krytyczne fragmenty kodu w czystym asemblerze, przenośność kodu (funkcje nie związane ze sprzętem, np.: algorytmy, funkcje konwertujące), szeroka dostępność bibliotek, popularnych kodów itp., darmowe narzędzia deweloperskie (avr-gcc), wersje kompilatora (porty) na różne mikrokontrolery. Struktura /bin zestaw bezpośrednio używanych programów narzędziowych avr-gcc i avr-binutils, /avr/include pliki nagłówkowe (headers) biblioteki avr-libc, glównie pliki z definicjami zasobów poszczególnych mikrokontrolerów, /avr/lib/ldscripts skrypty sterujące pracą linkera, opisują wielkości poszczególnych obszarów pamięci, podział na sekcje, adresy początkowe i końcowe, /lib/gcc/avr/3.4.2/include ogólne pliki nagłówkowe gcc (nie powiązane z mikrokontrolerami), /doc/avr-libc/avr-libc-user-manual pliki pomocy. 1
Kompilacja preprocesor realizuje zmiany w kodzie określone przez dyrektywy: dodatkowe pliki z dyrektyw #include, definicje i makroinstrukcje z #define, dyrektywy kompilacji warunkowej #if, #else, #endif, kompilacja z przeprowadzeniem optymalizacji (automatyczne uproszczenie i skrócenie kodu) wynik: instrukcje asemblera (.s), asemblacja (przetworzenie na kod maszynowy) pliki relokowalne (.o), adresy zmiennych i funkcji nie są jeszcze ustalone, Kompilacja linkowanie i konsolidacja (ulokowanie fragmentów kodu w obszarze pamięci programu i wyliczenie adresów), dołączenie funkcji bibliotecznych oraz plików kodu inicjującego dla danego mikrokontrolera, plik obiektowy (.elf) zawiera kod wynikowy, informacje dla debuggera, wykaz symboli, rozmiary sekcji kodu (z informacji tych można korzystać poprzez zbiór narzędzi binutils), W rezultacie tworzone są pliki wykonywalne (obrazy pamięci) Flash (.hex) lub EEPROM (.eep) Środowisko uruchomieniowe Kompilacja programu odbywa się w środowisku AVR Studio. Domyślnie środowisko pozwala na pisanie programu w asemblerze oraz jego symulację. Wcześniejsze zainstalowanie kompilatora avr-gcc (WinAVR) umożliwia kompilowanie kodów źródłowych programów w C poprzez AVR Studio. 2
Środowisko uruchomieniowe Programowanie technologia Flash ISP pozwala na przeprogramowywanie pamięci w systemie poprzez szeregowy interfejs ISP z wykorzystaniem konwencjonalnych programatorów, magistralę JTAG oraz przez program bootujący pracujący w samym układzie, program bootujący może wykorzystywać dowolny rodzaj interfejsu, aby załadować właściwy program do pamięci aplikacji, program z sekcji bootującej kontynuuje swoją pracę podczas programowania części aplikacyjnej, na co pozwala technika Write-While-Read. Programatory /STK500 Microsense/ programator zgodny z AVR STK500v2 na USB, w systemie Windows XP działa w trybie COM, w systemach Windows 7 oraz Windows Vista zarówno 32 i 64 bitowych pracuje w trybie HID. 3
Programatory /STK500 Microsense/ Programatory /STK500 Microsense/ instalacja sterowników (USB AVR ISP II FT STK500v2), przypisanie urządzenia do wolnego portu COM w systemie (Menedżer urządzeń -> Właściwości), Connect -> Zmniejszenie częstotliwości: ISP frequency. Programatory /KamPROG Kamami/ Prosta instalacja oprogramowania wraz z plugin-em do AVRStudio: http://www.kamami.com/dl/kamprogavr_en.pdf 4
Programatory /KamPROG Kamami/ Programowanie /STK 200 LPT/ aplikacja PonyProg2000 jest przeznaczona do programowania układów z pamięcią Flash lub EEPROM, które mogą być programowane szeregowo, obsługuje przy tym różne standardy szeregowej transmisji takie jak magistrala I2C, microwire i SPI, za pomocą aplikacji można zaprogramować większość popularnych mikrokontrolerów jednoukładowych AVR wyposażonych w interfejs SPI (ang. Serial Peripherial Interface), niektóre z mikrokontrolerów ATMEL z serii AT89S, mikrokontrolery PIC serii PIC16X84 oraz pamięci szeregowe EEPROM. Programowanie /STK 200 LPT/ 5
Programowanie /STK 200 LPT/ Porty mikrokontrolera układy peryferyjne mikrokontrolera AVR można dołączać do czterech portów poprzez rejestry we/wy 8-bitowe rejestry we/wy znajdują się w przestrzeni adresowej pamięci danych, możliwe jest zapisywanie do portów/rejestrów we/wy lub odczytywanie z nich podobnie jak z pamięci danych, w zbiorze instrukcji języka maszynowego mikrokontrolera AVR istnieją też specjalne rozkazy służące do odczytu i zapisu zawartości rejestrów we/wy oraz rozkazy do manipulowania pojedynczymi bitami rejestrów, Porty mikrokontrolera z każdym z równoległych portów we/wy: A, B, C i D powiązane są po trzy rejestry I/O, o nazwach: DDRx, PORTx, PINx, (gdzie x oznacza port A, B, C lub D, stan poszczególnych bitów rejestrów DDRx (ang. Port Data Direction Register) decyduje czy odpowiadające im linie są wejściami czy wyjściami (0-wejście, 1-wyjście), jeżeli dana linia we/wy pracuje jako wyjście, wtedy ustawiając na wartość 1 odpowiadający tej linii bit w rejestrze PORTx (ang. Port Data Register) na wyprowadzeniu wymuszany jest stan wysoki, a ustawiając wartość bitu na 0 stan niski, 6
Porty mikrokontrolera jeżeli linia portu została skonfigurowana jako wejście, poziom logiczny na wyprowadzeniu sprawdza się odczytując wartość odpowiadającego tej linii bitu w rejestrze PINx (ang. Port Input Pins Address), dodatkowo, gdy linia jest wejściem i odpowiadający tej linii bit w rejestrze PORTx ma wartość 1, wtedy wyprowadzenie jest wewnętrznie podciągnięte do napięcia zasilania, dla dowolnego pinu jednego z portów konfiguracja przedstawia się następująco: Ustawiając wszystkie linie portu B jako wyjścia należy do rejestru DDRB wpisać wartość 0xff. DDRx.n PORTx.n Px.n 0 0 wejście 0 1 wejście podciągnięte do Vcc 1 0 lub 1 wyjście Asembler vs. C.INCLUDE "m32def.inc".org 0x0000 rjmp Reset Reset: ldi R16, 0xff out DDRA, R16 Petla: ldi R16, 0b10101010 out PORTA, R16 rjmp Petla #define F_CPU 16000000UL #include <avr/io.h> int main(void) { } DDRA = 0xFF; PORTA = 0x05; while (1) { } Porty mikrokontrolera Pętle opóźniające są dobrze skalibrowane tylko przy włączonej optymalizacji: Project -> GCC / WinAVR flags -> Optimization -> Level 2 7
Porty mikrokontrolera DDRB = _BV(7) _BV(6) _BV(5) _BV(4) DDRB = 0xF0 Porty mikrokontrolera 8