Dołączył(a): 01 sty 2013 Posty: 328 Lokalizacja: Rzgów k. Łodzi
Pomógł: 11
Siemka, jako że ostatnio kupiłem sobie płytkę uruchomieniową z procesorem XMega, chciałbym rozpocząć cykl poradników dotyczący tych fajnych mikrokontolerków. Na płytce którą posiadam jest zamontowana ATXMega 128A3U która w porównaniu do modeli bez literki „U” na końcu posiada sprzętowe USB W tej części chciałbym poruszyć kwestie związane z skonfigurowaniem naszego ulubionego środowiska jakim jest Eclipse, wgrania do niego nowszej wersji AVRDude (6.1 mianowicie), które jest wymagane do programowania tego procesora. Starsza wersja też wspiera Xmegi, ale jest ich znacznie mniej w porównaniu do nowej wersji, co zresztą nie dziwi . Warto również wspomnieć, że stary plugin w Eclipse nie wspiera nowszej wersji AVRDude i należy wgrać nowszą jego wersję, ale o tym później Na razie przejdźmy do omówienia nowości wprowadzonych w XMegach
Na pewno należy wspomnieć o sporej liczbie nowych peryferii, które są zaczerpnięte z ARM. Są to między innymi DMA, EventSystem, RTC, DAC, etc. No i oczywiście jest ich dużo więcej w porównaniu do Atmeg. W ATXMegach normalnością są 4 moduły SPI, 4 UARTy czy 8 interfejsów TWI (I2C). Należy również wspomnieć, że odświeżeniu uległy rejestry, które są teraz ładnie uporządkowane w strukturach, które są identyczne dla peryferii. Od teraz nie ma żadnej różnicy, czy konfigurujesz SPI na porcie C (SPIC), czy SPI na porcie E (SPIE). Inżynierowie Atmela mieli na uwadze łatwość przenoszenia kodu między ATXMegami, no i najwyraźniej im się to w pewnym stopniu udało
No i kolejną zmianą w XMegach jest zmiana interfejsu programowania. Od teraz nie zaprogramujemy ich starymi programatorami z SPI, trzeba mieć programator z możliwością programowania PDI (przykładowo MkII, którego posiadam i polecam). W przypadku Xmeg z hardware`owym interfejsem USB jest możliwość programowania ich przez Bootloader za pomocą Atmelowego FLIPa, jednak nie konieczne jest to najwygodniejsze i najszybsze rozwiązanie
Warto wspomnieć, że w ATXMegach nie uświadczymy zmiany taktowania przez fusebity Wszystko dzieje się programowo, więc odpada problem ewentualnej blokady procesora.
Jest jeszcze wiele innych smaczków, ale o nich będzie mowa w dalszej części cyklu
PRZYGOTOWANIE ŚRODOWISKA
Wgranie nowego pluginu AVR w Eclipse Nie będę tutaj opisywał instalacji całego Eclipse tylko szybko opiszę co i jak z „wymianą” starego pluginu na nowy. Przypomnę tylko, że wymagane jest Eclipse z nowym toolchainem
Aby można było wygodnie programować Xmegi z poziomu Eclipse, należy zaktualizować plugin integrujący AVRDude i Eclispe. Aby to zrobić należy wejść w About Eclipse i odinstalować stary plugin. Tutaj przedstawiawiam na screenach jak to zrobić
Dalej nie będę przedstawiał, bo ja już mam to za sobą . Eclipse powinien się ponownie uruchomić, teraz należy zainstalować nową wersję pluginu AVR
Dalej nie pokazuję, z wyżej wymienionego powodu. Eclipse powinien kolejny raz się ponownie uruchomić
Zmiana AVRDude na nową wersję Tutaj należy wymienić wersję AVRDude na nową, domyślnie w z toolchainem jest instalowana wersja 5.10 albo 5.11, która nie wspiera wielu nowych ATXMeg, w tym mojej, na której będzie bazował poradnik Wspomnę tylko jeszcze, że AVRDude jest kompilowane przeze mnie, bo domyślnie wersja 6.11 nie wspiera mojego programatora MkII i nawet odczytanie sygnatury nie było możliwe. W tym miejscu chciałbym podziękować użytkownikom Lemurek, Foreste i SunRiver oczywiście , którzy bardzo pomogli mi w kompilacji mojego AVRDude Tutaj link do pobrania :
Teraz wchodzimy w miejsce, gdzie mamy zainstalowany nowy toolchain. Domyślnie jest to C:\ProgramFiles (x86)\Atmel\AVR Tools\AVR Toolchain\bin I należy tam wgrać (zamienić) 3 pliki z paczki, mianowicie : avrdude.exe avrdude.conf pthreadGC2.dll
Pozostaje jeszcze tylko przestawić ścieżki w pluginie AVR w Eclipse na poprawne
Należy zmienić tylko 4 pierwsze ścieżki, Atmel Part Description Files może pozostać niezmieniony W moim przypadku wygląda to tak :
No i w zasadzie przygotowanie środowiska mamy już za sobą, więc pozostaje tylko sprawdzić działanie kompilatora. W takim razie tworzymy nowy projekt W zasadzie nie ma tu żadnej filozofii, ale na wszelki wypadek dam screeny jak należy to zrobić
Tutaj TRZEBA odznaczyć Debug
Przed jakąkolwiek kompilacją należy wejść w ustawienia projektu
Teraz musimy zmienić programator i procesor na który zostanie skompilowany program, klikamy Apply :
Przechodzimy do zakładki Target Hardware, klikamy Load From MCU i jeżeli wszystko jest ok, procek powinien sam się wczytać
Po poprawnym wczytaniu pozostanie nam ustawienie odpowiedniej częstotliwości i to by było na tyle Klikamy OK
Tworzymy nowy plik main.c, wrzucamy prosty program :
Dołączył(a): 01 sty 2013 Posty: 328 Lokalizacja: Rzgów k. Łodzi
Pomógł: 11
Porty I/O Pierwsza, a w zasadzie druga część tego poradnika będzie dotyczyć portów IO Xmegi. Czyli krótko o tym jak ustawić kierunki, stan i odczytać stan który jest na porcie.
Porty IO w Xmegach są trochę ulepszone w porównaniu do jej strarszej siostry. Mam tu na myśli dodanie rezystora PullDown, którego nie uświadczymy w Atmegach. Kolejnym usprawnieniem jest multiplekser, który pozwala generować przerwania z dowolnego pinu, ustawionego wcześniej w programie. Każdy port posiada dwa „kanały” przerwań pod które można podpiąć jeden pin z portu, które mogą reagować na cztery rózne zbocza. Uogólniając, możemy sobie wybrać dwa dowolne piny z portu, które mogą generować osobne przerwania, ale ten temat poruszymy w części o przerwaniach . Jest jeszcze wiele innych ciekawych funkcji portów, ale na razie zostawię ten temat na później .
Przejdźmy więc do omówienia sposobu zapisywania danych do struktury. Mamy sobie klika struktur (jedna dla każdego portu), które opisują porty. Struktura wygląda następująco :
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Może na pierwszy rzut oka struktura wygląda na strasznie zaawansowaną, jednak do podstawowych operacji na portach I/O będziemy używać dosłownie kilku zmiennych, ale o tym zaraz.
Zmienna DIR odpowiada za kierunek na pinie, czyli bit ustawiony to wyjście, bit wyzerowany to wejście.
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Taką instrukcją ustawiliśmy PA0 jako wyjście. Prawda, że proste i przejrzyste ? Może zastanawiać zapis PIN0_bm, ale to tylko definicja, która zostanie rozwinięta przez kompilator do (1<<0). Do każdego portu są dwie podobne definicje, jedna z końcówką _bm (Bit Mask) a druga z końcówką _bp (Bit Position). W czym różnica ? W tym, że ta druga definicja to tylko numer pinu, czyli w przypadku PIN0_bp zostanie to rozwinięte przez kompilator do postaci 0. Oczywiście taka definicja może się przydać do ustawienia czy wyzerowania pinu, ale sposób będzie się trochę różnił. W przypadku końcówki _bp będziemy robić to tak :
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Czyli po prostu jak w Atmegach. W Xmegach występuje jeszcze jedna końcówka, mianowicie _gc (Group Configuration), która odpowiada za konfigurację wielu bitów na raz. Dobrym przykładem może tutaj być konfiguracja rezystorów pullup i pulldown, które zapobiegają stanom nieustalonym przy konfiguracji pinu jako wejście, ale o tym za chwilkę
Przejdźmy teraz do omówienia kolejnych rejestrów odpowiedzialnych za piny I/O
Następnymi trzema zmiennymi są zmienne DIRSET, DIRCLR i DIRTGL. Poruszam ich kwestię w jednym akapicie, gdyż niejako są one ze sobą powiązane Mianowicie, pierwsza zmienna odpowiada za ustawienie bitów które, się w niej znajdują na jedynki w rejestrze DIR, a druga analogicznie odpowiada za wyzerowanie bitów w rejestrze DIR. Trzecia zmienna odpowiada za zmianę bitu na przeciwny. Czyli jak będzie 1, to po zmianie będzie 0 i analogicznie w drugą stronę, jak będzie 0 to po zmianie będzie 1. Jak wygląda to w praktyce ? A tak :
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Prawda, że proste ?
Następnym rejestrem jest OUT. Czyli po prostu to, co znajduje się fizycznie na porcie (oczywiście po uprzednim ustawieniu go jako wyjście )Rejestr ten również posiada 3 swoje „pochodne” rejestry do czyszczenia, ustawienia i zmiany stanu bitu. Są to OUTCLR, OUTSET, OUTTGL. Tutaj już nie będę poruszał kwestii tego, jak zapisywać dane do tych rejestrów, bo to zostało już opisane w akapicie o rejestrze kierunku
Przejdźmy teraz do rejestru IN. Znajduje się tam to, co również jest fizycznie na porcie, ale jeżeli ustawimy go wcześniej jako wejście Tutaj poruszymy kwestię tego, jak włączać rezystory podciągające do zasilania (pull-up) i do masy (pull-down), i kwestie ośmiu rejestrów, w których to będziemy odpowiednimi bitami włączać wyżej wymienione rezystory i nie tylko . Rejestr ten nie posiada trzech „pochodnych” rejestrów (logiczne ). Przejdźmy do tego, jak włączać te rezystory.
Poniższy kod przedstawia włączenie rezystora pullup na pinie 0
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
I to by było na tyle. Warto przypomnieć o trzeciej końcówce _gc, która tutaj znalazła zastosowanie. O tym dlaczego, po co i czemu odsyłam do datasheeta .
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Jest jeszcze jedna możliwość, czyli bez włączania rezystorów podciągających, ale pod pin musi być coś podłączone aby zapobiegać stanom nieustalonym, przez które pin i kod może wariować
Na dzisiaj koniec, w następnej części będzie o timerach
Wszystkie uwagi i komentarze proszę pisać w tym temacie.
_________________ sig off ;(
Ostatnio edytowano 20 lip 2014, o 00:38 przez PawelGaj, łącznie edytowano 2 razy
Dołączył(a): 01 sty 2013 Posty: 328 Lokalizacja: Rzgów k. Łodzi
Pomógł: 11
Siemka, dzisiaj zajmiemy się timerami i przerwaniami. Na początku myślałem, że opiszę tylko timery, jednak timery są niejako powiązane z przewianiami i zdecydowałem, że lepiej będzie jak z konieczności trochę wtrącę w tej części przerwań;) Dodam tylko, że wszystkie próby z timerami nie będę przedstawiał na HD44780 czy na terminalu, tylko przystępnie na GLCD ILI9341 2,2”
Teraz może pokrótce omówię co oferują timery w nowych procesorach. Warto wspomnieć, że w porównaniu do Atmeg, wszystkie timery w Xmegach są 16bitowe i mają te same rejestry konfiguracyjne – ukłon w stronę osób, które pracują na kilku wersjach procesorów z tej samej rodziny, ale o tym było we wstępie Timery można połączyć z systemem zdarzeń, przez co można połączyć 4 timery 16bitowe w jeden, 64bitowy, albo podzielić jeden timer 16bitowy na dwa timery 8bitowe, ale o tym będzie w późniejszej części cyklu. Dzięki temu możliwe jest uzyskanie 14, niezależnych timerów 8bitowych (A3U). Timery posiadają dodatki, które pozwalają rozszerzyć rozdzielczość PWM. Oferują możliwość współpracy z DMA. Timery te mają kilka rejestrów, które odpowiadają za jego pracę. Najważniejsze z nich opiszę poniżej :
CNT – zmienna przechowująca aktualną wartość timera.
CCx – rejestr do funkcji Capture/Compare (przechwycenia i porównania).
- Porównanie między innymi wykorzystuje się do generowania PWM. Rejestr CNT jest cały czas porównywany z rejestrem CCx i jeżeli nastąpi zrównanie, następuje zmiana stanu logicznego na pinie OCx zgodnie z ustawieniami timera, więcej o tym będzie w podrozdziale o PWM .
- Przechwycenie z kolei działa odwrotnie, po zmianie stanu na pinie OCx następuje przepisanie wartości CNT do rejestru CCx pod warunkiem wystąpienia określonego zbocza. Czyli upraszczając, jeżeli w rejestrze CNT jest wartość 15000 i w tym momencie nastapi „określone zbocze”, wartość ta zostanie skopiowana do rejestru CCx. Zostanie to dokładniej omówione w podrozdziale o przechwytywaniu.
PER – rejestr, w którym przechowana jest maksymalna wartość którą timer może osiągnąć. Przykładowo, jeżeli PER = 1000, przepełnienie timera nastąpi co 1001 cykli. W momencie kiedy w rejestrze konfiguracyjnym zmieniony jest kierunek liczenia, zmienna ta określa od jakiej wartości timer będzie liczył do zera.
CTRLx – rejestry konfiguracyjne.
INTCTRL – rejestry konfigurujące przerwania.
1. Praca normalna z przerwaniami
W tym podrozdziale omówimy sobie jak skonfigurować timer, żeby przykładowo zwracał przerwanie co 1s. Program wykorzystany do obliczenia wartości porównania timera to „rodzimy” MkAVRCalculator Tak więc do celu. Zerknijmy więc do noty jak mamy skonfigurować timer do normalnej pracy, jak skonfigurować przerwanie, a na końcu będzie filmik przedstawiający pracę kodu
Jak widać z powyższej tabelki, musimy ustawić timer w tryb NORMAL. Proszę zwrócić uwagę na nazwę kolumny, mianowicie Group Configuration. Kojarzycie ? Tak, to to, o czym wspominałem w poprzedniej części poradnika Więc na podstawie tabeli skonfigurujmy timer w programie
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
I to wszystko, pozostaje jeszcze ustawić preskaler, ale żeby to zrobić, musimy wyliczyć wartość timera i preskaler. A zrobimy to za pomocą MkAVRCalculator W tym momencie również dodam, że wszystkie ATXMegi po uruchomieniu są taktowane z wewnętrznego oscylatora 2MHz, więc na taką też częstotliwość będziemy wyliczać timer i preskaler.
Jak widać z powyższego zrzutu, żeby uzyskać w „bezbłędne” 1000ms, musimy ustawić preskaler na 64, a do rejestru PER musimy wpisać wartość 31249. Nie zapominajmy, że mamy rejestry 16 bitowe, więc wartość taka nie jest żadnym problemem
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Teraz zrobimy mały przerywnik związany z koniecznością skonfigurowania przerwania Aby przerwanie mogło się prawidłowo odbyć, musimy zrobić 3 kroki
1.Ustawić w rejestrze INTCTRLA bit odpowiadający za przerwanie i jego piorytet. Aby to zrobić, musimy znaleźć rejestr, który jest odpowiedzialny za przerwanie od przepełnienia. Znajduje się on tu :
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
2.Musimy zezwolić na przerwania wybranego poziomu, włączyć kontroler przerwań i zezwolić na globalne przerwania (funkcja sei). Przykładowo, jeżeli wybierzemy poziom przerwań od timera LO, czyli najniższy, musimy odblokować przerwania z piorytetu LO. Jeżeli wybierzemy MED, czyli średni, musimy analogicznie odblokować przerwania MED. Jaka jest różnica między nimi ? Przerwanie wysokiego piorytetu nie może przerwać żadne inne przerwanie (no, jest jeden wyjątek, ale o tym dokładniej opowiem w części o przerwaniach), przerwanie MED może zostać przerwane przez przerwanie o priorytecie HI, a przerwanie LO może zostać przerwane przez przerwania o priorytecie HI oraz MED. My dla naszego timera wybierzemy przerwanie średniego piorytetu
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Efekt jest taki, że kwadrat na wyświetlaczu co sekundę zmienia swój kolor z zielonego na czerwony i z czerwonego na zielony. Tutaj filmik przedstawiający zachowanie tego kodu
I to na dzisiaj tyle, w najbliższym czasie opiszę PWM z przechwytywanie i porówaniem
Wszystkie uwagi i komentarze proszę pisać w tym temacie.
_________________ sig off ;(
Ostatnio edytowano 20 lip 2014, o 00:38 przez PawelGaj, łącznie edytowano 2 razy
Dołączył(a): 01 sty 2013 Posty: 328 Lokalizacja: Rzgów k. Łodzi
Pomógł: 11
Siemka, na początku chciałem przeprosić za to, że ostatnio nie pojawiła się żadna część kursu, ale są wakacje i mam sporo roboty typowo fizycznej, a po pracy nie mam zbytnio chęci na jakiekolwiek myślenie. Wraz z końcem mojej pracy (jakoś przed końcem wakacji), powinny zacząć się pojawiać kolejne części kursu Dzięki za zrozumienie
Świetnie, czekam na więcej ! Mogłeś powiedzieć więcej o uC z usb bo do nich nie potrzeba dodatkowego programatora Albo mogłeś wspomnieć o przeróbce usbasp na programator PDI
Dołączył(a): 01 sty 2013 Posty: 328 Lokalizacja: Rzgów k. Łodzi
Pomógł: 11
Witam po długiej przerwie. Niestety z tymczasowych powodów prywatnych nie jestem w stanie dalej prowadzić tego "kursu". Może ktoś to dalej pociągnie, mi pozostaje tylko przeprosić.
Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 0 gości
Nie możesz rozpoczynać nowych wątków Nie możesz odpowiadać w wątkach Nie możesz edytować swoich postów Nie możesz usuwać swoich postów Nie możesz dodawać załączników