vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#

https://www.vbarchiv.net
Rubrik: Verschiedenes   |   VB-Versionen: VB5, VB615.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 GollmerBewertung:  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.
 



Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
 
Copyright ©2000-2024 vb@rchiv Dieter OtterAlle Rechte vorbehalten.


Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.