DevTrain Startseite Advanced Developers Conference vom 14.-15. Februar 2011  
  
  
SUCHEN:  
ARTIKEL ONLINE: 525   

Kategorien
.NET
Datenbanken
Web
XML

Allgemein
Camp
Foren
Events
Persönliche Einstellungen
Registrieren
Prämien Shop
Kontakt
Impressum
Über DevTrain

Autoren


   Autor: Hannes Preishuber Artikel Drucken
        
per API einen COM Port öffnen

Nachdem wir bereits im ersten Teil die nötigen Funktionen der API für die RS232 eingebunden haben, geht es nun an die Umsetzung. Die Schwierigkeit steckt weniger in der Programmierung mit VB .NET sondern mehr im tiefen Wissen um die API Funktionen.
Für die ersten Schritte, werden wir minimalistisch vorgehen. Zunächst muss die Schnittstelle geöffnet werden. dafür
implementieren wir eine Funktion Open. Dieser übergeben wir per Parameter alle nötigen Informationen.
Port Schnittstelle als Ganzzahl
Geschwindigkeit in Boud (z.B. 9600)
Datenbits Anzahl der Datenbits ( Typischerweise 8)
Parität (Typischerweise N für none, hier als 0)
Stopbit Anzahl der Stopbits als Ganzzahl
Buffergröße des IO Buffers
Diese Vorgehensweise bringt einige Nachteile mit sich. Vor allem, das alle Parameter korrekt gesetzt werden müssen. Optionale Parameter sind unter VB .NET nicht mehr möglich. So müsste die Funktion Open mehrfach überladen werden, was hier einen erhebelichen Coding Aufwand bedeutet.
Alternativ könnte man auch in der generellem Klasse Propertys verwenden um die Schnittstelle zu setzen. Dazu muss aber auch für jede Eigenschaft der Code über SET und GET implementiert werden zum lesen und schreiben.
Zunächst wird über Createfile ein Handle auf die Schnittestelle erzeugt. Die Fehlerbehandlung ist and dieser Stelle nur
Ansatzweise implementiert. Die Hexzahlen (&H80000000) geben den Schreib- und Lese Modus an.
Der 5te Parameter bewirkt, das ein offner Port nichmals geöffnet wird.
Wenn dann alles gut gegangen ist, ist der Handle gesetzt. Aufbauend auf diesem Handle wird der Buffer und die Errors gelöscht. Jede Funktion liefert einen Rückgabewert, der im Fehlerfalle, wenn Catch zuschlägt, ausgegeben werden kann.
Erst nachdem der Port offen ist, kann er mit den Settings versorgt werden. Dazu wird aus den Parametern ein String gebildet.
Über die API Funktion BuildComDCB wird damit eine Struktur gefüllt. Diese ist weiter unten im Text definiert.
Mit diesem Objekt wird über SetCommstate die Schnittstelle initialisiert. Im vorerst letzten Schritt werden noch die
Buffergröße und der Timeoput gesetzt. Wobei die Funtkion comSettimeout nicht aus der API kommt, sondern weiter unten definiert ist.
Public Sub Open(ByVal iPort As Int16, ByVal ioSpeed As Integer, ByVal ioData As Int16, ByVal ioParity As Int16, ByVal ioStop
As Int16, ByVal comBufferSize As Integer)
   Dim uDCB As DCB, iResult As Int32
   Try
      hCOMM = CreateFile("COM" & iPort.ToString, _
              &H80000000 Or &H40000000, 0, 0, _
             3, 0, 0)
      If hCOMM <> -1 Then
                    Dim sCOMSettings As String
                    iResult = ClearCommError(hCOMM, ErrCode, 0&) 'Fehler löschen
                    iResult = PurgeComm(hCOMM, PurgeBuffers.RXClear Or PurgeBuffers.TxClear) 'Buffer löschen
                    iResult = GetCommState(hCOMM, uDCB) 'Setting von COM`?
                    ' Port Settings
                    sCOMSettings = ioSpeed & "," & ioParity & "," & ioData.ToString & "," & CInt(ioStop).ToString
                    iResult = BuildCommDCB(sCOMSettings, uDCB)
                    iResult = SetCommState(hCOMM, uDCB)
                    iResult = SetupComm(hCOMM, comBufferSize, comBufferSize) 'Buffer setzen
                    comSetTimeout(100) 'Timeout Struktur sezen
       Else
                    ' Fehler werfen
       End If
       Catch Ex As Exception
                 'allgemeiner Fehler
       End Try
End Sub
Für ein sauberes Arbeiten gehört natürlich auch noch das Schliessen des Ports dazu. Hier wird einfach die API Funktion gekapselt.
Public Sub Close()
            If hCOMM <> -1 Then
                CloseHandle(hCOMM)
                hCOMM = -1
            End If
End Sub
Es folgt die Struktur für die Rückgabe der API Funktion BuildCommDCB. Die Anregung zur Erstellung ist wiederum aus der Platform SDK übernommen.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/hardware/commun_965u.asp
Da nicht alle Eingeschaften benötigt werden kann man diese aus der Struktur weglassen. Wichtig ist nur, das der Name der Struktur identisch ist.
<StructLayout(LayoutKind.Sequential, Pack:=1)> Private Structure DCB
            Private DCBlength As Int32
            Private BaudRate As Int32
            Private Bits1 As Int32
            Private wReserved As Int16
            Private XonLim As Int16
            Private XoffLim As Int16
            Private ByteSize As Byte
            Private Parity As Byte
            Private StopBits As Byte
            Private XonChar As Byte
            Private XoffChar As Byte
            Private ErrorChar As Byte
            Private EofChar As Byte
            Private EvtChar As Byte
            Private wReserved2 As Int16
End Structure
 
Die Funktion comSetTimeout kapselt die API Funktion SetCommTimeouts. Dies ist von Vorteil, da als Parameter eine komplexere Struktur benötigt wird. Diese ist auch weiter unten definiert.
Private Sub comSetTimeout(ByVal comTimeout As Int16)
            Dim uCtm As COMMTIMEOUTS
            If hCOMM = -1 Then
                Exit Sub
            Else
                With uCtm
                    .ReadIntervalTimeout = 0
                    .ReadTotalTimeoutMultiplier = 0
                    .ReadTotalTimeoutConstant = comTimeout
                    .WriteTotalTimeoutMultiplier = 10
                    .WriteTotalTimeoutConstant = 100
                End With
                SetCommTimeouts(hCOMM, uCtm)
            End If
End Sub
Die Idee zur Strukur kommt wieder über die Spezifikationen der API aus der Platform SDK
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/hardware/commun_9tgy.asp
<StructLayout(LayoutKind.Sequential, Pack:=1)> Private Structure COMMTIMEOUTS
            Public ReadIntervalTimeout As Int32
            Public ReadTotalTimeoutMultiplier As Int32
            Public ReadTotalTimeoutConstant As Int32
            Public WriteTotalTimeoutMultiplier As Int32
            Public WriteTotalTimeoutConstant As Int32
End Structure

So bisher haben wir schon sehr viel geleistet, aber noch keine Ergebnisse am Tisch. Im nächsten Teil beschäftigen wir uns mit dem schreiben und lesen von Daten auf die Seriellen Schnittstelle.
Ein paar Dinge wie z.B. die Art der Strukutrdefinition wurden hier nicht erläutert. Ich kann zum Studium folgende Links empfehlen:

Namespace System.Runtime.InteropServices
 
 
 

DevTrain Camp - Schneller zum .NET 3.5 Developer
 
Verwandte Artikel      Verlinkte Dokumente
    Keine Links vorhanden

  Erfasst am: 20.02.2002
  Gültig bis: 22.03.2002
30 Ratings
Bewertung: 82,7%
schlecht    sehr gut  

 
© Copyright 2007 ppedv AG