Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   Delphi Ansteuern des Parallelports (https://www.delphipraxis.net/5152-ansteuern-des-parallelports.html)

flomei 25. Mai 2003 19:29


Ansteuern des Parallelports
 
Hallo liebe DP-User! :hi:

Immer wieder wird gefragt, wie man den Parallelport ansteuern kann. Also dachte ich mir: Fängste mal an und schreibst ein Tutorial. Ich hoffe, dass wird mir gelingen. :roll:
Ich werd gleich erstmal mit nem bisschen Theorie anfangen. Zum Aufwärmen! :mrgreen:

Also: Ab geht´s! :D


MfG Florian :hi:



P.S.: Ich werde gelegentlich aus einer meiner Technik-Arbeiten zitieren.

[EDIT] Ich übernehme keinerlei Garantie für die Richtigkeit der von mir gemachten Angaben. Große Teile des Codes stammen aus dem I-Net und aus diesem Forum. Ich danke allen, die durch ihre Beiträge geholfen haben dieses Tutorial zu vervollständigen! [/EDIT]

flomei 25. Mai 2003 20:09

Ansteuern des Parallelports - Teil I: Theorie :-)
 
Es wäre sicherlich zu kompliziert und zu ausführlich alle möglichen Fragen zu beantworten, aber einige (mir wichtig erscheinende) Fragen möchte ich dennoch beantworten.
  • Parallelport? Heisst der nicht auch LPT? Was bedeutet das?
    LPT bedeutet "Line Printer"
    Der Parallelport wird auch Parallele Schnittstelle genannt. Warum? Dazu komme ich noch! :)

    Aus meiner Technik-Arbeit:
    Zitat:

    Der Standard dieser Schnittstelle ist IEEE1284. Die Schnittstelle heißt EPP Enhanced Parallel Port oder ECP Enhanced Capabilities Port oder einfach LPT.
  • Parallelport? Wofür?
    Tja, ganz einfach! Zum Ansteuern aller möglichen (und unmöglichen ;)) Sachen. Zum Beispiel: Drucker, ZIP-Laufwerke, Scanner, usw.
    Wer Fantasie hat und handwerklich/technisch ein wenig geschickt ist kann alles mögliche per Parallelport steuern!
  • Hört sich ja gut an! Wie geht das?
    Eigentlich auch ganz einfach! Die Daten werden über 8 Datenleitungen geschickt. Weiterhin gibt es 8 Statusleitungen. Diese melden zum Beispiel, wenn das Papier leer ist oder wenn der Drucker Daten empfängt.
  • 8 Datenleitungen? Das ist ganz schön schnell, oder?
    Das stimmt! Das funktioniert wie folgt: Über die 8 Datenleitungen werden parallel (daher der Name) Daten gesendet. 8 x 1 Bit macht 1 Byte. D.h.: Pro "Signal" wird ein Byte Daten übertragen.
  • Aha! Wie sehen diese Schnittstellen denn aus und wo finde ich Sie?
    Die Stecker wurden von vielen großen Firmen entwickelt und später auch "Centronics" genannt. Unter diesen Firmen waren auch IBM und Microsoft. Centronics Schnittstellen findet man an (fast) allen PC´s. Während ältere PC´s noch Controller brauchten sind sie heute On-Board. Heutzutage wird der Parallelport allerdings immer unwichtiger, da USB durch Plug&Play flexibler und vielseitiger ist. Es gibt Centronics Stecker in mehreren Ausführungen.

    Hier hab ich mal nen paar Zeichnungen von Centronics Steckern.

Ich hoffe, dass ich jetzt die allerwichtigsten Fragen geklärt habe. Wenn jemand weitere Fragen hat, kann er diese ja per PN an mich richten, ich werde sie dann hier aufnehmen!

MfG Florian :hi:

P.S.: Warum die vielen Edits? Sch*** Bilder! :evil:

[edit=Admin]Bilder eingebettet und als Attachments entfernt. Mfg, Daniel[/edit]

flomei 10. Jul 2003 21:09

Ansteuern des Parallelports - Win9x und ME
 
Vielen Dank Daniel!

Hallo nochmal! :hi:

Da nun soviele Leute hier gefragt haben will ich doch schnell noch einen Teil machen... :roll:

Achtung! Dieser Code funktioniert nur unter Win9x und ME!

Man kann den Parallelport auf Win9x und ME Systemen leicht über eine kleine Prozedur ansprechen...

Delphi-Quellcode:
procedure PortOut(x:byte);
 begin
  asm          //erklärt dem Compiler, dass Assembler Code anfängt
   mov dx,378h //378h ist die Adresse von LPT 1
   mov al,x   //x müssen wir noch einen Wert zuweisen
   out dx,al
  end;
 end;
Schreibt diese Prozedur in euren Quelltext.
Dann könnt Ihr sie leicht aufrufen.
Bsp.:
Delphi-Quellcode:
procedure TEureForm.ZBButtonClick(Sender: TObject); assembler;
 begin
  port(1); //hier weisen wir x einen Wert zu (siehe Tabelle unten)
 end;
In diesem Beispiel setzen wir Datenpin 0 (den ersten Pin am Stecker) auf High.

http://www.delphipraxis.net/specials...ort/dp_937.jpg

Wir können erkennen, dass jeder Pin einen eigenen Wert hat. Setzen wir x nun auf diesen Wert werden die entsprechenden Pins High gesetzt. Damit kann man lustig herum experimentieren und allerlei "Zeugs" ansteuern und was sonst noch alles.

Kommen wir zum Einlesen... :D

Folgender Code stammt von Michael *-=[ Mika ]=-* Wendeln. Er hat mir beim Einlesen geholfen. Er wurde von ihm kommentiert und ich modifizierte ihn meinen Ansprüchen entsprechend.

Original Code:
Delphi-Quellcode:
//Nochmals tausend Dank an *-=[ Mika ]=-*
Function LesePort( Port : Word ) : Byte;
Const
  LPT_DataRegister = $378;
  LPT_StatusRegister = $379;
  LPT_KontrollRegister = $37A;

Var
  Value: Byte;
  Port: Word;

Begin
  // Welches Register des Statusports willst du lesen?
  Port := LPT_DataRegister

  // Werte holen aus dem Register des Ports (NUR UNTER WINDOWS 9X)
  asm
    mov dx, Port
    in al, dx
    Mov Value, AL
  end;

  // Nachsehen was gesetzt war
  case Port of
    LPT_DataRegister    : Begin
                             IF Value AND $01 = $01 then ShowMessage('Pin 1 ist gesetzt: Databit 0');
                             IF Value AND $02 = $02 then ShowMessage('Pin 2 ist gesetzt: Databit 1');
                             IF Value AND $04 = $04 then ShowMessage('Pin 3 ist gesetzt: Databit 2');
                             IF Value AND $08 = $08 then ShowMessage('Pin 4 ist gesetzt: Databit 3');
                             IF Value AND $16 = $16 then ShowMessage('Pin 5 ist gesetzt: Databit 4');
                             IF Value AND $32 = $32 then ShowMessage('Pin 6 ist gesetzt: Databit 5');
                             IF Value AND $64 = $64 then ShowMessage('Pin 7 ist gesetzt: Databit 6');
                             IF Value AND $128 = $128 then ShowMessage('Pin 8 ist gesetzt: Databit 7');
                           End;
    LPT_StatusRegister  : Begin
                             IF Value AND $08 = $08 then ShowMessage('Pin 4 ist gesetzt: ERROR');
                             IF Value AND $16 = $16 then ShowMessage('Pin 5 ist gesetzt: SELECT');
                             IF Value AND $32 = $32 then ShowMessage('Pin 6 ist gesetzt: PAPER OUT');
                             IF Value AND $64 = $64 then ShowMessage('Pin 7 ist gesetzt: ACK');
                             IF Value AND $128 = $0 then ShowMessage('Pin 8 ist gesetzt: BUSY (INVERTIERT)');
                           End;
    LPT_KontrollRegister : Begin
                             IF Value AND $01 = $00 then ShowMessage('Pin 1 ist gesetzt: STROBE (INVERTIERT)');
                             IF Value AND $02 = $02 then ShowMessage('Pin 2 ist gesetzt: AUTO FEED');
                             IF Value AND $04 = $00 then ShowMessage('Pin 3 ist gesetzt: INIT (INVERTIERT)');
                             IF Value AND $08 = $00 then ShowMessage('Pin 4 ist gesetzt: SELECT IN (INVERTIERT)');
                           End;
  end;
end;
Diesen Code kann man seinen Wünschen entsprechend anpassen (mehr oder weniger Ports abfragen usw.).
Am Besten ist man probiert einfach ein bisschen rum. Je nachdem was man machen will muss man vielleicht auch gar nichts einlesen sondern nur ausgeben... Ihr seht: Eurer Fantasie sind keine Grenzen gesetzt!

Nun ja... als nächstes müsste ich mit Win2k / NT / XP weiter machen. Wie mir von *-=[ Mika ]=-* berichtet wurde muss man lediglich einen Treiber einbinden damit der obrige Code auch dort funktioniert.
Ich möchte mich dafür entschuldigen, dass ich diesen Teil nur so hingepfuscht habe aber ich habe wirklich sehr wenig (ja ich wiederhole mich :roll:) Zeit. Der gepostete Code funktioniert bei mir tadellos und sollte so auch auf jedem anderen Win9x oder ME System laufen. So bald ich mich über das Einbinden der Treiber und deren Umgang schlau gemacht habe werde ich fortfahren.
Ich hoffe jedoch, dass ich wenigstens einigen wieder ein wenig helfen konnte.

MfG der gestresste Florian :hi:

[edit=Admin]Bild eingebettet und als Attachment entfernt. Mfg, Daniel[/edit]

Florian H 11. Jul 2003 05:56

Re: Ansteuern des Parallelports
 
Wow, super! Danke schonmal ;)
wir armen XP-User warten dann mal geduldig ;) :angle:

Gast 11. Jul 2003 08:16

Re: Ansteuern des Parallelports
 
Arme XP (i.e. NT-Plattform) Benutzer sollten sich mal mit der CreateFile() API und DeviceIoControl() auseinandersetzen. Natürlich geht das nur in einem bestimmten Kontext (zB Admin). Es handelt sich eben um ein System mit Sicherheitsmechanismen.
\??\LPT1 zeigt auf meinem System beispielsweise auf \Device\NamedPipe\Spooler\LPT1 ... ansonsten unter \Device\Parallel*
Wobei * ein generischer Platzhalter ist.

Obiges Beispiel geht zwar, aber nur von einem Treiber aus.
Aber wer weiß schon, ob die Geräte nun wirklich an diesem Port hängen, der dort hardcoded wurde?

pmc 11. Sep 2003 15:13

Re: Ansteuern des Parallelports
 
Für Alle XP und 2k user -> schaut mal HIER....

Virus3.1 9. Okt 2003 14:10

Ansteuern des Parallelports auch in Win XP möglich
 
Warum denn immer alles über Delphi ansprechen wollen. Wenn man auf das gute allte Turbo Pascal zurückgreift kann man mit den oben genannten Assembler Zeilen (In Turbo Pascal genauso einzubinden wie in Delphi über asm...end) den Com1, Com2, LPT Anschluss ansprechen, da das Projekt dann in DOS gestartet wird und man über Dos auch in Win XP auf die Ports zugreifen kann. :thuimb:

by Virus3.1

P.S.: Hab's nur unter Win XP getestet, dürfte aber auch unter Win 2k laufen.

flomei 9. Okt 2003 14:16

Re: Ansteuern des Parallelports auch in Win XP möglich
 
Zitat:

Zitat von Virus3.1
Warum denn immer alles über Delphi ansprechen wollen.

Warum? Weil das hier ein Delphi-Forum ist!!! Deshalb! Ausserdem glaube ich, dass man mit Delphi bessere GUI´s für solche Aufgaben erstellen kann als mit TP. Aber wenn du das besser weisst... mach das ruhig mit TP. Das ist sowieso die Zukunft... ;)

MfG Florian :hi:

Delphianer 10. Okt 2003 14:09

Re: Ansteuern des Parallelports
 
Sorry,

aber der (alte) Anschluß am PC ist eine 25polige Sub-D-Buchse. Und die original Centronics-Schnittstelle ist leider auch nicht die schnellste:

"Der Compatiblity Mode (auch "Centronics Mode") kann nur Daten senden, typischerweise mit 50 KB/s, in Ausnahmefällen auch mit mehr als 150 KB/s. Um Daten zu empfangen muss der Controller auf Nibble oder Byte Mode umstellen. Im Nibble Mode werden dabei 4 Bit Pakete
empfangen ("Nibbles"), während im Byte Mode die Bi-Direktionalität zum Zuge kommt und die Daten byte-weise (8 Bit) übertragen werden. Die bi-direktional fähigen Parallel-Ports bezeichnet man als SPP (Standard Parallel Port)."

von
http://www.faqs.org/faqs/de/comp/har...l_5/index.html

Grüße

flomei 10. Okt 2003 14:17

Re: Ansteuern des Parallelports
 
hm...
Die meisten Computer haben SPP. Ich habe noch keinen gesehen bei dem dies nicht so ist...

MfG Florian :hi:

Stephan N. 22. Okt 2003 11:47

Re: Ansteuern des Parallelports
 
Hallo
ich habe mal den Quelltext etwas umgeschrieben aber jetzt bringt er nur noch fehlermeldungen

Delphi-Quellcode:
Function LesePort( Port : Word ) : Byte;

implementation
Const
  LPT_DataRegister = $378;
  LPT_StatusRegister = $379;
  LPT_KontrollRegister = $37A;

Var
  Value: Byte;
  Port: Word;

function LesePort( Port : Word ) : Byte;


Begin
  // Welches Register des Statusports willst du lesen?
 // Port := LPT_DataRegister

  // Werte holen aus dem Register des Ports (NUR UNTER WINDOWS 9X)
  asm             //erklärt dem Compiler, dass Assembler Code anfängt
    mov dx, Port   //Port = 378h = die Adresse von LPT 1
    in al, dx
    Mov Value, AL
  end;


  case Port of
    LPT_DataRegister    : Begin
                             IF Value AND $01 = $01 then result:=1;
                             IF Value AND $02 = $02 then result:=2;
                             IF Value AND $04 = $04 then result:=3;
                             IF Value AND $08 = $08 then result:=4;
                             IF Value AND $16 = $16 then result:=5;
                             IF Value AND $32 = $32 then result:=6;
                             IF Value AND $64 = $64 then result:=7;
                             IF Value AND $128 = $128 then result:=8

  else result:= 0;

end;
end;
end;
end.
in der main unit um die funktion aufzurufen
Delphi-Quellcode:
a := LesePort(???)
was mus ich für ? einsetzen???

UweG. 22. Okt 2003 12:16

Re: Ansteuern des Parallelports
 
Hallo Stephan,

solltest Du den Wert des Porteingangs so abfragen

Delphi-Quellcode:
case Port of
    LPT_DataRegister    : Begin
                             IF Value AND $01 = $01 then result:=1;
                             IF Value AND $02 = $02 then result:=2;
                             IF Value AND $04 = $04 then result:=3;
                             IF Value AND $08 = $08 then result:=4;
                             IF Value AND $16 = $16 then result:=5;
                             IF Value AND $32 = $32 then result:=6;
                             IF Value AND $64 = $64 then result:=7;
                             IF Value AND $128 = $128 then result:=8

  else result:= 0;
bekommst Du als Resultat immer nur das höchstwertig gesetzte Bit zurückgegeben.

Beispiel

Value = 10010000b
Dann erfolgt bei Value AND $16 => result := 5
und bei Value AND $128 => result := 8

Die Information von Bit4 geht also verloren

Möchtest Du die Anzahl der gesetzten Bits wissen, solltest Du Result inkrementieren, ansonsten bleibt Dir nur die Übergabe des binären Wertes oder die Zuweisung an acht einzelnen Variabelen oder an ein Array oder eine Struktur.



MfG.
Uwe

:dancer2:

[edit=Christian Seehase]Delphi-Tags gesetzt. Bitte künftig selber machen. Danke. Mfg, Christian Seehase[/edit]

Nimoee 22. Okt 2003 13:15

Re: Ansteuern des Parallelports
 
Hallo,

die ganze Vorgehensweise, die du hier beschreibst ist auch für Win9x und Me extrem unsauber.
Wir befinden uns im protected mode eines intel Prozessors.
Eigentlich sind diese direkten Hardwarezugriffe nicht zulässig.
Dass sie funktionieren ist eine andere Sache.
Aber bitte sowas nicht in ein Tutorial ( auch wenns weh tut ).

Nimoee

mika 22. Okt 2003 14:26

Re: Ansteuern des Parallelports
 
olla an alle :)

@flomei: danke für das lob aber das wäre nicht nötig gewesen. ich meinte doch zu dir das das
testcode für mich war den ich ganz schnell schreiben musste um das auszuprobieren. aber ob
der code was für n tutorial taugt wage ich ein wenig zu bezweifeln. nicht böse nehmen.

@nimoee: wie würdest du es denn realisieren wenn du einzelne pins direkt setzen/lesen willst?
gibt es da noch andere funktionen für?


mfg, mika

thomasdrewermann 15. Nov 2003 07:22

Re: Ansteuern des Parallelports
 
Hallo liebe DP-Nutzer,
falls ihr Fragen oder Anregungen zu dem Tutorial von flomei habt
postet hier. Dann können auch andere User die das selbe Problem/ die
selbe Frage haben direkt hier im Forum die Lösung finden.
Andernfalls würde flomei mit E-Mails überheuft, was in letzter
Zeit der Fall war. Genau aus diesem Grund beantwortet er
Anfragen dieser Art mittlerweile garnicht mehr. Das Níchtbeantworten
hat also nichts mir personlichen Hass oder ähnlichem zu tun.

MFG
Thomas

Stephan N. 4. Feb 2004 11:23

Re: Ansteuern des Parallelports
 
Kann ich von dem kontrollregister überhaupt einlesen
also bei mir funktioniert nur das einlesen des Statusregisters


mfg Stephan

hannesburgemeister 17. Mär 2004 20:56

Re: Ansteuern des Parallelports
 
viiiiiiiiiilen dank für die kleine procedure portOut !!!!
ich suche sie schon seit wochen,
ich will ein interface ansteueren und konnte es nur in basic und turbopascal,
nun endlich auch in delphi;

ist doch ein viel schöneres arbeiten als mit basic...

meine schüler werden sich freuen

daaaanke
Hannes Burgemeister
Pauker an der
Martin-Buber-Oberschule.de
:hello:

Muetze1 22. Jan 2005 21:00

Re: Ansteuern des Parallelports
 
Moin!

Zitat:

Zitat von Capable
1. Frage

Delphi-Quellcode:
procedure PortOut(x:byte);
begin
  asm          //erklärt dem Compiler, dass Assembler Code anfängt
   mov [b]dx[/b],378h //378h ist die Adresse von LPT 1
   mov al,x   //x müssen wir noch einen Wert zuweisen
   out [b]dx[/b],al
  end;
end;
wieso wird hier zwei mal dx verwendet?

hier hingegen nicht

Delphi-Quellcode:
// Werte holen aus dem Register des Ports (NUR UNTER WINDOWS 9X)
  asm
    mov dx, Port   // 1. Verwendung DX        DX mit der Portadresse laden/füllen
    in al, dx     // 2. Verwendung DX        ein Byte von dem Port in DX auslesen und in AL schreiben
    Mov Value, AL                           // und AL in die Variable Value schreiben  
  end;

Wieso? Wird es doch auch?

Zitat:

Zitat von Capable
2. Frage

muss hier nicht hinter das port ein Out?

Ja, muss. Es wird anscheinend PortOut() angesprochen und ein Port() gibt es nicht.

Zitat:

Zitat von Capable
3. Frage

... wird hier port nicht zwei mal deklariert, bzw. der integer zugeordnet? (delphi meint: redeclaration...)

Ja, die Deklaration von Value und Port macht an der Stelle überhaupt keinen Sinnn - entferne sie einfach beide.

Zitat:

Zitat von Capable
4. Frage

bedeutet $378 das gleiche wie 378h ?

Ja, 378h bedeutet das gleiche wie $378. Wenn du in Delphi Zahlen ohne irgendwas angibst, so sind es dezimale Zahlen. Mit dem $ davor werden die Zahlen danach als hexadezimale Zahlen gewertet. Dies gilt für Delphi und Pascal - in C z.B. müsste man ein 0x vor der Zahl schreiben - aber da es so viele Sprachen gibt, gibt es auch eine allgemeine Schreibweise die einfach hinter der Zahl einen Buchstaben angibt um eine bestimmte Schreibweise zu kennzeichnen:

h = hexadezimal
d = dezimal
o = oktal
b = binär

Dies wird z.B. direkt so vom Turbo Assembler von Borland verwendet.

Zitat:

Zitat von Capable
5. Frage

muss ich bei LPT2 einfach die drei jeweils durch die 2 austauschen? also,

378 --> 278
379 --> 279
37A --> 27A

Nein, das ist nicht gesagt. Die Reihenfolge der LPT Ports und deren Adressen hängt vor allem davon ab wie sie gefunden werden vom BIOS bzw. von Windows. Parallelports können auf den folgenden Adressen zu finden sein:

3BCh, 378h, 278h und PCI Portadressen (also Portadressen > 1000h)

Bei den meisten Rechnern wo ein 2. Parallelport mit einer ISA Karte nachgerüstet ist, da wird es 278h sein. Bei solchen wo eine MDA Karte mit drinne steckt, da wird es 3BCh sein.

Zitat:

Zitat von Capable
6. Frage

wie kann ich den Wert der Variable Port aus word in einen string umwandeln und in einer showmessage darstellen?

In welcher Darstellungsform? Als Hexadezimalzahl oder als Dezimalzahl?

Delphi-Quellcode:
Begin
  ShowMessage('Portadresse: ' + IntToHex(Port, 3) + ' hexadezimal' + #13#10 +
              'Portadresse: ' + IntToStr(Port) + ' dezimal');
End;
Zitat:

Zitat von Capable
7. Frage

Code:
 // Werte holen aus dem Register des Ports (NUR UNTER WINDOWS 9X)
  asm
    mov dx, Port
 [b]in al, dx[/b]
    Mov Value, AL
  end;
wieso heißt es nicht in dx,al

Weil es so ist bei einem x86 kompatiblen Assembler und hier im Syntax von Borland. Hier ist es so festgelegt, das als erstes immer das Ziel einer Operation und danach die Quelle angegeben wird.

Code:
In Ziel, Quelle  einlesen, also ins Ziel schreiben und vom Port lesen
Out Ziel, Quelle  schreiben, also in den Port schreiben.
Genauso bei Move:

Code:
mov Ziel, Quelle
mov dx,  $378
Zitat:

Zitat von Capable
8. Frage

wieso verwendet man eine funktion und keine prozedur?

Weil eine Funktion einen Rückgabewert hat im Gegensatz zu einer Procedure. Daher gibt das PortIn() auch was zurück (den eingelesenen Wert) und PortOut() besteht aus einer Procedure, weil es nichts zurück gibt.

Den anderen Teil der 8. Frage kann dir ein anderer erklären - war genug erstmal für mich.

@flomei:

Erklär mal bitte auch, das es eine Basisadresse gibt und dann die Register immer nur ein fester Offset von dieser Basisadresse ist.

MfG
Muetze1

Capable 22. Jan 2005 21:07

Re: Ansteuern des Parallelports
 
nabend muetze,

ich danke dir vielmals für dein engagement. ich werd mich jetzt ma hinsetzen und versuchen das zu verarbeiten.

bei frage 6 war eine dezimalzahl gewünscht.

nochmals danke

gruß

capable

Capable 30. Jan 2005 11:45

Re: Ansteuern des Parallelports
 
hallo leutz,

könnt ihr mir kurz verraten, wie ich einen string in byte wandeln kann.

hintergrund:

ich möchte die variable x aus einem editfeld im formular holen.

ich danke euch!

capable

Capable 30. Jan 2005 12:24

Re: Ansteuern des Parallelports
 
editiert

Muetze1 30. Jan 2005 22:16

Re: Ansteuern des Parallelports
 
Moin!

Ein String (was in Edit1.Text steht) besteht aus einzelnen Zeichen - jedes Zeichen ist ein Byte.

Daher:

Delphi-Quellcode:
s := Edit1.Text;
For i := 1 To Length(s) Do
  DasByteDesItenZeichens := Ord( s[i] );
MfG
Muetze1

Capable 4. Feb 2005 08:11

Re: Ansteuern des Parallelports
 
ok, schauen wir mal, ob ich das halbwegs verstanden habe:

>s := Edit1.Text;

der variable s (die ich mit string deklariere) wird der wert aus dem editfeld zugeordnet.

>Length(s)

gibt bei einstelligen s den wert 1 aus und bei zweistelligen den wert 2 usw.

>For i := 1 To Length(s)

mit i (ein integer) wird von 1 bis (bsp. einstelliges s) 1 gerechnet.

>DasByteDesItenZeichens

ist auch ein integer, dem...

>Ord( s[i] );

...und jetzt steig ich nicht mehr durch. welcher wert wird der variable zugeordnet. was ist eine ordinalzahl oder ordinale position?


sorry für meine unkenntnis

Muetze1 4. Feb 2005 09:25

Re: Ansteuern des Parallelports
 
Moin!

s[i] ist das Zeichen der Zeichenkette an Position i.

Ein Zeichen ist aber ein anderer Typ als ein Byte - obwohl gleich gross und gleicher Inhalt, aber es ist ein anderer Typ. Ord() gibt dir somit den ASCII Wert des Zeichens zurück welches du übergibst - und genau dieses willst du doch auch ausgeben.

Length() - ermittelt die Länge des Strings - also Anzahl der Zeichen, ja

MfG
Muetze1

Capable 7. Feb 2005 21:08

Re: Ansteuern des Parallelports
 
so, ich hab etwas rumprobiert, komm aber zu keinem ergebnis. könnt ihr mir sagen, wo der fehlerteufel steckt?

Delphi-Quellcode:
editiert
es passiert schlichtweg gar nichts.

Muetze1 7. Feb 2005 21:37

Re: Ansteuern des Parallelports
 
Moin!

Warum sollte auch?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Port:Word;
begin
  LesePort(Port);
end;
Du definierst dir die lokale Variable Port, weisst ihr nirgendwo einen Wert zu und dann übergibst du diese an die LesePort() Funktion? Wovon soll sie denn nun lesen? bisher tut sie dieses von irgendwelchen Ports, nur nicht denen die du meinst.

Delphi-Quellcode:
procedure TForm1.RadioGroup1Click(Sender: TObject);
var
  Port:Word;
begin
  Port:=$279;
 
  case RadioGroup1.ItemIndex of
    0 : Port := $278;
    1 : Port := $279;
    2 : Port := $27A;
  end;
end;
Hier gleiches - so eine schöne Auswahl, aber alles wird einer lokalen Variable zugewiesen. Wozu?

Alle lokalen Variablen (also in einer Procedure definierten Variablen) haben beim Eintritt in die Procedure zufällige Werte und müssen daher initialisiert werden um benutzt zu werden. Ansonsten spielst du Lotto...
Und: lokale Variablen werden mit dem Verlassen (am Ende dieser bzw. ein Exit) der Procedure ungültig und verlieren ihren Inhalt.

MfG
Muetze1

Capable 7. Feb 2005 23:40

Re: Ansteuern des Parallelports
 
morgen muetze,

schön, dass du mir wieder hilfst.
also ich hab schon verstanden. die variable, die ich in der einen procedur deklariere, wird in der anderen nicht wieder erkannt, da lokal.

ich überleg mir später, wie ich das mit der radiogroup mache. aber mein problem besteht auch nicht wirklich darin.

es passiert auch sonst nichts. in der zwischenzeit hab ich mir mal die mühe gemacht alle werte anzupassen, doch funktionieren tut nichts

Delphi-Quellcode:
edit

BRunner77 8. Feb 2005 10:20

Re: Ansteuern des Parallelports
 
Moin!

1. Definiere Port in deiner Form

2. Ist die Portadresse 278h die richtige?

3. Warum fragst du die Bits mit
Delphi-Quellcode:
 Value And $64 = $64
ab? Damit fragst du gleich mehrere Bits ab - weil die Zahlen die du verwendest müssten dezimal angegeben werden damit es einzelne gesetzte Bits sind (siehe Taschenrechner von Windows: dezimal eingeben -> binäre Darstellung; hexadezimal eingeben -> binäre Darstellung (vorher in den wissenschaftlichen Modus des Taschenrechners umschalten)).

MfG
Muetze1

// UPS, falscher Account - naja, egal, kommt ja auf den Inhalt an...

Capable 8. Feb 2005 15:34

Re: Ansteuern des Parallelports
 
Zitat:

Zitat von BRunner77
Moin!

moin muetze,

Zitat:

1. Definiere Port in deiner Form
das hab ich mittlerweile hinbekommen.

Zitat:

2. Ist die Portadresse 278h die richtige?
ja, so steht es in der systemsteuerung von windows 98se

Zitat:

3. Warum fragst du die Bits mit
Delphi-Quellcode:
 Value And $64 = $64
ab? Damit fragst du gleich mehrere Bits ab - weil die Zahlen die du verwendest müssten dezimal angegeben werden damit es einzelne gesetzte Bits sind (siehe Taschenrechner von Windows: dezimal eingeben -> binäre Darstellung; hexadezimal eingeben -> binäre Darstellung (vorher in den wissenschaftlichen Modus des Taschenrechners umschalten)).
ganz einfach: so steht es im beispiel aus der ersten seite dieses threads.
das problem ist, dass ich eben erst ein halbes jahr delphi-kurs hinter mir habe und den hintergrund oft noch nicht verstehe.

was du mir sagen willst ist, dass ich

$16 in $10
$32 in $20
$64 in $40
$128 in $80

abändern soll, oder?

weil die dezimalzahlen umgewandelt in hexadezimalen?

um ehrlich zu sein verstehe ich die funktion der ganzen zeile

Delphi-Quellcode:
 IF Value AND $01 = $01 then ShowMessage('Pin 1 ist gesetzt: Databit 0');
nicht.

hm, ist wirklich nicht so einfach, wie ich mir das vorgestellt habe. ich kämpfe gerade mit 2 dicken büchern und massig internet infos (meist in englisch).

Muetze1 8. Feb 2005 15:57

Re: Ansteuern des Parallelports
 
Moin!

Zitat:

Zitat von Capable
was du mir sagen willst ist, dass ich

$16 in $10
$32 in $20
$64 in $40
$128 in $80

abändern soll, oder?

Ganz genau - es wurden die richtigen Zahlen genommen, aber leider wurden sie mit dem $ davor zu hexadezimalzahlen und damit wieder falsch.

Delphi-Quellcode:
 IF Value AND $01 = $01 then ShowMessage('Pin 1 ist gesetzt: Databit 0');
Der Wert Value beinhaltet ein Wert und dieser wird durch die unterschiedlichen Bits dargestellt. Um abzufragen ob einzelne Bits gesetzt sind oder nicht maskiert man sie aus. Dies geschieht durch eine binäre UND Verknüpfung. Dabei verknüpft man den Wert mit einer Maske. Bei einer UND Verknüpfung ist es so, dass nur die Bits gesetzt bleiben die auch in der Maske gesetzt sind - alle anderen werden auf 0 gesetzt. Und wenn nun in deinem Value das Bit 0 und Bit 1 gesetzt ist (Value = 3) und du eine UND Verknüpfung mit einem gesetzten Bit 0 und Bit 2 machst (5), dann wird Bit 0 und Bit 2 unverändert gelassen bei dem Wert und alle anderen Bits werden auf 0 gesetzt. Somit kannst du danach abfragen ob das Ergebnis <> 0 ist, was dann bedeutet das entweder Bit 0 oder Bit 2 gesetzt ist - oder beide.

Delphi-Quellcode:
     0000 0001b
AND 0000 0001b
=   0000 0001b

     0101 0101b
AND 1100 0011b
=   0100 0001b
Im Ergebnis sind immer nur die Bits gesetzt die in beiden Werten gesetzt sind - Wert und Maske. Daher auch UND ...

Die obige Abfrage in Delphi macht folgendes: Sie führt eine binäre UND-Verknüpfung mit dem Wert aus und einer Maske wo nur Bit 0 gesetzt ist. Danach fragt sie ab, ob das Ergebnis dieser Verknüpfung ein Wert mit gesetztem 0. Bit ist - alle anderen Bits können nicht mehr gesetzt sein. So gehen alle anderen IF Anweisungen auch vor - sie führen diese UND Verknüpfung durch - nacheinander für Bit 0, Bit 1, Bit 2, Bit 3, Bit 4, etc

@flomei:
Zitat:

Zitat von Muetze1
@flomei:

Erklär mal bitte auch, das es eine Basisadresse gibt und dann die Register immer nur ein fester Offset von dieser Basisadresse ist.

Und bitte die Bit Abfrage korrigieren, also nicht
Delphi-Quellcode:
If ( Value And $64 ) = $64 Then
sondern
Delphi-Quellcode:
If ( Value And 64 ) = 64 Then
oder die richtigen Hexadezimalwerte dafür nutzen ($01, $02, $04, $08, $10, $20, $40, $80).

MfG
Muetze1

Capable 20. Feb 2005 16:45

Re: Ansteuern des Parallelports
 
hallo muetze,

kannst du mir vielleicht noch mal helfen?

ich verstehe nicht, wieso die variablen control, data und status nicht von den anderen prozeduren erkannt werden.

ich hab sie doch deklariert und auf unter private reingeschrieben. trotzdem kommt bei showmessage für alle drei "0".

ich suche schon seit stunden nach dem fehler, stehe aber auf dem schlauch. bitte bemühe dich doch noch mal kurz. danke!

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    RadioGroup1: TRadioGroup;
    RadioGroup2: TRadioGroup;
    procedure Button1Click(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
    procedure RadioGroup2Click(Sender: TObject);
  private
    { Private declarations }
  j:byte;
  Data,Status,Control:Word;
  public
    { Public declarations }

  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.RadioGroup1Click(Sender: TObject);

var Data,Status,Control:Word;

begin

  case RadioGroup1.ItemIndex of 0 : begin
                                    Data    := $378;
                                    Status  := $379;
                                    Control := $37A;
                                    end;

                                1 : begin
                                    Data    := $278;
                                    Status  := $279;
                                    Control := $27A;
                                    end;

  end;
end;

procedure TForm1.RadioGroup2Click(Sender: TObject);      //j sei die Fahrregleradresse

begin

  case RadioGroup2.ItemIndex of 0 : begin
                                    j:=$E0;
                                    end;

                                1 : begin
                                    j:=$E1;
                                    end;

                                2 : begin
                                    j:=$E2;
                                    end;

                                3 : begin
                                    j:=$E3;
                                    end;
  end;
end;



procedure ControlOut;

var Control:word;

begin

    asm          //erklärt dem Compiler, dass Assembler Code anfängt
    mov dx,Control
    mov al,4
    out dx,al
    end;

end;

procedure DataOut(j:byte);

var Data:word;

  begin
    asm          //erklärt dem Compiler, dass Assembler Code anfängt
    mov dx,Data
    mov al,j
    out dx,al
    end;

end;



procedure TForm1.Button1Click(Sender: TObject);

 begin

 ControlOut;
 DataOut(j);
 showmessage(inttostr(j));
 showmessage(inttostr(Control));
 showmessage(inttostr(Status));
 showmessage(inttostr(Data));

 end;

end.

Muetze1 20. Feb 2005 17:38

Re: Ansteuern des Parallelports
 
Moin!

Es ist schön deklariert im private Abschnitt der Form, aber wenn du die Variablen mit gleichen Namen nochmals deklarierst in der RadioGroup1Click(), dann nutzt der Compiler natürlich diese. Diese Variablen sind aber lokal in der Procedure definiert und haben nix mit denen in der Klasse zu tun.

Mit anderen Worten: Lösche die Deklaration der Variablen in der RadioGroup1Click() Methode.

MfG
Muetze1

Capable 23. Feb 2005 12:46

Re: Ansteuern des Parallelports
 
hallo muetze,

also folgendes: ich möchte den variablen data, status und control einfach die verschiedenen adressen, entsprechend, ob der programmbenutzer lpt1 oder lpt2 nutzen will, zuordnen.

wie bekomme ich es also hin, dass die werte, die ich den drei variablen zuordne im ganzen form erkannt werden?

oder ist da eine ganz andere vorgehensweise zu empfehlen? vielleicht indem ich einfach in den einzelnen prozeduren schreibe

if radiogroup1.itemindex = 1 do begin... ?

danke dir noch einmal

Muetze1 23. Feb 2005 16:34

Re: Ansteuern des Parallelports
 
Moin!

Lese dir erstmal ein Grundlagen Tutorial durch und eins über Klassen, sonst kommen wir hier nicht weiter...

Ein letzter Versuch, dann gebe ich auf:

RadioGroup1Click() ist eine Methode der TForm1 und hat damit Zugriff auf die Variablen und Eigenschaften der Klasse TForm1. Wenn also nun die Klasse TForm1 Variablen Namens Data, Status und Control definiert hat, dann sind sie in der Methode gültig. Wenn du nun aber auf die durchaus witzige Idee kommst Variablen mit gleichen Namen nochmals lokal in der Procedure zu deklarieren, dann haben diese eine höhere Wertigkeit im Scope (Bereich) der lokalen Funktion und Zugriffe auf Variable mit den Namen werden dann auf die lokalen Variablen ausgeführt anstatt auf die Klassenvariablen.

Also zum zweiten Male: entferne die Deklaration der Variablen Data, Status und Control aus der RadioGroup1Click().

MfG
Muetze1

izzi 31. Mär 2005 11:55

Re: Ansteuern des Parallelports
 
Hallo erstmal an alle!

Der Zugriff unter WIN XP ist wie schon alle mitbekommen haben nicht so ohne weiteres möglich.
Das Problem hatte ich auch.

Unter WIN XP gibt es aber die möglichkeit, das Programm im Kompalibitätsmodus laufen zu lassen.

Das heißt: Man klickt mit der rechten Maustaste auf die *.exe die man im Kompabilitätsmodus laufen lassen will. Danach auf Registerkarte Kompabilität und anschließend den Modus einstellen.

Nun läuft das Programm wie unter WIN 95, 98 oder 2000 oder eben XP.

Das alles übernehmen und das Programm starten.

Keine Fehlermeldung mehr von wegen PREVILIGIERTE ANWEISUNG:

Viel Spaß beim Ansteuern des LPT.

BYE

Muetze1 31. Mär 2005 13:26

Re: Ansteuern des Parallelports
 
Moin!

Zitat:

Zitat von izzi
Hallo erstmal an alle!

Der Zugriff unter WIN XP ist wie schon alle mitbekommen haben nicht so ohne weiteres möglich.
Das Problem hatte ich auch.

Unter WIN XP gibt es aber die möglichkeit, das Programm im Kompalibitätsmodus laufen zu lassen.

Das heißt: Man klickt mit der rechten Maustaste auf die *.exe die man im Kompabilitätsmodus laufen lassen will. Danach auf Registerkarte Kompabilität und anschließend den Modus einstellen.

Nun läuft das Programm wie unter WIN 95, 98 oder 2000 oder eben XP.

Das alles übernehmen und das Programm starten.

Keine Fehlermeldung mehr von wegen PREVILIGIERTE ANWEISUNG:

Viel Spaß beim Ansteuern des LPT.

BYE

Super! Toll! Und? Was haben wir nun? eine immernoch illegale Anwendung die illegalerweise direkt auf die Hardware versucht zu zu greifen, Windows dazwischenfunkt, etc.

Also, wenn, dann nutze die WinAPI die einem die Möglichkeiten bietet um die parallele Schnittstelle ordentlich anzusprechen. Nutze die Routinen und es läuft auf allen 32bit Windowsversionen, du machst dir nicht dein ZIP am Parellelport kaputt und der Drucker druckt auch keine komischen Zeichen. Auch das Bus System wie es das ZIP Laufwerk benutzt am Parallelport wird ordentlich unterstützt.

Warum versuchen immer alle am Problem drumherum zu manschen anstatt das Problem an der Wurzel zu packen und dort zu lösen?

MfG
Muetze1

dragi 23. Apr 2005 02:41

Re: Ansteuern des Parallelports
 
@Muetze1 und auch sonst alle die sich auskennen:

Gibt es denn irgendwo ein Beispiel wie man dn Parallelport mit der WinApi anspricht? Ich habe leider noch nicht das Wissen die sachen aus dem SDK nach Delphi zu übertragen und bin nun auch an dem Punkt an dem ich den Parallelport ansprechen möchte :(

Gruss

Dragi

mallowd 31. Mär 2006 13:05

Re: Ansteuern des Parallelports
 
io.dll ist echt supi ^^ habe mich auch zuerst gewundert, warum der assemblercode nicht unter xp läuft, aber dann die erklärung und erlösung :firejump: :corky: :hello:

Cyberbob 8. Okt 2006 21:01

Re: Ansteuern des Parallelports
 
Sorry, das ich das Thame nochmal hervorhole...

Ich habe einen Laptop ohne Parallele Schnittstelle. Ich habe allerdings einen USBtoLPT-Adapter, unter welchem Port, muss ich den ansprechen. Ich habe alle hier genannten ausprobiert, doch er reagiert in keinster weise!
Geht das überhaupt?

Gruss
Christian


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz