www.mikrocontroller.net

Forum: PC-Programmierung Serielle Schnittstelle ansprechen mit VB und API


Autor: Johannes H. (johannes-kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich suche Beispielcode um via API-Aufrufen die seriellen COM Ports 
nutzen zu können.

Insbesondere:
Handle bekommen mit CreateFile
Gerät identifizieren
Senden und Empfangen
Handle schliessen mit CloseFile

Danke, Johannes

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...zwar nicht in VB, aber die Winapi-Aufrufe kannst Du leicht
übertragen: http://www.winapi.net/index.php?inhalt=t3

Gruß Matthias

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>ich suche Beispielcode um via API-Aufrufen die seriellen COM Ports
>nutzen zu können.

findest du in der MSDN

Autor: Andreas Lang (andi84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
auf planetsourcecode.com gab es mal was.

Autor: Fritz Feichtinger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

Ich hab mich da ein wenig hinein gelesen und dann selbst ein Programm 
geschrieben, dass den COM Port abfragt und grafisch auf dem Bildschirm 
darstellt, allerdings in C. Das funktioniert auch noch mit 115200 Baud!

Für den gesamten Code bitte nachfragen.

Im Prinzip geht das so:

erst ein:

RS232=CreateFile(PORT,GENERIC_READ | 
GENERIC_WRITE,0,NULL,OPEN_EXISTING,NULL,NULL);

PORT ist hier zb. "COM1" (mit "")
RS232 ist der Handle, den dir Windows zurückliefert

Dann die Einstellungen abfragen:
GetCommState(RS232,&settings);

Dann die Einstellungen bearbeiten:

settings.BaudRate=BAUDRATE;
settings.ByteSize=8;
settings.Parity=NOPARITY;
settings.StopBits=ONESTOPBIT;´

Dann die geänderten Einstellungen setzten:

SetCommState(RS232,&settings);

Tja und dann kannst du theoretisch die Schnittstelle mit:

ReadFile(RS232,&data,1,&received_bytes,NULL);

auslesen.

Was die Befehle jetzt im Detail zu bedienen sind, und was es sonst noch 
gibt, siehe hier:

http://msdn2.microsoft.com/en-us/library/aa363196.aspx

Autor: Johannes H. (johannes-kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, danke.
Ihr seid eine große Hilfe.

Mit euren Anmerkungen sind mir auch schon erste Erfolge gelungen.
Ich arbeite das Ganze noch ein bischen aus, und poste dann hier den vb 
code.

Autor: Johannes H. (johannes-kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, hier ist fast alles was das Herz begehrt.

COM-Port mit VBA 6.0 bedienen.
Suchbefriffe: Visual Basic COM SERIELL
Option Explicit

Public Const COM_PORT_MAX = 9
Public Const GENERIC_READ = &H80000000
Public Const GENERIC_WRITE = &H40000000
Public Const OPEN_EXISTING = 3
Public Const FILE_ATTRIBUTE_NORMAL = &H80
Public Const INVALID_HANDLE_VALUE = -1


Type dcb 'Com-Port Settings
        DCBlength As Long
        BaudRate As Long
        fBitFields As Long
        wReserved As Integer
        XonLim As Integer
        XoffLim As Integer
        ByteSize As Byte
        Parity As Byte
        StopBits As Byte
        XonChar As Byte
        XoffChar As Byte
        ErrorChar As Byte
        EofChar As Byte
        EvtChar As Byte
        wReserved1 As Integer
End Type

'Handle erstellen
Public Declare Function CreateFile _
    Lib "kernel32" _
    Alias "CreateFileA" _
    (ByVal lpFileName As String, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, _
    ByRef lpSecurityAttributes As Long, _
    ByVal dwCreationDisposition As Long, _
    ByVal dwFlagsAndAttributes As Long, _
    ByVal hTemplateFile As Long) _
As Long

'Handle löschen
Public Declare Function CloseHandle _
    Lib "kernel32" _
    (ByVal hObject As Long) _
As Long

'Von Handle empfangen
Public Declare Function ReadFile _
    Lib "kernel32" _
    (ByVal hFile As Long, _
    ByVal lpBuffer As Any, _
    ByVal nNumberOfBytesToRead As Long, _
    ByRef lpNumberOfBytesRead As Long, _
    ByVal lpOverlapped As Any) _
As Long

'An Handle senden
Public Declare Function WriteFile _
    Lib "kernel32" _
    (ByVal hFile As Long, _
    ByVal lpBuffer As Any, _
    ByVal nNumberOfBytesToWrite As Long, _
    ByRef lpNumberOfBytesWritten As Long, _
    ByVal lpOverlapped As Any) _
As Long

'Com Port Eigenschaften Setzen
Public Declare Function SetCommState _
    Lib "kernel32" _
    (ByVal hCommDev As Long, _
    lpDCB As dcb) _
As Long

'Com Port Eigenschaften Holen
Public Declare Function GetCommState _
    Lib "kernel32" _
    (ByVal nCid As Long, _
    lpDCB As dcb) _
As Long

'Kommunikationsweg freiblasen
Declare Function FlushFileBuffers _
    Lib "kernel32" _
    (ByVal hFile As Long) _
As Long

'Com setting setzen
Public Sub SetCOM(ByVal handle As Long, ByVal BaudRate, ByteSize, Parity, StopBits As Integer)
    Dim settings As dcb
    settings.DCBlength = LenB(settings)
    Call GetCommState(handle, settings)
    settings.BaudRate = BaudRate
    settings.ByteSize = ByteSize
    settings.Parity = Parity
    settings.StopBits = StopBits
    Call SetCommState(handle, settings)
    'Nach mir die Sintflut, die alten settings gehen verloren
End Sub

Public Function DetectWaage() As Long
    Dim CurrentHandle As Long
    Dim CurrentMember As Integer
    
    For CurrentMember = 1 To COM_PORT_MAX
        CurrentHandle = CreateFile("COM" + Right(Str(CurrentMember), Len(Str(CurrentMember)) - 1) + Chr(0), _
        GENERIC_READ Or GENERIC_WRITE, ByVal 0, ByVal 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, ByVal 0)
        
        'TODO Gerät erkennen
        '************
        If Not CurrentHandle = INVALID_HANDLE_VALUE Then
            Exit For
        End If
        '*************
    Next CurrentMember
    
    DetectWaage = CurrentHandle
End Function

Public Sub send(ByVal handle As Long, ByVal message As String)
    Dim nirvana_long As Long
    Dim nirvana_string As String * 1024
    Call WriteFile(handle, message, Len(message), nirvana_long, vbNullString)
    Call ReadFile(handle, nirvana_string, Len(message), nirvana_long, vbNullString)
End Sub

Public Function read(ByVal handle As Long) As String
    Dim nirvana_long As Long
    Dim counter As Long
    Dim buffer As String
    Dim readonce As String * 1
    readonce = ""
    buffer = ""
    counter = 0
    Do Until (Left$(readonce, 1) = vbCr)
        Call ReadFile(handle, readonce, 1, nirvana_long, vbNullString)
        counter = counter + 1
        buffer = buffer + Left$(readonce, 1)
    Loop
    readx = Left$(buffer, counter)
End Function

Autor: Dirk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ein kleines Beispiel für VB2005 und der SystemIO (Framework 2.0). 
Ein Teil des Codes hab ich im Internet gefunden. Das Programm 
funktioniert (getestet hab ich die Empfangs- und Senderoutine mittels 
Virtual Serial Port).

Die Buffergroesse laesst sich variable einstellen, aber mich wuerde 
interessieren ob man trotzdem noch einen Ringbuffer implementiert oder 
nicht.
Imports System.IO.Ports


Public Delegate Sub rxDataDelegate()

Public Class Form1
    Dim WithEvents SerialPort As New SerialPort
    Dim rev(80) As Byte
    Dim cnt_index As Byte

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        If SerialPort.IsOpen Then
            SerialPort.Close()
        End If

        Try
            With SerialPort
                .PortName = "Com4"
                .BaudRate = 9600
                .Parity = Parity.None
                .DataBits = 8
                .StopBits = StopBits.One
            End With
            SerialPort.Open()
        Catch ex As Exception
            MsgBox(ex.ToString)
        End Try


    End Sub


    REM Private Sub com1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles com1.DataReceived
    REM Dim returnStr As String
    REM returnStr = com1.ReadLine
    REM ReceiveSerialData(returnStr)
    REM End Sub



    Sub SendSerialData(ByVal data As String)
        ' Send strings to a serial port.
        SerialPort.WriteLine(data)
    End Sub


    Private Sub ReceiveSerialData()
        'TextBox1.AppendText(SerialPort.ReadLine)
        rev(cnt_index) = SerialPort.ReadByte
        ListBox1.Items.Add(rev(cnt_index))
        ListBox1.Items.Add(cnt_index)
        cnt_index = cnt_index + 1
    End Sub


    Private Sub serialport_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort.DataReceived, SerialPort1.DataReceived
        TextBox1.Invoke(New rxDataDelegate(AddressOf ReceiveSerialData), New Object() {})
    End Sub


    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'SendSerialData("TestString")
        SendSerialData("hhhh")
    End Sub

   
    Private Sub GetSerialPortNames()
        ' Show all available COM ports.
        For Each sp As String In My.Computer.Ports.SerialPortNames
            ListBox1.Items.Add(sp)
        Next
    End Sub


    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        GetSerialPortNames()
    End Sub


    Private Sub SetuToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SetuToolStripMenuItem.Click
        GetSerialPortNames()
    End Sub
End Class

Autor: Johannes H. (johannes-kuriboh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Problem mit meinem obigen Code:

Der Input und der Output Buffer sind der selbe.

Vermutete Lösung:
Zwei seperate Handle mit Createfile holen, einer mit Read, der andere 
mit write rechten. Wobei share enabled werden muss.

Ich habe heute keine Zeit mehr das zu testen, kann das jemand 
bestätigen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.