www.mikrocontroller.net

Forum: Compiler & IDEs Präprozessor verschachteln


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
//Ausgänge auf "1" setzen:
  //==> output_high(F, 6);
#define output_high(Port, Nr)  PORT ##Port |= (1 << Nr)
//#define output_high(Port, Nr)  Port |= (1 << Nr)

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

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

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

// DDR auf Ausgang setzen:
  //==> easyDDR_out(F, 5); ==> DDRF |= (1 << 5);
#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
 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
#ifndef _ADC121_PORT
  #define _ADC121_PORT  F
  #warning "_ADC121_PORT not defined, using default port F"
#endif

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

Leider führt dies zu folgender Ausgabe im "Build"-Fenster:
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 !!!!!

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>
#include "avr-port-macros.h"
#include "avr-port-enum.h"

enum
{
    PORT_POWER    = PORTD_6,
    PORT_DREHTAST = PORTB_3, // MOSI
    PORT_DREHA    = PORTB_0,
    PORT_DREHB    = PORTD_7,

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

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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.