www.mikrocontroller.net

Forum: Compiler & IDEs GCC : NAMEN statt Pinnummern?


Autor: mil (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine einfache Lösung:

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

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: mil (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Frank Erdrich (erdi-soft)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: mil (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank Erdrich (erdi-soft)
Datum:

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

hal.c:
#include "hal.h"

void initPort(uint8_t port, uint8_t direction)
{
  switch(port)
  {
    case 'a':
      DDRA = direction;
    break;

    case 'b':
      DDRB = direction;
    break;

    case 'c':
      DDRC = direction;
    break;

    case 'd':
      DDRD = direction;
    break;
  }
}

hal.h:
#include <inttypes.h>
#include <avr/io.h>
#include "lcd.h"

void initPort(uint8_t port, uint8_t direction);
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.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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...


Peter

Autor: Günter R. (galileo14)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.