Einzelnen Beitrag anzeigen

Benutzerbild von Matze
Matze
(Co-Admin)

Registriert seit: 7. Jul 2003
Ort: Schwabenländle
14.929 Beiträge
 
Turbo Delphi für Win32
 
#3

Re: [c-lib] Parellelport-Tutorial

  Alt 15. Jun 2006, 17:41
Machen wir folgenden Versuch:

Angenommen wir haben auf die Datenbits im Parallelport Schalter angeklemmt, diese von 0 bis 7 nummeriert, und wollen nun wissen, wie ich den Schalter im Computer zuordnen kann. Gehen wir davon aus, jeder hat schon mal auf den Port zugegriffen und weiß, wie das geht und er hat nun einen Wert in der Variablen ReadLPTPort stehen.

ReadLPTPort wie folgt deklariert

ReadLPTPort: Byte Kleines Beispiel:

Delphi-Quellcode:
asm
  Mov DX, $378h // Portadresse in DX Register schreiben
  In AL, DX // Port in AL Register lesen
  Mov ReadLPTPort, AL // Wert aus AL Register in Variable eintragen
end;
Natürlich kann man davon auch eine Function machen und den Wert darüber einlesen, aber das machen wir später. Hier geht es um etwas anderes.
Wie kann ich erkennen, welche Schalter hinter dem Wert 163 z. B. stehen.
Und jetzt geb ich euch eine Function.

function Byte_To_Str(ByteWert: Byte): string; Na, ist das was? Na gut, geb ich euch eben den zugehörigen Quellcode.

Delphi-Quellcode:
function Byte_To_Str(Byte_Val: Byte): string;
var
  CalcWert : Integer;
  Ausg : string;
begin
  Ausg := '';
  CalcWert := Byte_Val;

  repeat
    if CalcWert / 2 = Trunc(CalcWert / 2) then
      Ausg := '0' + Ausg
    else
      Ausg := '1' + Ausg; // Darauf achten: Der String wächst von hinten !
    Calcwert := Trunc(CalcWert / 2);
  until Calcwert = 0;

  while Length(Ausg) < 8 do // Wir wollen doch den ganzen Port also 8 Bit
    Ausg := '0' + Ausg;

  Byte_To_Str := Ausg;
end;
Also, die Integerzahl 163 wird durch 2 geteilt und geprüft, ob sie gerade oder ungerade war. Bei einer ungeraden Zahl ergibt sich ein Rest von 1 bzw. bei einer geraden eben ein Rest 0. Diese Werte werden von hinten in einen String eingetragen und die Rechnung mit dem ganzen halben Wert wiederholt. Solange, bis nur noch 0 übrigbleibt.

Klartext:

Code:
163 / 2 = 81 Rest 1     String ="1"               ("1")
81 / 2  = 40 Rest 1     String = "1" + String     ("11")
40 / 2  = 20 Rest 0     String = "0" + String     ("011")
20 / 2  = 10 Rest 0     String = "0" + String     ("0011")
10 / 2  = 5 Rest 0     String = "0" + String     ("00011")
5 / 2   = 2 Rest 1     String = "1" + String     ("100011")
2 / 2   = 1 Rest 0     String = "0" + String     ("0100011")
1 / 2   = 0 Rest 1     String = "1" + String     ("10100011")
Die Abfrage nach der Länge des String ist nur bei kleineren Zahlen notwendig, um den String mit vorstelligen "0"en aufzufüllen. Der String zeigt nun, dass Schalter S7, S5, S1 und S0 geschaltet sind. Das ist doch was, oder....

Wenn ihr wollt:

Edit1.Text := Byte_To_Str(ReadLPTPort); Und weil ich es schon hab und ihr es auch wollt, gleich die Kehrseite, nämlich die "1" aus einem String

zum Ansteuern von irgendwas nehmen:

Delphi-Quellcode:
function Str_To_Byte(Str_Val: string): Byte;
var
  i : Integer;
  Ausg : Real;
begin
  Ausg := 0;
  for i := 0 to Length(Str_Val) - 1 do
    if Str_Val[Length(Str_Val) - i] = '1then
      Ausg := Ausg + Power(2, i); // dies ist die Function 2 hoch n (uses Math)
  Str_To_Byte := Trunc(Ausg);
end;
Funktioniert folgendermaßen:

String hat den Wert "10100011", sagen wir mal, den Wert der eingelesenen Schalter.
Um ein bisschen unabhängig von der Stringlänge zu sein, lassen wir die Schleife bis zur Länge des Strings laufen, und da wir bei 0 anfangen, muss es natürlich auch Length(String)-1 lauten.

for i := 0 to Length(Str_Val) - 1 do ... Beachte:

Bei längeren Strings ist die Function mit anderem Typ zu deklarieren, weil Bytewerte nur bis 255 gehen, nicht, dass mir dann unterstellt wird, meine Function könnte nicht rechnen....

Also: Ist das letze Zeichen-Laufzähler (im String = 1 dann ist die die Summenvariable = Summenvariable + 2 hoch Laufzähler. Dies erledigt die

Function Power(Basis, Exp).
Delphi-Quellcode:
if Str_Val[Length(Str_Val) - i] = '1then
  Ausg := Ausg + Power(2, i); ...
Sie liefert allerdings einen Realwert, daher muss der Ausgang letztlich mittels Trunc-Function zugewiesen werden.
So, damit haben wir schon die Möglichkeit in einem Textfeld Bits anzusehen oder zu setzen. Vereinbaren wir nun ein Ausgabe-Byte für den Port.

WriteLPTPort: Byte; Dann könnte die Ausgabe eines Textfeldes an den LPT1 folgendermaßen lauten:

Delphi-Quellcode:
WriteLPTPort := Str_To_Byte(Edit1.Text);
asm
  Mov DX, $378
  Mov AL, WriteLPTPort
  Out DX, AL
end;
So, hat doch was.
Ich hab jetzt Schalter, die über einen komplizierten und teuren Rechner und einem mit einem nicht minder teuren Entwicklungstool geschriebenen Programm Relais schalten.....
Wer's einfacher haben will, der sollte direkt mit den Schaltern sein Licht an- und ausknipsen....
  Mit Zitat antworten Zitat