Forum: Mikrocontroller und Digitale Elektronik AVR GCC Präprozessor #if funktioniert nicht !


von alex (Gast)


Lesenswert?

Hallo Community, ich versuche momentan meine Bibliotheken von AVR.ASM
an AVR GCC anzupassen. Doch leider funtionier die Präprozessoranweisung 
#if
nicht wirklich.

Funktionierender ASM Code:
1
.equ  LCD_Data_Port = PORTA
2
3
.if (LCD_Data_Port == PORTA)
4
  .equ    LCD_Data_DDR  = DDRA
5
.endif

Nicht funktionierende C Portierung:
#define LCD_Data_Port PORTA
1
#if (LCD_Data_Port == PORTA)    
2
#define   LCD_Data_DDR     DDRA        
3
#endif

Nach über 5 Stunden experementieren gebe ich mich geschlagen. Bitte um 
hilfe.

von 12345 (Gast)


Lesenswert?

Den AVR-GCC hab ich gerade nicht parat, aber ich vermute mal der 
Präprozessor ist dem x86-GCC ähnlich und mit letzterem gibt es keine 
Probleme... Erzähl mal genauer was da nicht geht.

von (prx) A. K. (prx)


Lesenswert?

PORTA ist in C ein recht komplizierter Ausdruck in einem Makro und ist 
keine Zahl. #if vergleicht aber numerisch.

von 12345 (Gast)


Lesenswert?

1
#define LCD_PORT A
2
#define LCD_PORT_DATA PORT##LCD_PORT
3
#define LCD_PORT_DDR DDR##LCD_PORT

ungetestet

von Peter D. (peda)


Lesenswert?

.equ Anweisungen werden erst vom Assembler ausgewertet, da ist der 
Präprozessor aber schon durch.
Benutze #define anstatt .equ.


Peter

von (prx) A. K. (prx)


Lesenswert?

1
#define GLUE(a, b)      a##b
2
#define PORT(x)         GLUE(PORT, x)
3
#define PIN(x)          GLUE(PIN, x)
4
#define DDR(x)          GLUE(DDR, x)
5
6
#define LCD_PORT        A
7
#define LCD_PORT_DATA   PORT(LCD_PORT)
8
#define LCD_PORT_DDR    DDR(LCD_PORT)
Getestet.

von 12345 (Gast)


Lesenswert?

A. K. schrieb:
> Getestet.
Danke.
Immerhin war die Idee richtig. :-)

von alex (Gast)


Lesenswert?

@ A. K.
der selben Meinung bin ich auch,
wenn LCD_Data_Port eine Zahl währe und PORTA auch, dann täte es gehen,
quasi so:
1
#define LCD_Data_Port 1
2
#define PORTA 1
3
4
#if (LCD_Data_Port == PORTA)    
5
#define   LCD_Data_DDR     DDRA        
6
#endif
 Das WILL ICH ABER NICHT !

Denn ich möchte dass im LCD Treiber alle weiteren Konfigurationen
automatisch ausgewählt werden.

Quasi SO:
1
#define LCD_Data_Port PORTA  // LCD PORT für Pins (DB4-DB7) festlegen
2
3
#if (LCD_Data_Port == PORTA)    
4
#define   LCD_Data_DDR     DDRA   
5
#define   LCD_Data_Pin      PINA        
6
#endif

von alex (Gast)


Lesenswert?

@ A.K danke für das faszinierende Beispiel, jetzt muss ich es nur noch 
verdauen:-)

von alex (Gast)


Lesenswert?

@A.K
Wow auf so eine geniale Lösung währe ich Lebtag nicht gekommen.
Aber ich hoffe es verstanden zu haben, falls nicht bitte korrigieren.

1) Glue setzt quasi string "a" und "b" lückenlos zusammen.
1
#define GLUE(a, b)      a##b

2) Das Makro "PORT(x)" wird im Code durch  "GLUE(PORT, x)"
Und da der text "PORT",bereits vorhanden ist bleibt nur noch der
Platzhalter "x" übrig.
1
#define PORT(x)         GLUE(PORT, x)

3) An dieser Stelle wird im Code überall wo "LCD_PORT" vorkommt
durch "A" ersetzt.
#define LCD_PORT        A

4) Und im letzten Schritt wird quasi der Platzhalter "x"
durch "LCD_PORT" ersetzt, in unseren Fall durch "A"
1
#define LCD_PORT_DATA   PORT(LCD_PORT)

von (prx) A. K. (prx)


Lesenswert?

alex schrieb:

> Wow auf so eine geniale Lösung währe ich Lebtag nicht gekommen.

Stammt von Jörg, war alles schon mal da:
Beitrag "Re: Preprozessor bedingte Verknüpfung"

Setzt aber voraus, dass der Präprozessor sich regelkonform verhält. Mit 
Microchips C18 Compiler klappt das deshalb weniger gut.

von alex (Gast)


Lesenswert?

Jetzt kann ich happy schlafen gehen :- )
Viele dank an Euch alle.
Wünsche Euch noch einen schönen Abend.
 Gruß Alex

von walder (Gast)


Lesenswert?

Wäre ifdef nicht auch ein Weg gewesen? Bei mehrach vorhandenen defines 
wird mit Fehler abgebrochen und ein fehlendes define könnte man mit 
ifndef abfangen...

von alex (Gast)


Lesenswert?

@ walder
klar #ifndef kann auch sehr nützlich sein.
Ich verwende es bei der definition meiner LCD- Datenleitungen
1
#ifndef    HD44780_DB4
2
#define    HD44780_DB4     4      // Datenleitung
3
#endif
4
5
#ifndef    HD44780_DB5
6
#define    HD44780_DB5  5      // Datenleitung
7
#endif

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.