Forum: Compiler & IDEs Eingang bzw. Ausgangsbit als Variable deklarieren


von Daniel P. (dpointeck)


Lesenswert?

Hallo zusammen,

für mich ist die AVR programmierung Neuland und wollte von euch wissen 
ob es möglich ist für Ein/Ausgangsbits Variablen zu vergeben?

z.B.:

statt:

if (PIND & (1<<PIND2))
{
 PORTB = 0x01;
}

so:

if(Taster == 1)
{
 LED =1;
}

weil so wäre der Code verständlicher

von ThomasL (Gast)


Lesenswert?

Hi

Ja das geht, falls ich dich richtig verstehe...
1
#define Taster (PIND & (1<<PIND2))

Für die LED geht das dann genauso.

von Daniel P. (dpointeck)


Lesenswert?

Hallo und danke,

ja stimmt schon.
Nur hab ich hier das Problem das der Taster hier als high abgespeichert 
wird.
ich will eigentlich nir für das 3.Bit am PORTD eine Variable definieren.

von Johannes M. (johnny-m)


Lesenswert?

Daniel P. wrote:
> if (PIND & (1<<PIND2))
> {
>  PORTB = 0x01;
> }
>
> so:
>
> if(Taster == 1)
> {
>  LED =1;
> }
Nein. Geht so nicht, weil (PIND & (1<<PIND2)) nie gleich 1 ist! Es ist 
allerhöchstens gleich "1 << PIND2", also "1 << 2" oder 4.

Wenn Du allerdings das "==1" weglässt, dann wird (PIND & (1<<PIND2)) als 
Wahrheitswert ausgewertet, und dann klappt es. Also einfach den 
Vergleich weglassen.

von Johannes M. (johnny-m)


Lesenswert?

Daniel P. wrote:
> Nur hab ich hier das Problem das der Taster hier als high abgespeichert
> wird.
Vestehe nicht ganz, was Du damit sagen möchtest.

von Das Tier (Gast)


Lesenswert?

Nun, Taster gedrückt Pin ist high.

von Daniel P. (dpointeck)


Lesenswert?

Also das ist so gemeint das ich eigentlich nur immer den Zustand des 3. 
Bit am PORTD abfragen will das wäre eigentlich nur 1 bzw. 0.
Dies funktioniert nicht weil es in der Realität 0 bzw. 4 ist.

Also sieht das ganze momentan so aus:

#define Taster (PIND &(1<<PD2))

int main(void)
{

  DDRD = 0x00;
  PORTD = 0xff;


  DDRB = 0xff;
  PORTB = 0x00;

  while (1)
  {
    if (Taster == 4)
    {
      PORTB = 0x00;
    }
    else
    {
      PORTB = 0x01;
    }

  }

}

für mich sehe aber das ganze schöner aus wenn ich den Taster mit
if (Taster == 1) abfragen könnte.

von yalu (Gast)


Lesenswert?

Es gibt verschiedene Möglichkeiten, den Code transparenter zu machen:

Die einfachste besteht darin, für den Port und das Portbit
aussagekräftigere Namen zu vergeben:
1
#define TASTERPORT PIND
2
#define TASTERBIT  PIND2
3
4
if (TASTERPORT & (1<<TASTERBIT))
5
// ...

Man kann auch Makros definieren, über die auf die Portbits wie auf
Variablen zugeriffen werden kann, dazu muss man aber etwas weiter
ausholen:
1
// Allgemeine Definitionen:
2
3
struct bits {
4
  uint8_t b0:1;
5
  uint8_t b1:1;
6
  uint8_t b2:1;
7
  uint8_t b3:1;
8
  uint8_t b4:1;
9
  uint8_t b5:1;
10
  uint8_t b6:1;
11
  uint8_t b7:1;
12
};
13
14
#define BIT(r,n) (((volatile struct bits *)&r)->b##n)
15
16
17
// Konkrete Definitionen der einzelnen Portbits:
18
19
#define TASTER BIT(PIND,  2)
20
#define LED    BIT(PORTD, 0)
21
22
23
// Verwendung der Makros:
24
25
// ...
26
  if(TASTER)  // oder auch: if(TASTER == 1)
27
    LED = 1;

Obwohl das etwas komplizierter aussieht, erzeugt auch hier der GCC
optimalen Code, nämliche exakt zwei Befehle (einen für die Abfrage und
einen für die Zuweisung).

Das Ganze wurde schon einmal hier behandelt:

  Beitrag "sbit macro für avr-gcc"

Was die Lesbarkeit des Codes betrifft: Geübte Mikrocontrollerprogrammie-
rer haben sich schon so sehr an die Notation mit den Bitoperatoren (&,
|, ~ und <<) gewöhnt, dass auch die erste Variante sofort verstanden
wird.

von Michael A. (micha54)


Lesenswert?

Hallo,

Abfagen auf (Taster=1) erledigt man in C besser mit (Taster!=0)
In dieser Version ist es wurst, welches bit tatsächlich benutzt wird.

Gruss,
Michael

von Daniel P. (dpointeck)


Lesenswert?

Danke für die prompten Antworten.
am einfachsten ist wohl die Variante if(Taster != 0) abzufragen.
werde aber die anderen auch noch testen.

also Danke nochmal an alle

von Johannes M. (johnny-m)


Lesenswert?

Michael Appelt wrote:
> Abfagen auf (Taster=1) erledigt man in C besser mit (Taster!=0)
1
if(Taster != 0)
 macht exakt dasselbe wie
1
if(Taster)
Und das hatte ich oben schon mal angesprochen. Wozu also der zusätzliche 
Schreibaufwand?

von max (Gast)


Lesenswert?

wenn du umbedingt ==1 willst dann mach:

#define Taster ((PIND &(1<<PD2)) >>PD2)

  ;)

von Johannes M. (johnny-m)


Lesenswert?

max wrote:
> wenn du umbedingt ==1 willst dann mach:
>
> #define Taster ((PIND &(1<<PD2)) >>PD2)
>
>   ;)
Auaaaa... Komplizierter geht's fast net.
1
#define Taster ((PIND >> PD2) & 1)
Wenn Du natürlich gerne irgendwelche Sachen hin- und herschiebst, möchte 
ich Dich nicht daran hindern;-)

von Klaus (Gast)


Lesenswert?

Ich rate dir, diese Idee nicht weiter zu verfolgen. Auch wenn es 
zunächst ein wenig umständlich aussieht, wie in C die Pins gesetzt 
werden, so geht es nunmal. Daran gewöhnt man sich und dann ist es auch 
gar kein Problem mehr.

Man kann jetzt krampfhaft versuchen einen anderen Weg zu finden, anstatt 
es einfach zu akzeptieren, aber das is verschwendete Zeit ;)

von yalu (Gast)


Lesenswert?

@Johannes M.:
Auch wenn's kommisch klingt: Die doppelte Schieberei von Max wird vom
Compiler komplett eliminiert und durch einen einfachen SBIS-Befehl
ersetzt, während bei deiner Variante der Shift zur Laufzeit ausgeführt
wird, was sind je nach Bitnummer bis zu vier Befehle zusätzlich
bedeutet.

von Johannes M. (johnny-m)


Lesenswert?

yalu wrote:
> @Johannes M.:
> Auch wenn's kommisch klingt: Die doppelte Schieberei von Max wird vom
> Compiler komplett eliminiert und durch einen einfachen SBIS-Befehl
> ersetzt, während bei deiner Variante der Shift zur Laufzeit ausgeführt
> wird, was sind je nach Bitnummer bis zu vier Befehle zusätzlich
> bedeutet.
Hmmm, klingt komisch, is aber so...

Hast natürlich Recht! Bei meiner Variante sind dem Optimizer die Hände 
gebunden. Aber abgesehen davon würde ich immer noch einfach den 
(überflüssigen) Vergleich weglassen. Dann kann man sich das 
zurückschieben schlicht schenken.

von Peter D. (peda)


Lesenswert?

Klaus wrote:

> Man kann jetzt krampfhaft versuchen einen anderen Weg zu finden, anstatt
> es einfach zu akzeptieren, aber das is verschwendete Zeit ;)

Das ist doch kein Krampf, das ist astreines ANSI-C.

Ich finde auch, seitdem ich es verwende, hat sich die Lesbarkeit 
deutlich verbessert.
Und Schreibaufwand spart es obendrein.

Hier noch ein Beispiel mit Bitvariablen nach Yalu:

http://www.mikrocontroller.net/attachment/30300/lcd_drv.zip


Peter

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.