Forum: Compiler & IDEs flexibles Schalten von bits


von Klaus (Gast)


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

von wulf (Gast)


Lesenswert?

>Im zweiten Fall muss ich nur mehr ON
>und OFF entsprechend initialisieren.

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

von wulf (Gast)


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

von yalu (Gast)


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
1
unsigned char ON  = 0;
2
unsigned char OFF = 1;
3
4
LED1 = ON; // schalte LED ein
5
LED1 = OFF; // schalte LED aus
schreiben.

von Klaus (Gast)


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:
1
typedef unsigned char byte ;
2
3
struct bitVector 
4
{
5
  byte b0:1;
6
  byte b1:1;
7
  byte b2:1;
8
  byte b3:1;
9
  byte b4:1;
10
  byte b5:1;
11
  byte b6:1;
12
  byte b7:1;
13
  byte b8:1;
14
  byte b9:1;
15
  byte b10:1;
16
  byte b11:1;
17
  byte b12:1;
18
  byte b13:1;
19
  byte b14:1;
20
  byte b15:1;
21
  byte b16:1;
22
  byte b17:1;
23
  byte b18:1;
24
  byte b19:1;
25
  byte b20:1;
26
  byte b21:1;
27
  byte b22:1;
28
  byte b23:1;
29
  byte b24:1;
30
  byte b25:1;
31
  byte b26:1;
32
  byte b27:1;
33
  byte b28:1;
34
  byte b29:1;
35
  byte b30:1;
36
  byte b31:1;
37
} __attribute__((__packed__));
38
39
#define BIT(r,n) (((volatile struct bitVector *)&r)->b##n)
40
41
#define MODUL_LED     BIT(IOPIN,10)  // schalte IO-Pin
42
43
int main(void)
44
{  
45
    unsigned long i;
46
47
    IODIR |= 0x10000400;
48
    while (1==1)
49
    {    
50
       MODUL_LED = 1; // schalte Led aus
51
       for (i=0; i<0x1FFFFF; i++);
52
       MODUL_LED = 0; // schalte Led ein
53
       for (i=0; i<0x1FFFFF; i++);
54
    }
55
    return 0;
56
}

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

Klaus



von Peter D. (peda)


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

von Klaus (Gast)


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.

von wulf (Gast)


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.

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.