Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATxmega128A3][avr-gcc] - Makrodefinicje I/O w Xmega

hass-pol 09 Wrz 2012 12:49 1776 5
  • #1 09 Wrz 2012 12:49
    hass-pol
    Poziom 9  

    Moderowany przez LordBlick:

    Tytuł poprawiono.
    Proszę pamiętać o zasadach korzystania z działu:
    https://www.elektroda.pl/rtvforum/topic349089.html
    Na prośbę kolegi tmf temat przywracam(ale do działu dla początkujących), tym niemniej proszę zachować staranność w przestrzeganiu zasad tu panujących.


    Witam,

    Nie wiem czy mała popularność uC serii xmega wynika z ich trudniejszego programowania, czy ze znacznie mniejszej ilości tutoriali dostępnych w sieci? Ale po paru dniach testowania, rozumiem że może człowiek szybko się zniechęcić.

    Chciałem je przetestować. Wybór padł na ATxmega128A3 bo: zależy mi na 12bit ADC, 32MHz.

    Mam problem z najprostszą rzeczą jaką są macro definicje.

    Normalnie w serii mega robiłem to w ten sposób (oczywiście w odpowiednich miejscach)

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Natomiast przy xmedze próbowałem najróżniejszych rzeczy i nic. Np.: (sory za bajzel w kodzie, ale pokazuje jakie min. kombinacje robiłem)
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Proszę o pomoc w zdefiniowaniu LED_xx

    0 5
  • Pomocny post
    #2 09 Wrz 2012 13:44
    tmf
    Moderator Mikrokontrolery Projektowanie

    Można np. tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Przy czym w tym przypadku dlaczego po prostu nie wykorzystać funkcji języka C? Akurat w podanym przykładzie preprocesor niczemu nie służy.

    0
  • #3 09 Wrz 2012 15:24
    hass-pol
    Poziom 9  

    No popatrz... działa :)
    Bardzo dziękuję za pomoc.

    Korzystając z otwartego tematu o Xmedze. Kiedy piszemy np:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    W obu przypadkach efekt końcowy jest taki sam...

    Podobnie z
    Kod: c
    Zaloguj się, aby zobaczyć kod

    kiedy bm a kiedy bp?

    0
  • Pomocny post
    #5 09 Wrz 2012 21:29
    tmf
    Moderator Mikrokontrolery Projektowanie

    Dziękuję koledze LordBlick, poprosiłem go o odblokowanie tematu, bo wydaje mi się, że mimo pozornej prostoty problemu warto się nad nim chwilę zastanowić. Zanim przejdę do odpowiedzi na post #3, powiem dwa słowa o makrodefinicjach. Wiele osób z nich chętnie korzysta, w pokazanym wyżej przykładzie zdecydowanie lepiej posługiwać się makrami LED_ON i LED_OFF niż patrzeć na „goły” kod. Ale IMHO jeszcze lepiej wykorzystać wspomniane funkcje. Wtedy zamiast makra mamy zwykłą funkcję:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Co nam to daje? Przede wszystkim mamy zwykłą funkcję, która wywołana w kodzie będzie się stosować do wszystkich reguł języka C, a kod wynikowy będzie identyczny jak w przypadku stosowania makr. IMHO jeśli preprocesor nie jest niezbędny to lepiej z niego nie korzystać.
    Teraz kwestia zapisu PORTE_DIR=, czy PORTE.DIR=? Oba zapisy robią dokładnie to samo, zapisują nową wartość do rejestru DIR portu E. Dla kompilatora jest jednak różnica. Zapis PORTE_DIR to znane nam z innych AVRów makro, rozwijane do zapisu typu (volatile uint8_t*)(addr)=, powodujące zapis wartości pod wskazany adres IO. Zwykle kompilator tłumaczy to na jedną instrukcję ST(adres),rejestr. Sprawa prosta. Druga postać to zapis, ale z wykorzystaniem struktury o typie PORT_t, gdzie DIR to tylko jedno z kilku pól tej struktury. Wykorzystanie struktur wiąże się z adresowaniem pośrednim, gdzie mamy adres bazowy trzymany w rejestrze indeksowym, a pola struktury adresuje się jako przemieszczenie (offset) w stosunku do adresu bazowego. Zwykle jest to tłumaczone na instrukcję ST (Z+x), rejestr, co jest efektywne, ale wymaga wcześniejszego załadowania rejestru Z adresem struktury (kolejne dwie instrukcje). W efekcie nie zawsze warto ze struktur korzystać, chociaż optymalizator gcc odwala kawał dobrej roboty i trywialne odwołania do pól struktury czasami potrafi zamienić na pojedyncze instrukcje, w efekcie oba zapisy są równoważne. Jeśli adresujemy kilka pól tej samej struktury to przewaga struktury nad adresami IO staje się co raz bardziej oczywista. Struktury też można wygodnie przesyłać jako argumenty funkcji, co jest kłopotem w przypadku gołych rejestrów.
    Na koniec kwestia bp, bm, gm itd. Generalnie literka p to position (pozycja), m to mask (maska), b to bit, a g to grupa (pole bitowe). W efekcie wszystkie definicje kończące się na _bp określają pozycję bitu, np. PIN6_bp to liczbowo 6 – pozycja bitu wynosi 6. Taką pozycję można zamienić na maskę bitową, przy pomocy znanego z innych AVR przesunięcia bitowego (1<<PIN6_bp), lub od razu skorzystać z gotowej maski PIN6_bm. Podobne zasady dotyczą pól bitowych (grup). Wygląda to trochę inaczej niż dla innych AVR, ale w efekcie zapis jest przejrzysty i trudniej o błąd (przypuszczam, że każdemu zdarzyło się zrobić zamiast 1<<cośtam, 1<cośtam).

    0
  • #6 10 Wrz 2012 16:31
    hass-pol
    Poziom 9  

    Dziękuję koledze za interwencję :) Powinienem założyć temat w dziale dla początkujących.

    Wracając do tematu, rzecz w tym że zmieniam biblioteki z megi na xmegę i muszę pozmieniać macra pinów wyświetlacza i nie wiem czy mógłbym zastosować funkcję static inline void LED_on().
    Dzięki wcześniejszej pomocy udało mi się zmienić poprawnie bibliotekę.
    Pozdrawiam i dziękuję za pomoc.

    0