Rubrik: Verschiedenes | VB-Versionen: VB5, VB6 | 15.02.05 |
Ansteuerung des LPT-Port Heute wollen wir uns einmal mit der parallelen Schnittstelle (LPT-Port) befassen. Das Steuern von Hardware ist eigentlich gar nicht so schwer. Das größte Problem bereitet immer die Bitinvertierung... | ||
Autor: Thomas Gollmer | Bewertung: | Views: 56.572 |
Heute wollen wir uns einmal mit der parallelen Schnittstelle (LPT-Port) befassen. Das Steuern von Hardware ist eigentlich gar nicht so schwer. Das größte Problem bereitet immer die Bitinvertierung...
Wenn man von der normalen Computerlogik ausgeht muss ein Ausgang des LPT-Port auf High=1=5 Volt gehen und wenn eine 0=Low ausgegeben wird sollte der Ausgang auf Masse (GND) liegen. Dies ist nun leider beim LPT-Port nicht bei allen Ausgängen der Fall, aber dazu können wir dieses Modul verwenden. Wenn ein Ausgang auf Low gehen soll müssen wir nur an die entsprechenden Funktionen eine 0 bzw False übergeben. Analog verhält es sich mit den Eingängen. Die Funktionen liefern eine 0=False=Low zurück, wenn der Eingang von außen auf GND gelegt wird. Liegen an einem Eingang 5 Volt an so geben die Funktionen High=1= True zurück. Gleiches gilt auch wenn der Eingang "in der Luft hängt", also keine Verbindung zu einem Signal besteht.
Praktisches Beispiel: Ein Taster wird mit den LPT-Pins 15 und 18-25 verbunden. Ist der Taster nicht gedrückt bekommen wir von den Funktionen eine 1=High=True zurück. Sobald der Taster gedrückt wird, wird der Eingang mit GND verbunden und die Funktionen liefern eine 0=Low=False. Natürlich brauchen wir für die Kommunikation mit der Hardware eine DLL. In diesem Beispiel wird die inpout32.dll genutzt, die es recht häufig im Netz zu finden gibt.
Logix4u: Inpout32.dll for WIN NT/2000/XP
So nun geht's los...
Den nachfolgenden Code in einem Modul plazieren
Option Explicit ' API Funktionen der InpOut32.dll Private Declare Function Inp Lib "inpout32.dll" Alias "Inp32" ( _ ByVal PortAdress As Integer) As Integer Public Declare Sub Out Lib "inpout32.dll" Alias "Out32" ( _ ByVal PortAdress As Integer, _ ByVal Value As Integer)
Die Zuordnung der LPT-Pins (25 pol. Sub-D Anschluss) zu den Signalen und Ports
Wir haben mit dem Code nun Folgende Ein-, Ausgänge zur Verfügung:
DatenPort und KontrollPort = 12 Ausgänge InputPort = 5 Eingänge
Die Bidirektionale Funktion des Datenport wird hier nicht genutzt
' Signalname | LPT-Pin | BitNr | Portname ' -------------------------------------------- ' Data0 | 2 | 0 | DatenPort ' Data1 | 3 | 1 | DatenPort ' Data2 | 4 | 2 | DatenPort ' Data3 | 5 | 3 | DatenPort ' Data4 | 6 | 4 | DatenPort ' Data5 | 7 | 5 | DatenPort ' Data6 | 8 | 6 | DatenPort ' Data7 | 9 | 7 | DatenPort ' -------------------------------------------- ' Strobe | 1 | 0 | KontrollPort ' AutoFdx | 14 | 1 | KontrollPort ' InitPrnt | 16 | 2 | KontrollPort ' SlctInp | 17 | 3 | KontrollPort ' -------------------------------------------- ' Err | 15 | 3 | InputPort ' Slct | 13 | 4 | InputPort ' PE | 12 | 5 | InputPort ' Ack | 10 | 6 | InputPort ' Busy | 11 | 7 | InputPort ' -------------------------------------------- ' GND | 18-25 | - | Masse ' --------------------------------------------
Die Adressen für die jeweiligen Ports:
- Bei LPT1 ist die Basisadresse (DatenPort) = &h378
- Bei LPT2 ist die Basisadresse (DatenPort) = &h278
- Bei mehr als 2 LPT-Anschlüssen am PC sind die Adressen verschoben und die Basisadressen müssen der Systemsteuerung entnommen werden
- Die Adresse des InputPort ist IMMER Basisadresse + 1
- Die Adresse die KontrollPort ist IMMER Basisadresse + 2
Public Enum LPT LPT1 = &H378 LPT2 = &H278 End Enum
Als nächstes die Aufzählungen der LPT-Pins und deren BitNummern (siehe Oben)
Es können bei Funktionsaufrufen die PinNummern, BitNummern oder SignalNamen verwendet werden
Public Enum LPT_Daten_Pin ' Als PinNummer Pin2 = 0 Pin3 = 1 Pin4 = 2 Pin5 = 3 Pin6 = 4 Pin7 = 5 Pin8 = 6 Pin9 = 7 ' Als SignalName Data0 = 0 Data1 = 1 Data2 = 2 Data3 = 3 Data4 = 4 Data5 = 5 Data6 = 6 Data7 = 7 End Enum Public Enum LPT_Kontroll_Pin ' Als PinNummer Pin1 = 0 Pin14 = 1 Pin16 = 2 Pin17 = 3 ' Als SignalName Strobe = 0 AutoFdx = 1 InitPrnt = 2 SlctInp = 3 End Enum Public Enum LPT_Input_Pin ' Als PinNummer Pin15 = 3 Pin13 = 4 Pin12 = 5 Pin10 = 6 Pin11 = 7 ' Als SignalName Err = 3 Slct = 4 PE = 5 Ack = 6 Busy = 7 End Enum ' Zur Zwischenspeicherung der Ausgangszustände und des Ports Private oldDaten As Byte Private oldKontroll As Byte Private Basisadresse As Integer
Beim Schreiben & Lesen werden die Bitinvertierungen terminiert. Somit bekommt man an jedem Ausgang 5 Volt, wenn an die Funktionen ein True/Ein/1 übergeben wird. Bei den Eingängen verhält es sich analog.
MSB = Most Significant Bit = Höchstwertiges Bit = Bit7 = 1.Stelle bei Strings LSB = Least Significant Bit = Nierdertigstes Bit = Bit0 = 8.Stelle bei Strings
Hier nun erst einmal die grundlegenden Ein- und Ausgabefunktionen
Public Sub Init_LPT(DruckerPort As LPT, _ Optional DatenByte As Byte = 0, _ Optional KontrollByte As Byte = 0) ' Diese Funktion muß als erstes aufgerufen werden ' hiermit werden alle Ausgänge des LPT Ports auf GND (0) gelegt ' Optional können andere Ausgangswerte angegeben werden Basisadresse = DruckerPort Schreibe_DatenByte DatenByte Schreibe_KontrollByte KontrollByte End Sub
Public Sub Schreibe_DatenByte(ByVal Wert As Byte) ' Dieser Sub gibt ein Byte am DatenPort aus Dim Ausgabe As Integer Dim Port As Integer oldDaten = Wert Port = CInt(Basisadresse) Ausgabe = Wert Out Port, Ausgabe End Sub
Public Sub Schreibe_KontrollByte(ByVal Wert As Byte) ' Dieser Sub gibt ein Byte am KontrollPort aus Dim Ausgabe As Integer Dim Port As Integer oldKontroll = Wert Port = CInt(Basisadresse) + 2 Ausgabe = Wert Or 32 Ausgabe = Ausgabe Xor 43 Out Port, Ausgabe End Sub
Public Function Lese_InputByte() As Byte ' Diese Funktion liefert ein am InputPort gelesenes Byte zurück ' Die Bits 0,1,2 sind unbenutzt und werden immer als 1 = gesetzt zurückgegeben Dim Ausgabe As Integer Dim Port As Integer Port = CInt(Basisadresse) + 1 Ausgabe = Inp(Port) ' Bit7 muß invertiert werden & die 3 LSB auf 1 setzen If Ausgabe >= 128 Then Ausgabe = Ausgabe - 128 Else Ausgabe = Ausgabe + 128 Ausgabe = Ausgabe Or 7 Lese_InputByte = CByte(Ausgabe) End Function
Da man nicht immer Byte-Werte auf die Ports schreiben will bzw. Byte Werte zurückerhalten möchte, erstellen wir Funktionen, die uns ein Arbeiten mit Strings in Binärform erlauben.
Public Sub Schreibe_DatenString(ByVal Wert As String) ' Dieser Sub gibt ein Byte am DatenPort aus ' Der Übergabewert ist ein String aus 8 Zeichen mit 0en und 1en ' welche als Binärwerte interpretiert werden ' das Erste Zeichen ist das MSB das letzte Zeichen das LSB Dim Ausgabe As Byte Ausgabe = String2Byte(Wert) Schreibe_DatenByte Ausgabe End Sub
Public Sub Schreibe_KontrollString(ByVal Wert As String) ' Dieser Sub gibt ein Byte am KontrollPort aus ' Der Übergabewert ist ein String aus 8 Zeichen mit 0en und 1en ' welche als Binärwerte interpretiert werden ' das Erste Zeichen ist das MSB das letzte Zeichen das LSB Dim Ausgabe As Byte Ausgabe = String2Byte(Wert) Schreibe_KontrollByte Ausgabe End Sub
Public Function Lese_InputString() As String ' Diese Funktion liefert ein am InputPort gelesenes Byte in StringForm zurück ' Das MSB ist das erste und das LSB das letzte Zeichen ' Die Bits 0,1,2 sind unbenutzt und werden immer als 1 = gesetzt zurückgegeben Dim Ausgabe As Byte Dim AusString As String Ausgabe = Lese_InputByte AusString = Byte2String(Ausgabe) Lese_InputString = AusString End Function
Private Function String2Byte(ByVal Wert As String) As Byte ' Diese Funktion wandelt einen 8 Zeichen String mit 0en & 1en ' in ein Byte. Im String ist das MSB das erste und LSB das letzte Zeichen Dim zähler As Integer Dim Ausgabe As Byte For zähler = 0 To 7 If Mid$(Wert, zähler + 1, 1) = "1" Then Ausgabe = Ausgabe + 2 ^ (7 - zähler) End If Next String2Byte = Ausgabe End Function
Private Function Byte2String(ByVal Wert As Byte) As String ' Diese Funktion wandelt ein Byte in einen String um ' Im String ist das MSB das erste und das LSB das letzte Zeichen Dim zähler As Integer Dim Ausgabe As String For zähler = 7 To 0 Step -1 If Wert >= 2 ^ zähler Then Ausgabe = Ausgabe & "1" Wert = Wert - 2 ^ zähler Else Ausgabe = Ausgabe & "0" End If Next Byte2String = Ausgabe End Function
Um die Schreib- und Leseaktivitäten nicht immer mit ganzen Bytes oder Strings durchführen zu müssen... noch ein paar Funktionen zum Prüfen einzelner Eingänge oder Schalten einzelner Ausgänge ohne die Zustände der anderen Ein-, Ausgänge zu verändern/berücksichtigen.
Public Function Lese_InputBit(Pin As LPT_Input_Pin) As Boolean ' Diese Funktion prüft ob das übergebene Bit auf High liegt (5Volt) ' und gibt ein True zurück wenn dem so ist. Liegt der Eingang auf Low ' wird False zurückgegeben Dim Ausgabe As String Dim Position As Integer Dim Rückgabe As Boolean Position = 8 - Pin Ausgabe = Lese_InputString If Mid$(Ausgabe, Position, 1) = "1" Then Rückgabe = True Else Rückgabe = False Lese_InputBit = Rückgabe End Function
Public Sub Schreibe_KontrollBit(Pin As LPT_Kontroll_Pin, Ein As Boolean) ' Dieser Sub schaltet einen Ausgangspin des Kontrollport auf High (5Volt) ' wenn Ein = True, bei Ein = False wird das Pin auf GND (0Volt) gelegt ' Alle anderen Ausgänge des Kontrollport bleiben unverändert Dim Ausgabe As Byte Ausgabe = 2 ^ Pin Ausgabe = oldKontroll Or Ausgabe If Ein = False Then Ausgabe = Ausgabe Xor 2 ^ Pin Schreibe_KontrollByte Ausgabe End Sub
Public Sub Schreibe_DatenBit(Pin As LPT_Daten_Pin, Ein As Boolean) ' Dieser Sub schaltet einen Ausgangspin des Datenport auf High (5Volt) ' wenn Ein = True, bei Ein = False wird das Pin auf GND (0Volt) gelegt ' Alle anderen Ausgänge des Kontrollport bleiben unverändert Dim Ausgabe As Byte Ausgabe = 2 ^ Pin Ausgabe = oldDaten Or Ausgabe If Ein = False Then Ausgabe = Ausgabe Xor 2 ^ Pin Schreibe_DatenByte Ausgabe End Sub
Hier nun ein paar Beispiele:
Private Sub Command1_Click() ' Schnitstelle initialisieren Init_LPT LPT1 ' Alle Ausgänge des DatenPort einschalten Schreibe_DatenByte 255 ' Im DatenPort BitNr4=Data4=Pin6 auf Low=GND=0=False schalten ohne ' die anderen Ausgänge zu verändern Schreibe_DatenBit Data4, False ' Prüfen ob im Inputport das BitNr5=PE=Pin12 auf Low=GND=0=Flase liegt If Lese_InputBit(PE) = False Then Debug.Print "Eingang liegt auf Masse" Else Debug.Print "Eingang liegt auf 5 Volt oder ist nicht angeschlossen" End If ' Im Kontrollport die Bits 0 und 3 setzen, restliche Ausgänge = 0 Schreibe_KontrollString "00001001" End Sub
Hinweis:
VOR dem Ausprobieren der Beispiele sollte ein vorhandener Drucker (sofern am LPT-Port angeschlossen) abgeklemmt werden, da dieser u.U. die Signale als Befehle interpretiert.