mikrocontroller.net

Forum: Compiler & IDEs flexibles Schalten von bits


Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo


Ich arbeite mit einem gcc-Compiler auf einem ARM7-Controller.
Das Setzen und Löschen von Bits funktioniert einwandfrei. Trotzdem frage 
ich mich, ob es nicht noch eine flexiblere Lösung für das Problem gibt.
Aktuell erfolgt das Setzen und Rücksetzen über:

#define LED1_ON  IOSET  = (1<<21); // Pin 25 auf HIGH schalten
#define LED1_OFF  IOCLR  = (1<<21); // Pin 25 auf LOW schalten


gerne hätte ich aber eine Lösung wie etwa

unsigned char ON  = 0;
unsigned char OFF = 1;

LED1 = ON; // schalte LED ein
LED1 = OFF; // schalte LED aus

Wieso? Tja, je nach Hardware möchte man einen Ausgang oftmals als activ 
Low oder active High ansprechen. Im zweiten Fall muss ich nur mehr ON 
und OFF entsprechend initialisieren.

Gibt es in gcc hier auch eine elegante und effiziente Lösung?

Vielen Dank

Klaus

Autor: wulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Im zweiten Fall muss ich nur mehr ON
>und OFF entsprechend initialisieren.

Im ersten Fall brauchst du ja auch nur die defines umdrehen...

Autor: wulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
noch eine Ergänzung:
du könntest dir ein Makro schreiben, um ein Bit zu setzen/löschen und 
diesem dann per define den Ausgang übergeben
(also zb LED definieren auf PORTB bzw. PB0 und das dann dem Makro zum 
setzen/löschen geben

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Setzen/Löschen von Bits per direkter Zuweisung gab's schon mal
einen Thread:

  Beitrag "sbit macro für avr-gcc"

Damit kannst du (nach entsprechender Definition von LED1) wie
gewünscht
unsigned char ON  = 0;
unsigned char OFF = 1;

LED1 = ON; // schalte LED ein
LED1 = OFF; // schalte LED aus
schreiben.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Vielen Dank für die Infos.


@wulf: der entscheidende Vorteil ist, dass ich die Pins während der 
Programmlaufzeit ändern kann.

@yahlo: Habe dort eine Lösung gefunden. Sie sieht folgendermassen aus:

für alle, die es interessiert:

typedef unsigned char byte ;

struct bitVector 
{
  byte b0:1;
  byte b1:1;
  byte b2:1;
  byte b3:1;
  byte b4:1;
  byte b5:1;
  byte b6:1;
  byte b7:1;
  byte b8:1;
  byte b9:1;
  byte b10:1;
  byte b11:1;
  byte b12:1;
  byte b13:1;
  byte b14:1;
  byte b15:1;
  byte b16:1;
  byte b17:1;
  byte b18:1;
  byte b19:1;
  byte b20:1;
  byte b21:1;
  byte b22:1;
  byte b23:1;
  byte b24:1;
  byte b25:1;
  byte b26:1;
  byte b27:1;
  byte b28:1;
  byte b29:1;
  byte b30:1;
  byte b31:1;
} __attribute__((__packed__));

#define BIT(r,n) (((volatile struct bitVector *)&r)->b##n)

#define MODUL_LED     BIT(IOPIN,10)  // schalte IO-Pin

int main(void)
{  
    unsigned long i;

    IODIR |= 0x10000400;
    while (1==1)
    {    
       MODUL_LED = 1; // schalte Led aus
       for (i=0; i<0x1FFFFF; i++);
       MODUL_LED = 0; // schalte Led ein
       for (i=0; i<0x1FFFFF; i++);
    }
    return 0;
}


Beste Grüsse und nochmals vielen Dank für den hilfreichen Tipp!

Klaus



Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus wrote:

> @yahlo: Habe dort eine Lösung gefunden. Sie sieht folgendermassen aus:


Aber aufpassen, das ist dann nicht mehr atomar !

Falls Pins des gleichen Ports auch in Interrupts gesetzt werden.


Peter

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter

Vielen Dank für Deine Info. Das könnte ein gemeine Fehlerquelle sein. 
Mir geht es neben der Flexibilitä v.a. auch um Effizienz des Codes:)

Hast du vielleicht eine idealiere Lösung oder habe ich mich da zu früh 
gefreut?

Beste Grüsse

Klaus.

Autor: wulf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>der entscheidende Vorteil ist, dass ich die Pins während der
>Programmlaufzeit ändern kann.
ahh... Schon klar!
Du willst quasi wie bei zB PonyProg die Ausgänge invertiert oder nicht.
Eine Lösung, die funktionieren kann aber nicht muss (Überblick ist 
wichtig!)
Dort wo du invertiert/nicht inv. umstellst, setzt du die Ausgänge und 
überall wo es nötig ist, toggelst du sie. Kommt aber auch vor allem auf 
die Anwendung an, ob es so geht.

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.