GCC : NAMEN statt Pinnummern?

Gast #366818
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
Gast #366820
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 ;)
Gast #366821
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
Gast #366822
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
#366823
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.
Gast #366825
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.
#366826
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.
#366827
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.
#366828
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
Gast #366831
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren