Pins einlesen unter C

Gast #74980
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
Admin Persönliche Seite #74981
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!
Gast #74982
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
Gast #74983
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
Gast #74985
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
Gast #74986
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.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.