Forum: Compiler & IDEs Pins einlesen unter C


von Noname 1 (Gast)


Lesenswert?

Hallo Leute,

ich möchte gerne einen Pin einlesen und den Wert in einer Variablen
speichern.
Kann mir jemand sagen, wie dies Programmiert werden soll.

Danke

von Georg Schmidt (Gast)


Lesenswert?

Hallo,
wenn Du WinAVR verwendest, ist das ganz einfach.
Wenn Du zum Beispiel Port D, Pin 4 lesen möchtest, geht das mit

#include <avr\io.h>
bool ReadPin (void)
{
bool variable;
variable = PORTD & 0x10;
return variable;
}

Gruß, Georg

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

PORTD auszulesen dürfte in den wenigsten Fällen sinnvoll sein, um den
tatsächlich am Pin anliegenden Wert zu bekommen muss man PIND lesen.

bool ist kein Standard-Datentyp, und wenn man bool z.B. als unsigned
char definiert, dann kann man sich damit sehr leicht in den Fuß
schießen:


  bool bit;
  unsigned char var = 0;

  // Pin nach "bit" einlesen und "bit" von rechts in "var"
reinschieben
  bit = PIND & 0x10;
  var = (var << 1) | bit;  // hier kracht's!

von Berndt Brandes (Gast)


Lesenswert?

Dann machen wir eben aus
:  bit = PIND & 0x10;
die neue Zeile:
:  bit = (PIND & 0x10) ? 1 : 0;

Ist für so einen Fall wohl besser, hier hat man die totale Kontrolle.

Andere Variante:
:  bit = (PIND & 0x10) != 0;
hier entscheidet der Compiler über "Wahr" und "Falsch"

Hat noch jemand eine andere Lösung?

/Berndt

von Georg Schmidt (Gast)


Lesenswert?

Uups, da hab ich mich doch glatt mit PORT und PIN vertan.... natürlich
muss es PIN heißen...

Und, ja, ich habe bool als unsigned char definiert. Hat bisher noch nie
Probleme gegeben....mit Bit-Operationen muss man natürlich schon ein
wenig aufpassen. Bernds Lösung ist hier natürlich nicht schlecht.

Gruß, Georg

von Noname 1 (Gast)


Lesenswert?

Hallo, vielen Dank für eure Hilfe.

von Berndt Brandes (Gast)


Lesenswert?

habe eben festgestellt, daß der Compiler aus meinen Konstrukten
SCHLEIFEN!!! macht, um das abgefragte bit nach bit 0 zu kriegen. Eine
bessere Variante ist offenbar diese:
if (PIND & (char)0x10)
      bit=1;
    else
      bit=0;

oder noch besser (Compilat 7 words):
    {
      char tmp;
      if (PIND & (char)0x10)
        tmp=1;
      else
        tmp=0;
      bit=tmp;
    }

Man sieht also mal wieder: was einfach aussieht ist für den Compiler
nicht immer verständlich!

/Berndt

von Joerg Wunsch (Gast)


Lesenswert?

Wobei sich natürlich die Frage stellt, warum man solche Verrenkungen
überhaupt machen will.  Meist reicht es ja, wenn man sich den
interessierenden Bitwert einmal in einer Variable speichert und diese
dann innerhalb eines if() benutzt.  Ich kann mir so keine Anwendung
vorstellen, bei der man unbedingt hinterher in einer Variablen die
Werte 1 oder 0 brauchen würde...

Btw., bitte nicht

#include <avr\io.h>

schreiben, das macht den Code nur künstlich unportabel.

#include <avr/io.h>

ist portabel, das wird von allen gängigen C-Implementierungen und
Betriebssystemen verstanden (zumindest von denen, auf denen avr-gcc
läuft ;-).  Die Verrenkungen mit den Backslashes muß man bei DOS/Win
nur auf der Kommandozeile von command.com/cmd.exe machen, intern
verstehen diese Systeme sehr wohl schon seit 15 Jahren auch
Vorwärtsstriche als Pfadnamentrenner.  Wenn man eine bash als
Kommandointerpreter benutzt (wie das make.exe sie ja implizit
ausführt), funktionieren die Vorwärtsstriche natürlich auch genauso.

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.