Eingang bzw. Ausgangsbit als Variable deklarieren

#1065350
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
#1065378
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.
#1065413
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.
Gast #1065420
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.
Gast #1065477
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 ;)
Gast #1065479
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.
#1065482
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.
#1065487
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

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