Programmazione della porta seriale tramite API Win32 (Windows)

 C Programming >> Programmazione C >  >> Tags >> API
Programmazione della porta seriale tramite API Win32 (Windows)

A volte è necessario comunicare con un dispositivo esterno come una stampante, una scheda microcontrollore o qualsiasi dispositivo seriale utilizzando la porta seriale di una macchina Windows. Sono disponibili molte applicazioni seriali come Hercules, HyperTerminal, Docklight, ecc.

Possiamo utilizzarne uno qualsiasi per la comunicazione seriale, ma a volte è necessario creare la nostra applicazione seriale personalizzata per la comunicazione. In Windows, è facile creare l'applicazione seriale personalizzata utilizzando l'API win32.

In questo post del blog impareremo la programmazione della porta seriale utilizzando l'API Win32. In Windows, la programmazione della porta seriale è molto semplice, MSDN fornisce tutte le informazioni API Win32 necessarie per la programmazione della porta seriale.

Puoi anche vedere gli articoli seguenti su come modificare le proprietà di com-port come baud rate, parità utilizzando l'API di Windows.

  • Modifica le proprietà della porta COM utilizzando l'API win32
  • Ottieni la PORTA COM del dispositivo seriale USB utilizzando VID e PID

Trovare il numero della porta COM di un dispositivo

In Windows, il dispositivo seriale verrà visualizzato nella sezione porta com di Gestione dispositivi con il nome COM1, COM2, COM3, COM4.. ecc. In genere, COM1 e COM2 si riferiscono alle porte seriali hardware presenti nel PC e un altro numero di porta com è esporta quando qualsiasi dispositivo seriale o USB a dispositivo seriale collegato al PC. È anche possibile che com id possa essere virtuale (ad esempio porta com virtuale statica).

Nel mio laptop, ho collegato una scheda Arduino (Atmega 2560) e il suo ID COM sarebbe mostrato nella sezione della porta com (Pannello di controllo> Gestione dispositivi> Porte).

Utilizzo di compilatori e IDE

Qui ho usato Visual Studio 2013. Puoi anche usare MinGW (Minimalist GNU per Windows) uno strumento di programmazione Open Source. Presumo che tu sappia come creare l'applicazione console utilizzando Visual Studio e che conosci l'API di win32.

Apertura di una porta seriale

In Windows usando CreateFile(), possiamo aprire la porta seriale. CreateFile() è un'API Win32 che crea o apre un file o un dispositivo I/O.

In caso di successo, CreateFile() restituisce un handle che può essere utilizzato per accedere al file o al dispositivo a seconda dei flag e degli attributi specificati.

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
);

Chiusura di una porta seriale

Dovresti ricordare che dopo aver aperto la porta com usando CreateFile(), devi chiuderla chiamando CloseHandle() altrimenti non sarà disponibile per altre applicazioni.

BOOL CloseHandle(
  HANDLE hObject
);

In caso di successo CloseHandle() restituisce zero.

Applicazione di comunicazione tramite porta seriale

Vediamo un codice di esempio in cui sto parlando con un dispositivo Arduino Mega2560. Ho scritto un piccolo codice per mega2560 in cui riceve dati seriali. Se i dati ricevuti sono "aticleworld", invierà un messaggio "Benvenuto in AticleWorld!" o altrimenti invierà il messaggio “Invia messaggio corretto”.

Codice seriale Mega2560,

#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");
        }
    }
}

Puoi acquistare Mega2560 da Amazon, Fai clic qui

Applicazione seriale per la console,

Nell'applicazione console sottostante, sto usando l'API win32 per aprire la porta com e inviare i dati alla porta COM aperta. Guarda il video qui sotto in cui ho scaricato il codice Arduino nella scheda Arduino e ho comunicato con questa scheda utilizzando l'applicazione console.

#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;
}

Post consigliati per te:

  • I migliori libri sulle 5 C.
  • Ottieni la PORTA COM del dispositivo seriale USB utilizzando VID e PID.
  • Lettura e scrittura del registro di Windows utilizzando WinAPI
  • Installa il monitor della porta in modo invisibile all'utente senza l'interazione dell'utente.
  • Domande del colloquio C++ con risposte.
  • Domande sull'intervista C-Sharp.
  • Domande per l'intervista Python con risposta.
  • Layout di memoria in C.
  • 100 domande di intervista C, il tuo intervistatore potrebbe chiedere.
  • C Domande per l'intervista per l'esperienza.
  • 10 domande sull'allocazione dinamica della memoria
  • Gestione dei file in C, in poche ore.



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