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/
• • •
Programatory
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.
/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
#define F_CPU 16000000UL #include int main(void) { DDRA = 0xFF; PORTA = 0x05; while (1) {
Reset: ldi R16, 0xff out DDRA, R16 Petla: ldi R16, 0b10101010 out PORTA, R16 rjmp Petla
} }
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