definicje w AVRGCC

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

Reply to
Grzegorz Kurczyk
Loading thread data ...

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

Reply to
Grzegorz Kurczyk

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.

Reply to
Marcin

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

Reply to
Grzegorz Kurczyk

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

Reply to
Grzegorz Kurczyk

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

Reply to
Grzegorz Kurczyk

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_.

Reply to
Adam Dybkowski

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

Reply to
Grzegorz Kurczyk

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ę.

Reply to
Adam Dybkowski

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

Reply to
Grzegorz Kurczyk

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

Reply to
T.M.F.

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

Reply to
Grzegorz Kurczyk

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.