mikrocontroller.net

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


Autor: Daniel P. (dpointeck)
Datum:

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

Autor: ThomasL (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

Für die LED geht das dann genauso.

Autor: Daniel P. (dpointeck)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Das Tier (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun, Taster gedrückt Pin ist high.

Autor: Daniel P. (dpointeck)
Datum:

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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define TASTERPORT PIND
#define TASTERBIT  PIND2

if (TASTERPORT & (1<<TASTERBIT))
// ...

Man kann auch Makros definieren, über die auf die Portbits wie auf
Variablen zugeriffen werden kann, dazu muss man aber etwas weiter
ausholen:
// Allgemeine Definitionen:

struct bits {
  uint8_t b0:1;
  uint8_t b1:1;
  uint8_t b2:1;
  uint8_t b3:1;
  uint8_t b4:1;
  uint8_t b5:1;
  uint8_t b6:1;
  uint8_t b7:1;
};

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


// Konkrete Definitionen der einzelnen Portbits:

#define TASTER BIT(PIND,  2)
#define LED    BIT(PORTD, 0)


// Verwendung der Makros:

// ...
  if(TASTER)  // oder auch: if(TASTER == 1)
    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.

Autor: Michael Appelt (micha54)
Datum:

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

Autor: Daniel P. (dpointeck)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: max (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du umbedingt ==1 willst dann mach:

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

  ;)

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Klaus (Gast)
Datum:

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

Autor: yalu (Gast)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

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

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.