Programmierung der seriellen Schnittstelle mit Win32-API (Windows)

 C Programming >> C-Programmierung >  >> Tags >> API
Programmierung der seriellen Schnittstelle mit Win32-API (Windows)

Manchmal müssen wir mit einem externen Gerät wie einem Drucker, einer Mikrocontrollerplatine oder einem beliebigen seriellen Gerät über den seriellen Anschluss eines Windows-Computers kommunizieren. Es gibt viele serielle Anwendungen wie Hercules, HyperTerminal, Docklight usw.

Wir können jeden von ihnen für die serielle Kommunikation verwenden, aber manchmal müssen wir unsere eigene benutzerdefinierte serielle Anwendung für die Kommunikation erstellen. Unter Windows ist es einfach, die benutzerdefinierte serielle Anwendung mit der Win32-API zu erstellen.

In diesem Blogbeitrag lernen wir die Programmierung serieller Ports mit der Win32-API kennen. Unter Windows ist die Programmierung der seriellen Schnittstelle sehr einfach, MSDN bietet alle erforderlichen Win32-API-Informationen, die für die Programmierung der seriellen Schnittstelle erforderlich sind.

Sie können auch die folgenden Artikel lesen, wie Sie die Eigenschaften des COM-Ports wie Baudrate und Parität mithilfe der Windows-API ändern können.

  • Eigenschaften des COM-Ports mit Win32-API ändern
  • Ermitteln Sie den COM-PORT des seriellen USB-Geräts mithilfe von VID und PID

Suchen der COM-Anschlussnummer eines Geräts

In Windows wird das serielle Gerät im Com-Port-Bereich des Geräte-Managers mit dem Namen COM1, COM2, COM3, COM4 usw. angezeigt. Im Allgemeinen beziehen sich COM1 und COM2 auf die im PC vorhandenen seriellen Hardware-Ports und eine andere Com-Port-Nummer ist Exportieren Sie, wenn ein serielles Gerät oder ein USB-zu-Seriell-Gerät an den PC angeschlossen ist. Es ist auch möglich, dass die Com-ID virtuell ist (zum Beispiel statischer virtueller Com-Port).

In meinem Laptop habe ich ein Arduino-Board (Atmega 2560) angeschlossen und seine COM-ID wird im COM-Port-Bereich angezeigt (Systemsteuerung> Geräte-Manager> Ports).

Verwendete Compiler und IDEs

Hier habe ich Visual Studio 2013 verwendet. Sie können auch MinGW (Minimalist GNU for Windows) verwenden, ein Open-Source-Programmiertool. Hier gehe ich davon aus, dass Sie wissen, wie die Konsolenanwendung mit Visual Studio erstellt wird, und mit der Win32-API vertraut sind.

Öffnen einer seriellen Schnittstelle

In Windows können wir mit CreateFile() die serielle Schnittstelle öffnen. CreateFile() ist eine Win32-API, die eine Datei oder ein E/A-Gerät erstellt oder öffnet.

Bei Erfolg gibt CreateFile() ein Handle zurück, das für den Zugriff auf die Datei oder das Gerät verwendet werden kann, abhängig von den angegebenen Flags und Attributen.

HANDLE CreateFile(
    LPCTSTR lpFileName,          // pointer to name of the file
    DWORD dwDesiredAccess,       // access (read-write) mode
    DWORD dwShareMode,           // share mode
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    // pointer to security attributes
    DWORD dwCreationDisposition,  // how to create
    DWORD dwFlagsAndAttributes,  // file attributes
    HANDLE hTemplateFile         // handle to file with attributes to
    // copy
);

Schließen einer seriellen Schnittstelle

Sie sollten daran denken, dass Sie nach dem Öffnen des COM-Ports mit CreateFile() ihn schließen müssen, indem Sie CloseHandle() aufrufen, da er sonst für andere Anwendungen nicht verfügbar ist.

BOOL CloseHandle(
  HANDLE hObject
);

Bei Erfolg gibt CloseHandle() Null zurück.

Kommunikationsanwendung für serielle Schnittstelle

Sehen Sie sich einen Beispielcode an, in dem ich mit einem Mega2560-Arduino-Gerät spreche. Ich habe einen kleinen Code für mega2560 geschrieben, in dem es serielle Daten empfängt. Wenn die empfangenen Daten „aticleworld“ sind, wird eine Nachricht „Willkommen bei AticleWorld!“ gesendet. andernfalls wird die Nachricht „Bitte korrekte Nachricht senden“ gesendet.

Mega2560-Seriencode,

#include <SoftwareSerial.h>

void setup()
{
    // initialize serial ports
    Serial.begin(9600);    // USB serial port 0
}


void loop()
{
    String msg = "";
    // check for data byte on USB serial port
    if (Serial.available())
    {
        // get byte from USB serial port
        while(Serial.available())
        {
            msg = Serial.readString();// read the incoming data as string
        }
        if( msg == "aticleworld")
        {
            //Send data to usb serial port
            Serial.write(" Welcome to AticleWorld !");
        }
        else
        {
            //Send data to usb serial port
            Serial.write("Please Send Correct Message");
        }
    }
}

Sie können Mega2560 bei Amazon kaufen, klicken Sie hier

Serienanwendung für die Konsole,

In der folgenden Konsolenanwendung verwende ich die Win32-API, um den COM-Port zu öffnen und die Daten an den offenen COM-Port zu senden. Sehen Sie sich das folgende Video an, in dem ich den Arduino-Code in das Arduino-Board heruntergeladen und mit diesem Board über die Konsolenanwendung kommuniziert habe.

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <string.h>

int main(void)
{

    HANDLE hComm;  // Handle to the Serial port
    BOOL   Status; // Status
    DCB dcbSerialParams = { 0 };  // Initializing DCB structure
    COMMTIMEOUTS timeouts = { 0 };  //Initializing timeouts structure
    char SerialBuffer[64] = { 0 }; //Buffer to send and receive data
    DWORD BytesWritten = 0;          // No of bytes written to the port
    DWORD dwEventMask;     // Event mask to trigger
    char  ReadData;        //temperory Character
    DWORD NoBytesRead;     // Bytes read by ReadFile()
    unsigned char loop = 0;
    wchar_t pszPortName[10] = { 0 }; //com port id
    wchar_t PortNo[20] = { 0 }; //contain friendly name



    //Enter the com port id
    printf_s("Enter the Com Port: ");
    wscanf_s(L"%s", pszPortName, (unsigned)_countof(pszPortName));
    swprintf_s(PortNo, 20, L"\\\\.\\%s", pszPortName);

    //Open the serial com port
    hComm = CreateFile(PortNo, //friendly name
                       GENERIC_READ | GENERIC_WRITE,      // Read/Write Access
                       0,                                 // No Sharing, ports cant be shared
                       NULL,                              // No Security
                       OPEN_EXISTING,                     // Open existing port only
                       0,                                 // Non Overlapped I/O
                       NULL);                             // Null for Comm Devices

    if (hComm == INVALID_HANDLE_VALUE)
    {
        printf_s("\n Port can't be opened\n\n");
        goto Exit2;
    }

    //Setting the Parameters for the SerialPort
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

    Status = GetCommState(hComm, &dcbSerialParams); //retreives  the current settings
    if (Status == FALSE)
    {
        printf_s("\nError to Get the Com state\n\n");
        goto Exit1;
    }

    dcbSerialParams.BaudRate = CBR_9600;      //BaudRate = 9600
    dcbSerialParams.ByteSize = 8;             //ByteSize = 8
    dcbSerialParams.StopBits = ONESTOPBIT;    //StopBits = 1
    dcbSerialParams.Parity = NOPARITY;      //Parity = None

    Status = SetCommState(hComm, &dcbSerialParams);
    if (Status == FALSE)
    {
        printf_s("\nError to Setting DCB Structure\n\n");
        goto Exit1;
    }

    //Setting Timeouts
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;
    if (SetCommTimeouts(hComm, &timeouts) == FALSE)
    {
        printf_s("\nError to Setting Time outs");
        goto Exit1;
    }


    printf_s("\n\nEnter your message: ");
    scanf_s("%s", SerialBuffer, (unsigned)_countof(SerialBuffer));


    //Writing data to Serial Port
    Status = WriteFile(hComm,// Handle to the Serialport
                       SerialBuffer,            // Data to be written to the port
                       sizeof(SerialBuffer),   // No of bytes to write into the port
                       &BytesWritten,  // No of bytes written to the port
                       NULL);
    if (Status == FALSE)
    {
        printf_s("\nFail to Written");
        goto Exit1;
    }

    //print numbers of byte written to the serial port
    printf_s("\nNumber of bytes written to the serail port = %d\n\n", BytesWritten);

    //Setting Receive Mask
    Status = SetCommMask(hComm, EV_RXCHAR);

    if (Status == FALSE)
    {
        printf_s("\nError to in Setting CommMask\n\n");
        goto Exit1;
    }


    //Setting WaitComm() Event
    Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received
    if (Status == FALSE)
    {
        printf_s("\nError! in Setting WaitCommEvent()\n\n");
        goto Exit1;
    }

    //Read data and store in a buffer
    do
    {
        Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL);
        SerialBuffer[loop] = ReadData;
        ++loop;
    }
    while (NoBytesRead > 0);

    --loop; //Get Actual length of received data

    printf_s("\nNumber of bytes received = %d\n\n", loop);

    //print receive data on console
    printf_s("\n\n");
    int index = 0;
    for (index = 0; index < loop; ++index)
    {
        printf_s("%c", SerialBuffer[index]);
    }

    printf_s("\n\n");

Exit1:
    CloseHandle(hComm);//Closing the Serial Port
Exit2:
    system("pause");
    return 0;
}

Empfohlene Beiträge für Sie:

  • Die 5 besten C-Bücher.
  • Ermitteln Sie den COM-PORT des seriellen USB-Geräts mithilfe von VID und PID.
  • Lesen und Schreiben der Windows-Registrierung mit WinAPI
  • Installieren Sie den Port-Monitor im Hintergrund ohne Benutzereingriff.
  • C++-Interviewfragen mit Antworten.
  • C-Sharp-Interviewfragen.
  • Python-Interviewfragen mit Antwort.
  • Speicherlayout in C.
  • 100-C-Interviewfragen, die Ihr Interviewer stellen könnte.
  • C Interviewfragen für die Erfahrung.
  • 10 Fragen zur dynamischen Speicherzuweisung
  • Dateiverwaltung in C in wenigen Stunden.



Referenz:https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea