Forum: Compiler & IDEs GCC : NAMEN statt Pinnummern?


von mil (Gast)


Lesenswert?

hallo

ist es irgendwie (mit vernünftigem aufwand) möglich ein gcc für atmel
so zu schreiben dass statt pinnummern eigene labels verwendet werden
können?

zum beispiel statt PORTB |= (1 << 0) dann SetPin(LAMPE, LOW) ?

oder DefinePin(LAMPE, OUTPUT)
und auch ReadPin(TASTER)

was mir unklar ist, wie könnte ich LAMPE definieren dass nur ein pin
referenziert ist? und wie diese funktionen dann effizient auflösen?

ev bin ich ja auch grad völlig auf dem holzpfad... ;-)

vielen dank

von Benedikt (Gast)


Lesenswert?

Eine einfache Lösung:

#define LAMPE_AN PORTB |= (1 << 0)
#define LAMPE_AUS PORTB &=~(1 << 0)

von Philipp Karbach (Gast)


Lesenswert?

#define LAMPE 1

void SetPin(int PORT,int PIN,int VALUE)
{
if(VALUE)
PORT |= _BV(PIN);
else
PORT &= ~_BV(PIN);
}

SetPin(PORTB,LAMPE,1);

oder ähnlich, aber das andere ist doch schon recht einfach ;)

von mil (Gast)


Lesenswert?

besten dank für die schnellen antworten.

beim beispiel von philipp hätte ich noch fragen :

- SetPin(PORTB,LAMPE,1);
PORTB ist ja defniert als _SFR_IO8 (0x05) im iomx8 (für den atmega48)
was wird hier genau übergeben?

- ~_BV(PIN) : für was steht das _BV ?

besten dank

von johnny.m (Gast)


Lesenswert?

Also mit einer Funktion würd ich da gar nix machen. Die verbraucht
Speicher und Rechenleistung bzw. Rechenzeit des µC. Mach es
ausschließlich mit #define.... Dann wird alles zur Compilerlaufzeit
ausgerechnet.

z.B.:

#define LAMPE 0
...
PORTB |= 1 << LAMPE; //LAMPE ein
PORTB &= ~(1 << LAMPE); //LAMPE aus

oder, wenn das noch zu kompliziert ist:

#define LAMPE 0
#define LAMPE_EIN PORTB |= 1 << LAMPE
#define LAMPE_AUS PORTB &= ~(1 << LAMPE)
...
LAMPE_EIN; //LAMPE ein
LAMPE_AUS; //LAMPE aus

von Frank E. (erdi-soft)


Lesenswert?

Die Lösung von Philipp hat aber den Vorteil, dass Hardwarefunktionen von
der Software komplett getrennt werden. Das erhöht die Portabilität
enorm. In der Regel wird hier auch gleich eine Trennung in  HAL
(Hardware Abstraction Layer) und Andwendungslayer gemacht.
Somit muss bei einem Prozessorwechsel nur noch die HAL angepasst
werden, die Anwendung an sich ist dann so Plattformunabhängig, dass
nichts mehr daran getan werden muss.

Inwieweit das natürlich im Hobbybereich notwendig ist, sei
dahingestellt. Weiterer Vorteil ist aber auch, dass man die HAL als
Bibliothek einbinden kann und sich somit bei jeden neuen Projekt für
diesen Controller rein um die Anwendung kümmern kann.

von mil (Gast)


Lesenswert?

aha, interessant.

gibt es für diese art irgendwo beispiele? mit dem beispiel von philipp
habe ich noch irgend ein problem, es will grad nicht so recht...

merci

von Benedikt (Gast)


Lesenswert?

Wenn man alles mit HAL macht, kann man auch gleich Windows nehmen.
Dann braucht man halt 2GHz nur damit der Mauszeiger ruckelfrei läuft.

HAL macht eigentlich nur Sinn, wenn man weiß dass die Software auf
verschiedenen Systemen laufen soll. Ansonsten tun es defines auf
jedenfall auch, und sind vermutlich um den Faktor 10 schneller.

von Frank E. (erdi-soft)


Lesenswert?

Ich hab das spasseshalber mal für ein Projekt (zumindest Ansatzweise)
umgesetzt:

hal.c:
1
#include "hal.h"
2
3
void initPort(uint8_t port, uint8_t direction)
4
{
5
  switch(port)
6
  {
7
    case 'a':
8
      DDRA = direction;
9
    break;
10
11
    case 'b':
12
      DDRB = direction;
13
    break;
14
15
    case 'c':
16
      DDRC = direction;
17
    break;
18
19
    case 'd':
20
      DDRD = direction;
21
    break;
22
  }
23
}

hal.h:
1
#include <inttypes.h>
2
#include <avr/io.h>
3
#include "lcd.h"
4
5
void initPort(uint8_t port, uint8_t direction);
6
void setPort(uint8_t port, uint8_t value);

Die hal.h macht man dann der Anwendung bekannt. Dinge, die die
Anwendung nicht kennen darf, packt man in ne separate Header, die man
auch in der hal.c einbindet (z.B. darf das Definitionsfile für den
Controller, z.B. m8def.in, nur der HAL bekannt sein, da ansonsten die
Anwendung wieder direkten Zugriff auf die Hardware bekommt.).

Das verlangt natürlich eine gewisse Disziplin, das durchzuhalten. Und
wie gesagt, ob das im Hobbybereich Sinn macht, sei dahingestellt. Auf
den ersten Blick sieht es deutlich nach Mehraufwand auf, aber
spätestens beim 2. Projekt amortisiert sich das dann wieder.

Man kann diese Trennung auch mal mit einem Betriebssystem vergleichen.
Dieses lässt auch keine direkten Zugriffe auf die Hardware zu, sondern
kapselt jeglichen Zugriff (sofern überhaupt möglich) in Funktionen, die
gleich noch Kontrollfunktion haben. Somit kann man schon im Vorfeld
falsche Parameter filtern.
Na ja, genug geredet. Falls du noch mehr Infos dazu willst, kannst du
ja schreiben.


Gruß, ERDI - Soft.

von Karl heinz B. (kbucheg)


Lesenswert?

> #define LAMPE 1
>
> void SetPin(int PORT,int PIN,int VALUE)
> {
< if(VALUE)
> PORT |= _BV(PIN);
> else
> PORT &= ~_BV(PIN);
> }

Das wird so mit Sicherheit nichts.
Mit C-Funktionen hast du da keine Chance, da der
Compiler das was wie eine Zuweisung aussieht:

    PORTA = 5;

völlig anders behandeln muss, wie eine normale Zuweisung:

   int i;
   i = 5;

Innerhalb der Funktion, ist diese Unterscheidung aber
nicht mehr feststellbar.

Wenn man sowas machen will, dann geht der Weg nur über
Makros.

von Peter D. (peda)


Lesenswert?

HAL heißt nicht, mit Kanonen auf Spatzen schießen zu müssen.

Es heißt nur, die Zugriffe formal zu kapseln.

Rein syntaktisch besteht zwischen Funktionen und Macros eh kein
Unterschied.
Es ist also völlig wurst, ob ein Macro zu einem Funtionsaufruf
expandiert oder den Befehl direkt ausführt.


Eine effiziente Möglichkeit ist das hier:

http://www.mikrocontroller.net/forum/read-1-368567.html#368661


Peter

von Günter R. (galileo14)


Lesenswert?

Karl Heinz hat recht mit seiner Anmerkung; Ports als Funktionsparameter
funktionieren so nicht; das ist ausführlich abgehandelt im "avr-libc
Reference Manual" (Abschnitt "How do I pass an IO port as a parameter
to a function"), die u.a. im WinAVR enthalten ist.

von Volker (Gast)


Lesenswert?


von Rolf Magnus (Gast)


Lesenswert?

> Also mit einer Funktion würd ich da gar nix machen. Die verbraucht
> Speicher und Rechenleistung bzw. Rechenzeit des µC.

Eine inline-Funktion ist im schlechtesten Fall genauso schnell, wie ein
Makro.

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.