Präprozessor verschachteln

Gast #1340897
Lesenswert?
• ▲
▼
Hallo,

ich habe folgendes Problem mit dem AVR GCC Präprozessor:

Um einfacher auf die IO-Pins des ATMega64 zugreifen zu können habe ich 
mir folgende Präprozessordirektive geschrieben:
1
//Ausgänge auf "1" setzen:
2
  //==> output_high(F, 6);
3
#define output_high(Port, Nr)  PORT ##Port |= (1 << Nr)
4
//#define output_high(Port, Nr)  Port |= (1 << Nr)
5

6
//Ausgänge auf "0" setzen:
7
  //==> output_low(F, 2);
8
#define output_low(Port, Nr)  PORT ##Port &= ~(1 << Nr)
9
//#define output_low(Port, Nr)  Port &= ~(1 << Nr)
10

11
// Eingangspin einlesen:
12
  //==> Status = input_Pin(A,2);
13
#define input_Pin(Port, Nr)    PIN ##Port & (1 << Nr)
14

15
// DDR auf Eingang setzen:
16
  //==> easyDDR_in(F, 5); ==> DDRF &= ~(1 << 5);
17
#define easyDDR_in(Port, Nr)  DDR ##Port &= ~(1 << Nr)
18

19
// DDR auf Ausgang setzen:
20
  //==> easyDDR_out(F, 5); ==> DDRF |= (1 << 5);
21
#define easyDDR_out(Port, Nr)  DDR ##Port |= (1 << Nr)
Diese sind in einer Datei ausgelagert und werden im Main-file 
includiert.
Funktioniert auch einwandfrei, mit
1
 output_high(F,6)
wird PortF, Pin6 logisch 1.

Nun möchte aber auch für Ports einen Alias mittels #define festlegen.
Dazu habe ich eine neue .c-Datei angelegt, die ebenfalls in meinem 
Projekt includet wird. Zu Beginn dieser Datei steht
1
#ifndef _ADC121_PORT
2
  #define _ADC121_PORT  F
3
  #warning "_ADC121_PORT not defined, using default port F"
4
#endif

Dann folgt die Funktion
1
void Test
2
    {
3
    easyDDR_out(_ADC121_PORT, 4);

Leider führt dies zu folgender Ausgabe im "Build"-Fenster:
1
D:\AVR\Akkumanagement\..\libraries\Header-Files/ADC121S021.c:56: error: 'DDR_ADC121_PORT' undeclared (first use in this function)

Das "_ADC121_PORT" wird also vom Präprozessor nicht durch das "F" 
ersetzt.
Was mache ich falsch ???

Danke schonmal !!!!!
Persönliche Seite #1340984
Lesenswert?
• ▲
▼
Hinweise was schief get findest zu im i-File, also in der präprozessten 
Quelle.

Das häufigste Missverständnis ist, daß Makros wie Funktionen verwendet 
werden, wobei sie aber nur Textersetz machen. Und da kommt's eben auf 
die Reihenfolge an.

Solche Port-Makros können sehr praktisch sein, aber sie bedeuten auch 
eine Präprozessor- und Makro-Schlammschlacht.

Ich hab mir solche Makros gebastelt als ich mit AVRs anfing. Sie 
funktionieren zwar wie gewünscht und ich hab's praktisch in all meinen 
Projekten, aber ich weiß nicht ob ich das wieder so machen würde; eben 
wegen den komplexen, schwer durchschaubaren Makros.

Die Portzuweisungen für's jeweilige Projekt sind in ports.h:
1
#include <avr/io.h>
2
#include "avr-port-macros.h"
3
#include "avr-port-enum.h"
4

5
enum
6
{
7
    PORT_POWER    = PORTD_6,
8
    PORT_DREHTAST = PORTB_3, // MOSI
9
    PORT_DREHA    = PORTB_0,
10
    PORT_DREHB    = PORTD_7,
11

12
    PORT_DAC_CS = PORTD_2, // 0=Enable
13
    PORT_DAC_AB = PORTD_3, // 0=A, 1=B
14
    ...

Den Makro-Wahn findest du in avr-port-macros.h und avr-port-enum.h in
   Beitrag "Re: Idee für Optimierung? (Scope-Clock auf Speed)"

Wobei da noch die zusätzliche Komplexität behandelt wird, daß ein Port 
nur virtuell ist, d.h. nicht einem I/O-Pin entspricht sondern eine Pin 
an einem Port-Expander.

Die Makros gehen nicht von einer bestimmten Anordnung der Port-SFRs im 
I/O-Bereich aus.

Johann

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.