ublo
bogdan's (micro)blog

bogdan

bogdan » simple windows COM port wrapper library

06:00 pm on Dec 19, 2011 | read the article | tags:

searching for a way to read the serial port in windows using C (usually i do my programming under linux), i found a cute little wrapper for the serial port here. i don’t like .NET that’s why i’ve wanted a pure C implementation. here’s the code (most of it from the source). read the comments as it saved me a lot of problems accessing higher COM ports. remember to escape the characters in the string!

HANDLE openSerialConsole (LPCSTR p) {
// LPCSTR p is a string containing the name of the device
// in Windows namespace, the safest way to access the COM ports
// is to use the \\.\COMxx syntax. remember, p is a string
// and \ escapes characters so p should really be "\\\\.\\COMxx"
    HANDLE h;
    DCB params = {0};
    COMMTIMEOUTS timeouts = {0};

    h = CreateFile ( p,
        GENERIC_READ | GENERIC_WRITE, // the way we want to interact with the COM port
        0, // not the wisest way to open the device as it takes exclusive control over
        NULL, // no security attributes, meaning no child process access
        OPEN_EXISTING, // only if we have a COM port
        0, // some things i didn't understood completely
        NULL);
    if (h == INVALID_HANDLE_VALUE) {
        printf("Error: Could not create handle!\n");
        return (void *) NULL;
        }

    params.DCBlength = sizeof(params);
    if (!GetCommState(h, &params)) {
        printf("Error: Setting COM State!\n");
        CloseHandle (h);
        return (void *) NULL;
        }

    // 9600 bauds, with a 8N1 format
    params.BaudRate=CBR_9600;
    params.ByteSize=8;
    params.Parity=NOPARITY;
    params.StopBits=ONESTOPBIT;
    if (!SetCommState(h, &params)) {
        printf("Error: Setting BAUD!\n");
        CloseHandle (h);
        return (void *) NULL;
        }

    // timeouts, avoid hanging
    timeouts.ReadIntervalTimeout=50;
    timeouts.ReadTotalTimeoutConstant=50;
    timeouts.ReadTotalTimeoutMultiplier=10;
    timeouts.WriteTotalTimeoutConstant=50;
    timeouts.WriteTotalTimeoutMultiplier=10;
    if (!SetCommTimeouts(h, &timeouts)) {
        printf("Error: Setting timeouts!\n");
        CloseHandle (h);
        return (void *) NULL;
        }

    return h;
    }

unsigned long int readFromSerialConsole ( HANDLE h, char * buffer, int size ) {
    unsigned long int bytes = 0;
    COMSTAT status;
    unsigned long int errors;

    ClearCommError (h, &errors, &status);

    if (status.cbInQue > 0) {
        size = status.cbInQue > size ? size : status.cbInQue;
        if (ReadFile(h, buffer, size, &bytes, NULL) && bytes != 0)
            return bytes;
        }
    return bytes;
    }

unsigned long int writeToSerialConsole(HANDLE h, char * buffer, int size) {
    unsigned long int bytes = 0;
    if (!WriteFile(h, buffer, size, &bytes, NULL));
    return bytes;
    }

void closeSerialConsole (HANDLE h) {
    CloseHandle (h);
    }

aceast sait folosește cookie-uri pentru a îmbunătăți experiența ta, ca vizitator. în același scop, acest sait utilizează modulul Facebook pentru integrarea cu rețeaua lor socială. poți accesa aici politica mea de confidențialitate.