definicje w AVRGCC

Dec 24, 2008 12 Replies

Witam Kolegów. Kombinuję coś takiego. Mamy przykładowe definicje:



#define a ALA #define b MA #define c KOTA



Czy da się w wykombinować taką definicję na pod stawie a, b i c aby w wyniku uzyskać ALAMAKOTA ? oczywiście zabawa z podwójnym ## nie daje efektu bo późniejsza definicja w stylu: #define x a##b##c da w wyniku abc



Tak kombinuję, kombinuję, ale powoli dochodzę do wniosku, że "to se ne da"



Pozdrawiam i życzę zdrowych i spokojnych Świąt Bożego Narodzenia Grzegorz


To jest jêzyk C i nie ma tu znaczenia czy AVR gcc czy inny. Musisz siê zdecydowaæ co to jest ALA, MA, KOTA. Czy to s± wcze¶niej zdefiniowane sta³e, makra, czy np ci±gi znaków.

Takie co¶ ju¿ zadzia³a :

#define a "ala " #define b "ma " #define c "kota" #define d a b c

printf(d);

Użytkownik kk napisał:

Oczywiście... z rozpędu w tytule wpisałem gcc

Już piszę o co konkretnie mi chodzi. jest sobie w bibliotekach avrgcc predefiniowane makro:

#define PORTB _SFR_IO8(0x05)

czyli jeśli w programie wpiszemy: PORTB = 10; to zostanie podstawione: _SFR_IO8(0x05) = 10;

Późną nocą podczas podpierania powiek zapałkami ;-) wymarzyło mi się coś takiego aby "skleić" definicje:

#define NAZWA PORT #define SYMBOL B #define NOWYPORT NAZWA<magiczny operator>SYMBOL

i teraz problem czy jest taki <magiczny operator> coby: NOWYPORT = 10; dało w efekcie: _SFR_IO8(0x05) = 10;

Niestety wydaje mi się, że to były tylko senne majaczenia przemęczonego umysłu ;-) ale może...

Pozdrawiam Świątecznie Grzegorz

Grzegorz Kurczyk pisze: > (...)

Chyba wiem co knujesz:). Może nie jest to dokładnie to co byś chciał ale może pomoże:

#define NAZWA(x) (PORT##x) #define NOWYPORT(x) NAZWA(x)

#define SYMBOL C

w kodzie musiałbyś wtedy operować:

NOWYPORT(SYMBOL)=10;

Z pozdrowieniami, MD.

Użytkownik Marcin napisał:

BINGO !!! Kurcze.... uparłem się aby była to elegancka pojedyncza etykieta, ale w sumie tak też może być.

Dzięki serdeczne za pomysł :-)

P.S. Chodzi oczywiście o zmniejszenie upierdliwości definiowania PORT,PIN,DDR dla każdej potrzebnej linii I/O. Kiedyś wykombinowałem definicje w oparciu o adresy SFR, bo w starszych avr-ach były to kolejne adresy, ale w np. ATmega128 nie jest już to regułą dla wszystkich portów.

Pozdrawiam Grzegorz

Użytkownik Grzegorz Kurczyk napisał:

P.S. Choć w sumie można dać następną definicję: #define KUKURYKU NOWYPORT(SYMBOL) i w kodzie: KUKURYKU = 10;

Pozdrawiam i jeszcze raz dzięki za ulgę dla udręczonego umysłu ;-) Grzegorz

No to definicje gotowe. Pewnie komuś się przyda.

#define _SKLEJ_(a,b) a##b #define _PORT_(x) _SKLEJ_(PORT,x) #define _PIN_(x) _SKLEJ_(PIN,x) #define _DDR_(x) _SKLEJ_(DDR,x)

w pliku nagłówkowym modułu wystarczą już tylko dwie definicje opisujące jedną linię I/O

#define LED_PPD C // brama C #define LED_BIT 1 // bit 1

#define KEY_PPD B // brama B #define KEY_BIT 5 // bit 5

w kodzie programu mamy dostęp do rejestrów portu

void led(void) { sbi(_DDR_(LED_PPD), LED_BIT); // ustaw jako wyjście sbi(_PORT_(LED_PPD), LED_BIT); // LED ON cbi(_PORT_(LED_PPD), LED_BIT); // LED OFF

cbi(_DDR_(KEY_PPD), KEY_BIT); // ustaw jako wejście sbi(_PORT_(KEY_PPD), KEY_BIT); // włącz pullup if(_PIN_(KEY_PPD) & (1<<KEY_BIT)) { // sprawdź stan wejścia ... ... } }

Pozdrawiam Świątecznie Grzegorz

Grzegorz Kurczyk pisze:

UWAGA! Makra sbi i cbi są oznaczone w standardowych plikach nagłówkowych najnowszego avr gcc jako "deprecated" czyli wycofane z użycia - nie należy z nich korzystać, bo zostaną w przyszłych wersjach kompilatora biblioteki avr-libc całkowicie usunięte:

formatting link
Według mnie wystarczająco czytelny jest kod w stylu: LED_PORT |= (1 << LED_BIT); LED_PORT &= ~(1 << LED_BIT); o ile oczywiście wcześniej zdefiniuje się LED_PORT, LED_DDR i LED_BIT (można też zrobić LED_MASK zamiast 1<<LED_BIT), może być z wykorzystaniem wcześniej podanych makr _DDR_ i _PORT_.

Użytkownik Adam Dybkowski napisał:

Wiemy, wiemy :-)

Eeee... ;-) Mam juz zbyt silne przyzwyczajenia i jakoś sbi/cbi do banglania bitami lepiej do mnie przemawia. Z tego też powodu pierwsze linijki w mojej bibliotece, którą dołączam do każdego projektu to:

#define sbi(port, bit) port |= (1<<bit) #define cbi(port, bit) port &= ~(1<<bit)

:-)

Ale jak to mówią... to rzecz gustu :-)

można sobie oczywiście dorobić: #define LED_ON LED_PORT |= (1 << LED_BIT) #define LED_OFF LED_PORT &= ~(1 << LED_BIT)

i wtedy to już mamy pełen luz blues cud malina :-)

Pozdrawiam Grzegorz

Grzegorz Kurczyk pisze:

Sugeruję jeszcze dodanie nawiasów okalających port oraz bit. Bo jeżeli na przykład zadeklarujesz LED_BIT jako BUZZER_BIT + 1 - to wynik działania sbi(PORTA,LED_BIT) będzie conajmniej niepokojący.

Tak więc lepiej zrobić coś w tym rodzaju: #define sbi(port, bit) (port) |= (1 << (bit)) #define cbi(port, bit) (port) &= ~(1 << (bit))

A z drugiej strony jednak warto pamiętać o nawiasach także w definicjach "pierwotnych", tzn.: #define BUZZER_BIT 0 #define LED_BIT (BUZZER_BIT + 1)

Oczywiście - to najwygodniejsze rozwiązanie i sam stosuję.

Użytkownik Adam Dybkowski napisał:

Co prawda nigdy nie miałem potrzeby takiej deklaracji z +1 dotyczącej numeru bitu w porcie, więc w tym przypadku nawiasy nie są mi potrzebne, ale ma oczywiście Kolega rację. Sam kiedyś się przejechałem na braku nawiasów w definicji i faktycznie czasem lepiej jest dać ich za dużo niż o jeden za mało :-)

Pozdrawiam Grzegorz

Szczegolnie jesli to jest o *jeden* za malo :)

Użytkownik T.M.F. napisał:

Eeee... no musiał się przyczepić ;-) chodziło mi oczywiście parę nawiasów (otwierający i zamykający). "Jeden" nawias to nie problem bo w czasie kompilacji zaraz to wylezie :) Znacznie bardziej upierdliwe są przypadki, o których pisał Kolega Adam. Kompilacja przebiegła pomyślnie i to nawet bez "warningów", a program robi głupoty...

Pozdrawiam Grzegorz

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required