Forum: Mikrocontroller und Digitale Elektronik Preprozessor


von Uwe M. (lifthrasil)


Lesenswert?

Hi @all,

warum funktioniert folgender Code nicht?

funktioniert nicht:
/*
#define HAL_PortInit(byPort, byValue)                 \
   #if (byPort == P0)                                 \
      DDRB = byValue;                                 \
   #else if (byPort == P1)                            \
      DDRC = byValue;                                 \
   #else if (byPort == P2)                            \
      DDRD = byValue;                                 \
   #else                                              \
      #message ("HAL_PortInit: unknown Port")         \
  #endif

*/

funktioniert:

#define HAL_PortInit(byPort, byValue)                 \
   if(byPort==P0) DDRB = byValue;                     \
   else if(byPort==P1) DDRC = byValue;                \
   else if(byPort==P2) DDRD = byValue;                \
   else HAL_ByteSend(USART, 'E');

hat mir dazu jemand ne erklärung?? Vor allem find ich die erste
Variante auch schöner!

Gruß Uwe

von Frank E. (erdi-soft)


Lesenswert?

Mir ist ja schonmal nicht ganz klar, warum du den Präprozessor benutzt,
um ne Funktion anzulegen...

Du schreibst ne Funktion, die dir vom Application Layer aus erlaubt,
auf die Hardware zuzugreifen. Dazu brauchst du auch Funktionen, die
aufrufbar sind. Der Präprozessor greift vor dem Compilieren und ihm ist
nicht bekannt, welche Werte du übergibst...

Vielleicht solltest du mal nach nem Style Guide programmieren, dann
würde dir die 2. Variante auch eher "gefallen":

if(bla = bla)
   {
   mache dies;
   }
else if .....

von Frank E. (erdi-soft)


Lesenswert?

hmmm, sorry, sollte if(bla == bla) heißen

von Daniel Fischer (Gast)


Lesenswert?

Noch besser:

switch(byPort)
   {
   case P0:
        DDRB = byValue;
        break;
    case P1:
        DDRC = byValue;
        break;
    case P2:
        DDRD = byValue;
        break;
    default:
        message ("HAL_PortInit: unknown Port")
        break;
    }

Und was ist damit gemeint???
#define HAL_PortInit(byPort, byValue)

von Uwe M. (lifthrasil)


Lesenswert?

Hi Frank und Daniel,

ich weiß das es kein besonders guter Stil ist nicht direkt eine
Funktion zu schreiben, aber dadurch das ich den Preprozessor
"mißbrauche" bekomme ich den minimalen Code wenn ich
HAL_PortInit(P0,0xFF) aufrufe. Der Preprozessor minimiert dann meinen
Code zu

13:          HAL_PortInit(P1,0xFD);
+00000045:   EFAD        LDI     R26,0xFD         Load immediate
+00000046:   B9A7        OUT     0x07,R26         Out to I/O location

mit einer Funktion würde er nen call machen und die switch bzw. if
Anweiungen einfügen, usw. Für die einfache Initialisierung des Ports
schreib ich dann einfach direkt DDRB = 0xFF. Allerdings wollte ich
genau das verhindern ... Hardwareabhängiger Code in der main! Darum die
HAL (Hardware abstraktion Layer) ... oder ist das nur Wunschdenken? Die
2. Variante funktioniert ja?!?

Gruß Uwe

von peter dannegger (Gast)


Lesenswert?

Wie wärs denn damit:
1
#define P0 DDRB
2
#define P1 DDRC
3
#define P2 DDRD
4
#define HAL_PortInit(x,y) x = y
5
...
6
HAL_PortInit(P1,0xFD);


Peter

von Frank E. (erdi-soft)


Lesenswert?

Deine 2. Variante funktioniert deshalb, weil dein #define nicht
HAL-PortInit() definiert, sondern irgendwas anderes macht.

So, wie du es geschrieben hast, ist es eine Funktion mit dem
Rückgabewert void.

Nochmal: Die HAL stellt Funktionen zur Verfügung, die vom Application
Layer benutzt werden können, um die Hardware anzusprechen. Allerdings
wird die HAL vorher compiliert und dann erst als Bibliothek zu deinem
Application Layer dazugelinkt. Somit kommen Präprozessoranweisungen vom
AL schon gar nicht zur HAL.

Wenn du also wirklich ne Trennung machen willst, dann vergiss das mit
dem Präprozessor und dem kleinsten Code...

Schreib ne HAL, die alle Hardwarefunktionen zur Verfügung stellt. Und
schreib sie so, als würde der HAL-Entwickler den AL-Entwickler nicht
kennen. Der AL-Entwickler bekommt vom HAL-Entwickler nur die
HAL-Bibliothek, die er dann zu seiner Application dazulinkt, ebenso wie
ne Header, in der alle Funktionsprototypen der HAL (und was man sonst
noch so braucht) deklariert sind. Und ne Dokumentation, wie welche
Funktion anzuwenden ist. ;)

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.