Serielle Kommunikation mit WriteFile/ReadFile

Lesezeit: 5 Minuten

Serielle Kommunikation mit WriteFileReadFile
lyricAlsSH

//#include "StdAfx.h"
#include <stdio.h> 
#include <windows.h> 
#include <winbase.h>
#include <iostream>
#include <tchar.h>
using namespace std;

int main()
{

    int com = 'COM2';
    string data = "n 010400 n";
    char output[32];
    //unsigned int length = 0;
    DCB config = {0};
    bool abContinue = true;
    DWORD dwBytesWritten;
    DWORD  dwBytesRead;
    int isRead = false;

    HANDLE m_hCommPort = ::CreateFile(L"COM2",
        GENERIC_READ|GENERIC_WRITE,//access ( read and write)

        0,    //(share) 0:cannot share the COM port                        

        0,    //security  (None)                

        OPEN_EXISTING,// creation : open_existing

        0,    // we dont want overlapped operation

        0// no templates file for COM port...

        );

    config.DCBlength = sizeof(config);


    if((GetCommState(m_hCommPort, &config) == 0))
    {
        printf("Get configuration port has a problem.");
        return FALSE;
    }

    config.BaudRate = 9600;
    config.StopBits = ONESTOPBIT;
    config.Parity = PARITY_NONE; 
    config.ByteSize = DATABITS_8;
    config.fDtrControl = 0;
    config.fRtsControl = 0;

    if (!SetCommState(m_hCommPort, &config))
    {

        printf( "Failed to Set Comm State Reason: %dn",GetLastError());
        //return E_FAIL;
    }

    printf("Current Settingsn Baud Rate %dn Parity %dn Byte Size %dn Stop Bits %d", config.BaudRate, 
        config.Parity, config.ByteSize, config.StopBits);

    int isWritten = WriteFile(m_hCommPort, &data,(DWORD) sizeof(data), &dwBytesWritten, NULL);


    //memset(output, 0, sizeof(output));
    while (abContinue) 
    {

        isRead = ReadFile(m_hCommPort, output, sizeof(output), &dwBytesRead, NULL);

        if(!isRead)
        {
            abContinue = false;
            break;
        }

    }

    cin.get();
}

Ich habe Probleme beim Lesen vom COM-Port. Wenn ich den Code schrittweise durchgehe, geht er in “isRead = ReadFile(m_hCommPort, output, sizeof(output), &dwBytesRead, NULL);” und kommt nicht wieder heraus …. Dies ist mein erster Versuch ohne Erfolg.

  • Mein Problem ist genau das Gegenteil. ReadFile wartet nicht auf irgendetwas, kehrt einfach mit 0 gelesenen Bytes und Rückgabewert zurück TRUE -.-

    – Bitter blau

    13. Mai 14 um 13:29 Uhr

Serielle Kommunikation mit WriteFileReadFile
Jerry Sarg

Sie könnten einen Code wie diesen ausprobieren, nachdem Sie die Datei geöffnet haben, aber bevor Sie versuchen, sie zu verwenden:

COMMTIMEOUTS timeouts;

timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
if (!SetCommTimeouts(m_hCommPort, &timeouts))
    // setting timeouts failed.

Bearbeiten: Vielleicht ist es einfacher, mit einem Code zu beginnen, der funktioniert, und ihn dazu zu bringen, das zu tun, was Sie wollen, anstatt zu versuchen, Ihren Code zum Laufen zu bringen. Hier ist ein einfaches Terminalprogramm. Es ist extrem minimalistisch, funktioniert aber (zumindest gut genug, um zum Beispiel die Ausgabe meines GPS zu sehen). Es ist weit entfernt von dem, was irgendjemand (am wenigsten ich) anspruchsvoll nennen würde, aber es sollte zumindest eine Vorstellung davon geben, wie man anfängt.

#include <stdio.h>
#include <conio.h>
#include <string.h>

#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

void system_error(char *name) {
// Retrieve, format, and print out a message from the last error.  The 
// `name' that's passed should be in the form of a present tense noun 
// (phrase) such as "opening file".
//
    char *ptr = NULL;
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM,
        0,
        GetLastError(),
        0,
        (char *)&ptr,
        1024,
        NULL);

    fprintf(stderr, "nError %s: %sn", name, ptr);
    LocalFree(ptr);
}

int main(int argc, char **argv) {

    int ch;
    char buffer[1];
    HANDLE file;
    COMMTIMEOUTS timeouts;
    DWORD read, written;
    DCB port;
    HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE);
    HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD mode;
    char port_name[128] = "\\.\COM3";
    char init[] = ""; // e.g., "ATZ" to completely reset a modem.

    if ( argc > 2 )
        sprintf(port_name, "\\.\COM%c", argv[1][0]);

    // open the comm port.
    file = CreateFile(port_name,
        GENERIC_READ | GENERIC_WRITE,
        0, 
        NULL, 
        OPEN_EXISTING,
        0,
        NULL);

    if ( INVALID_HANDLE_VALUE == file) {
        system_error("opening file");
        return 1;
    }

    // get the current DCB, and adjust a few bits to our liking.
    memset(&port, 0, sizeof(port));
    port.DCBlength = sizeof(port);
    if ( !GetCommState(file, &port))
        system_error("getting comm state");
    if (!BuildCommDCB("baud=19200 parity=n data=8 stop=1", &port))
        system_error("building comm DCB");
    if (!SetCommState(file, &port))
        system_error("adjusting port settings");

    // set short timeouts on the comm port.
    timeouts.ReadIntervalTimeout = 1;
    timeouts.ReadTotalTimeoutMultiplier = 1;
    timeouts.ReadTotalTimeoutConstant = 1;
    timeouts.WriteTotalTimeoutMultiplier = 1;
    timeouts.WriteTotalTimeoutConstant = 1;
    if (!SetCommTimeouts(file, &timeouts))
        system_error("setting port time-outs.");

    // set keyboard to raw reading.
    if (!GetConsoleMode(keyboard, &mode))
        system_error("getting keyboard mode");
    mode &= ~ ENABLE_PROCESSED_INPUT;
    if (!SetConsoleMode(keyboard, mode))
        system_error("setting keyboard mode");

    if (!EscapeCommFunction(file, CLRDTR))
        system_error("clearing DTR");
    Sleep(200);
    if (!EscapeCommFunction(file, SETDTR))
        system_error("setting DTR");

    if ( !WriteFile(file, init, sizeof(init), &written, NULL))
        system_error("writing data to port");

    if (written != sizeof(init))
        system_error("not all data written to port");

    // basic terminal loop:
    do {
        // check for data on port and display it on screen.
        ReadFile(file, buffer, sizeof(buffer), &read, NULL);
        if ( read )
            WriteFile(screen, buffer, read, &written, NULL);

        // check for keypress, and write any out the port.
        if ( kbhit() ) {
            ch = getch();
            WriteFile(file, &ch, 1, &written, NULL);
        }
    // until user hits ctrl-backspace.
    } while ( ch != 127);

    // close up and go home.
    CloseHandle(keyboard);
    CloseHandle(file);
    return 0;
}

  • ok, das scheint das Thread-Problem zu beheben, aber ich kann die ReadFile() nicht dazu bringen, mein Ausgabe-Array zu füllen.

    – lyricAlsSH

    17. Mai ’11 um 22:30 Uhr

  • Ich sollte klarstellen, dass ich versuche, seriell mit einem eingebetteten System zu kommunizieren, und sein Anforderungs- / Antwortprotokoll basiert auf Zeichenfolgen. Ich habe es auf hyperTerminal, aber ich versuche, meinen eigenen Code zu erstellen, der im Wesentlichen dasselbe tut.

    – lyricAlsSH

    17. Mai 11 um 23:12 Uhr

  • Ok, ich habe deinen Code genauer durchgesehen. Es hilft wirklich, danke!

    – lyricAlsSH

    17. Mai ’11 um 23:49 Uhr

Wenn Sie nicht setzen Sie die Timeouts explizit, dann wird ReadFile auf unbestimmte Zeit blockiert, bis Daten verfügbar werden.

Die ReadFile-Funktion blockiert möglicherweise Ihren Thread. Wenn dies der Fall ist, bleibt sie blockiert, bis einige Daten von der seriellen Schnittstelle gelesen werden können. Hier ist ein Verknüpfung mal sehen ob es hilft. Viel Glück.

Ich hatte dieses Problem bei einer Readfile mit eingestellten Timeouts. Das hat mich verrückt gemacht, also habe ich mir Code aus dem Internet geholt, der funktioniert hat, und dann Zeile für Zeile geändert, um zu sehen, wo der Fehler war.

Es stellte sich heraus, dass die Readfile in Ordnung war. Mein Problem war ein WaitCommEvent, das hängen blieb, als der Port getrennt wurde, da kein com-Ereignis jemals empfangen wurde …

.

796540cookie-checkSerielle Kommunikation mit WriteFile/ReadFile

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy