Wie funktioniert das binäre ansteuern von Ports?

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
TigerClaw
Posts: 2
Joined: Fri Jan 05, 2007 9:38 pm

Wie funktioniert das binäre ansteuern von Ports?

Post by TigerClaw »

Viele Benutzer in diesem und anderen Foren bewegt diese Frage sehr.

Grundlage:
Ein Byte besteht aus 8 Signalleitungen die entweder An oder Aus sind (5 V oder 0 V).
Ein Byte kann bekanntlich 256 verschiedene Werte darstellen.
Binär sieht das wie folgt aus:
00000000 = 0
00000001 = 1
00000010 = 2
00000011 = 3
00000100 = 4
usw. bis (!):
11111111 = 255
Geschrieben wird von Rechts nach Links!
Das ist eigentlich die ganze Zauberei. Genaueres kann man aber bei Wikipedia nachschlagen: http://de.wikipedia.org/wiki/Dualsystem
Oder einfach googlen. :wink:

Interessant wird es jetzt für die, die nun einzelne Pins setzen möchten:
In diesem Beispiel möchte ich Bit (Pin) 5 und 7 setzen.
Pin 5: 00010000
Pin 7: 01000000
Ergibt: 01010000
Pin 5 (dezimal 16) plus Pin 7 (dezimal 64) währe ein Bytewert von 80.
Währe der Zustand der Pins für uns uninteressant könnte man diesen Wert einfach an die Schnittstelle senden (IO Warrior, LPT Port, Serial Port usw.)

Aber! Wie ich gelesen habe ist es nicht so. :wink: Wir müssen den Ist Zustand übernehmen. Also lesen wir den Ist Wert erst aus (Nicht IO Warrior!) oder holen Ihn uns aus einer Variablen in der wir den aktuellen Wert mitgeführt haben. (Siehe Hinweis von Herrn Körber.)

Mit dem Ist Wert und unseren gewünschten Pin 5 und 7 machen wir nun folgendes: Maskieren mit OR!
Nehmen wir an die Pins 2, 3, 5 und 8 haben wir bereits vorher schon gesetzt und in einer Variablen vermerkt! (Wichtig für IO Warrior.) Einfaches Addieren geht nicht (!) da Pin 5 schon gesetzt ist und eine Addition einen Überlauf zum nächsten Bit ergeben würde (Wie im Dezimalen auch wenn man zu 9 eins dazu addiert.).
Binär sieht der Ist Stand so aus:
Pin 2: 00000010
Pin 3: 00000100
Pin 5: 00010000
Pin 8: 10000000
Ergibt: 10010110 = Dezimal 150

OR oder ODER *grins* funktioniert so: Ein Bit wird immer dann gesetz wenn mindestens ein Bit in Argument A und B vorkommt!
Dieses kann man in sogenannten Wahrheitstabellen schnell und genau nachschlagen: http://de.wikipedia.org/wiki/Logikgatter

Wir nehmen nun den Ist Stand machen OR mit unseren gewünschten Pins. Aber Bitweise(!):
Ist OR Gewünscht = Ergebnis
Pin 1: 0 OR 0 = 0
Pin 2: 1 OR 0 = 1
Pin 3: 1 OR 0 = 1
Pin 4: 0 OR 0 = 0
Pin 5: 1 OR 1 = 1
Pin 6: 0 OR 0 = 0
Pin 7: 0 OR 1 = 1
Pin 8: 1 OR 0 = 1
Ergebnis Wagerecht: Binär: 11010110 Ergibt Dezimal: 214

Wenn wir nun die 214 auf unsere Schnittstelle ausgeben und danach in der mitgeführten Variablen abspeichern haben wir es richtig gemacht. :)

Um ein Bit zu löschen nimmt man einfach AND: Nur wenn beide Bits von Argument A und B gesetzt sind ist das Ergebnis 1!
Beispiel:
1 AND 1 = 1 (Da wir ja das Bit löschen wollen wird diese AND Verknüpfung nicht vorkommen.)
1 AND 0 = 0
0 AND 0 = 0
0 AND 1 = 0 (Da wir ja das Bit löschen wollen wird diese AND Verknüpfung nicht vorkommen.)
-So funktioniert das mit den Binärwerten!

---------------------------------------------------------------
Mit Delphi, C++ und Visual Basic geht es einfacher:
$Ergebnis := $ArgumentA OR $ArgumentB;
Dabei ist es egal ob die Variablen Dezimal oder Binär verwendet werden.

Das war es erst mal. :) Ich hoffe es hilft jemanden.

Folgende kleine Funktion wandelt Dezimalzahlen in Binärzahlen um (Delphi 6.0):
---------------------------------------------------------------
// Integer nach Binär umwandeln.
function IntToBin(Int: Integer): String;
var
i : Integer;
begin
Result := '';
for i := 7 downto 0 do
Result := Result + IntToStr((Int shr i) and 1);
end;
---------------------------------------------------------------
Erklährung: shr (ShiftRight) schiebt ein Bit weiter nach rechts.
---------------------------------------------------------------
Folgendes Experimentier Programm von mir liest und beschreibt mit hilfe von inpout32.dll LPT Ports. (Delphi Quellcode liegt bei. IntToBin verwende ich hier.)
http://www.prozessor.org/tigerclaw/files/LPT-Port.zip

An meine LPT Schnittstelle habe ich eine LED auf einen Pin direkt zu GND gelegt und mit diesem Programm An und Aus geschaltet. :)
Wer zum testen aber sicher gehen möchte sollte einen 1KOhm Widerstand in Reihe zu GND schalten:

Pin1      LED     __R1     GND
O------|>|------|__|------|

---------------------------------------------------------------
Hier einige Links die mir weiter geholfen haben:

http://www.netzmafia.de/skripten/hardwa ... lport.html
(Die beste Erklärung zur LPT Programmierung.)

http://lena.franken.de/hardware/temperaturmessung.html
(Die Schaltung habe ich nachgebaut und funktioniert einwandfrei. -Auch mit mehreren Temperaturchips.
Schön wenn irgendwann jemand den Dallas Chip 1820 mit hilfe des IO Warriors am laufen bekommen würde und es veröffentlicht.)

http://cc5x.de/schaltungen/
(Hier habe ich auch die LED Schaltung her.)
---------------------------------------------------------------

Gruß
TigerClaw

---------------------------------------------------------------
Edit1: Ein Tip ist mir noch eingefallen:
Das Umrechnen von Binär nach Dezimal und umgekehrt mache ich mit dem Windows mitgelieferten Taschenrechner (Start/Alle Programme/Zubehör/Rechner).
Diesen im Menupunkt "Ansicht" auf Wissenschaftlich stellen.
Nun kann man den Wert Dezimal eingeben und einfach auf Binär umschalten und umgekehrt. :wink:

Edit2: Port in Pin umbenannt. Szenario Port lesen umgeändert in Variable.
Last edited by TigerClaw on Mon Jan 08, 2007 12:02 pm, edited 7 times in total.
Guido Körber
Site Admin
Posts: 2882
Joined: Tue Nov 25, 2003 10:25 pm
Location: Germany/Berlin
Contact:

Post by Guido Körber »

Also Daten zurücklesen, maskieren und dann in den IO-Warrior schreiben ist ganz schlecht. So wird aus einem Eingang der extern auf Null gezogen wurde ein Ausgang der auf Null zieht.

Generell immer die zuletzt geschriebenen Daten aufheben und bei Änderungen mit Logikfunktionen darauf zu greifen.

Der Begriff "Port" bezieht sich in diesem Kontext immer auf eine Gruppe von Pins die physikalisch zusammen angesteuert werden, der IOW40 hat vier Ports zu je 8 Pins.
TigerClaw
Posts: 2
Joined: Fri Jan 05, 2007 9:38 pm

Post by TigerClaw »

Habe den Text entsprechend korrigiert und das Port Auslesen umformuliert: Anstelle die Werte vom Port zu lesen werden die manipulierten Pins in einer Variablen mitgeführt. Ich hoffe der Sinn im Text past. :)
Post Reply