Serial Port (RS232) communication with Visual C++ 2010

后端 未结 2 1373
别那么骄傲
别那么骄傲 2021-01-07 13:57

I have to write a program in Visual C++ 2010 to communicate via Serial Port (RS232) in Windows 7 32 bit. Can Someone help me to find correct example?

相关标签:
2条回答
  • 2021-01-07 14:44

    Here it is a two samples of the same program, one for visual studio 2013 and the other for minGW in Eclipse in Windows 7 32 bits

    for visual studio:

    stadfx.h

    #pragma once
    #include "targetver.h"
    #include <stdio.h>
    #include <tchar.h>
    
    // TODO: mencionar aquí los encabezados adicionales que el programa necesita
    #include <conio.h>
    #include <string.h>
    
    #define STRICT
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    #include <iostream>
    using namespace std;
    

    terminal.cpp

    #include "stdafx.h"
    
    void error_de_sistema(char *name) {
        // Recupera, formatea y despliega el mensaje del ultimo error
        // 'name' que es el argumento pasado al momento del error debe ser una     frase en presente
        //  como por ejemplo "abriendo archivo".
        //
        //char *ptr = NULL;
        WCHAR ptr[1024];
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM,
            0,
            GetLastError(),
            0,
            //(char *)&ptr,
            ptr,
            1024,
            NULL);
        //fprintf(stderr, "\nError %s: %s\n", name, ptr);
        //fprintf(stderr, "\nError %s: %s\n", name, &ptr);
        wcout << endl << "Error " << name << ": " << ptr << endl;
        LocalFree(ptr);
    }
    
    
    int _tmain(int argc, _TCHAR* 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";
        LPCWSTR port_name = L"\\\\.\\COM5";
        char init[] = ""; // v.gr., "ATZ" resetea un modem por completo.
    
        if (argc > 2)
            swprintf_s((wchar_t *)&port_name, 128, L"\\\\.\\COM%c", argv[1][0]);
        //sprintf(port_name, "\\\\.\\COM%c", argv[1][0]);
    
        // abre el puerto.
        file = CreateFile(port_name,
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);
    
        if (INVALID_HANDLE_VALUE == file) {
            error_de_sistema("abriendo archivo");
            return 1;
        }
    
        // obtiene el block de control del dispositivo DCB, y ajusta unos cuantos bits para nuestro enlace.
        memset(&port, 0, sizeof(port));
        port.DCBlength = sizeof(port);
        if (!GetCommState(file, &port))
            error_de_sistema("obteniendo el estado del puerto");
        //if (!BuildCommDCB("baud=19200 parity=n data=8 stop=1", &port))
        if (!BuildCommDCB(L"baud=9600 parity=n data=8 stop=1", &port))
            error_de_sistema("creando el bloque DCB de comunicaciones");
        if (!SetCommState(file, &port))
            error_de_sistema("ajustando la configuracion del puerto");
    
        // Configura los tiempos fuera cortos para el puerto.
        timeouts.ReadIntervalTimeout = 1;
        timeouts.ReadTotalTimeoutMultiplier = 1;
        timeouts.ReadTotalTimeoutConstant = 1;
        timeouts.WriteTotalTimeoutMultiplier = 1;
        timeouts.WriteTotalTimeoutConstant = 1;
        if (!SetCommTimeouts(file, &timeouts))
            error_de_sistema("configurando los time-outs. del puerto");
    
        // Configura el teclado para una lectura raw (aleatoria y libre).
        if (!GetConsoleMode(keyboard, &mode))
            error_de_sistema("obteniendo el modo del teclado");
        mode &= ~ENABLE_PROCESSED_INPUT;
        if (!SetConsoleMode(keyboard, mode))
            error_de_sistema("configurando el modo del teclado");
    
        if (!EscapeCommFunction(file, CLRDTR))
            error_de_sistema("apagando el DTR");
        Sleep(200);
        if (!EscapeCommFunction(file, SETDTR))
            error_de_sistema("encendiendo el DTR");
    
        if (!WriteFile(file, init, sizeof(init), &written, NULL))
            error_de_sistema("escribiendo datos en el puerto");
    
        if (written != sizeof(init))
            error_de_sistema("porque no todos los datos se enviaron al puerto");
    
        // ciclo basico de la terminal:
        do {
            // checa por datos en el puerto y los despliega en pantalla.
            ReadFile(file, buffer, sizeof(buffer), &read, NULL);
            if (read)
                WriteFile(screen, buffer, read, &written, NULL);
    
            // checa por tecla presionada, y lo envia al puerto.
            if (_kbhit()) {
                ch = _getch();
                WriteFile(file, &ch, 1, &written, NULL);
            }
        } while (ch != 127);    // hasta que el usuario pulse ctrl-backspace.
    
        // cierra todo y bye bye.
        CloseHandle(keyboard);
        CloseHandle(file);
        return 0;
    }
    

    y para eclipse con minGW

    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    
    #define STRICT
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    #include <iostream>
    using namespace std;
    
    void error_de_sistema(char *name) {
        // Recupera, formatea y despliega el mensaje del ultimo error
        // 'name' que es el argumento pasado al momento del error debe ser una frase en presente
        //  como por ejemplo "abriendo archivo".
        //
        char *ptr = NULL;
        //WCHAR ptr[1024];
        FormatMessage(
            FORMAT_MESSAGE_ALLOCATE_BUFFER |
            FORMAT_MESSAGE_FROM_SYSTEM,
            0,
            GetLastError(),
            0,
            //(char *)&ptr,
            ptr,
            1024,
            NULL);
        //fprintf(stderr, "\nError %s: %s\n", name, ptr);
        //fprintf(stderr, "\nError %s: %s\n", name, &ptr);
        wcout << endl << "Error " << name << ": " << ptr << endl;
        LocalFree(ptr);
    }
    
    
    int main(int argc, char **argv)
    {
        int ch;
        char buffer[1];
        char mensaje[256];
        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] = "\\\\.\\COM5";
        //LPCWSTR port_name = L"\\\\.\\COM5";
        char init[] = ""; // v.gr., "ATZ" resetea un modem por completo.
    
        if (argc > 2)
            //swprintf_s((wchar_t *)&port_name, 128, L"\\\\.\\COM%c", argv [1][0]);
            sprintf(port_name, "\\\\.\\COM%c", argv[1][0]);
    
        // abre el puerto.
        file = CreateFile(port_name,
            GENERIC_READ | GENERIC_WRITE,
            0,
            NULL,
            OPEN_EXISTING,
            0,
            NULL);
    
        if (INVALID_HANDLE_VALUE == file) {
            strncpy(mensaje, "abriendo archivo", sizeof(mensaje));
            error_de_sistema(mensaje);
            return 1;
        }
    
        // obtiene el block de control del dispositivo DCB, y ajusta unos  cuantos bits para nuestro enlace.
        memset(&port, 0, sizeof(port));
        port.DCBlength = sizeof(port);
        if (!GetCommState(file, &port)){
            strncpy(mensaje, "obteniendo el estado del puerto", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
        if (!BuildCommDCB("baud=9600 parity=n data=8 stop=1", &port)){
        //if (!BuildCommDCB(L"baud=9600 parity=n data=8 stop=1", &port))
            strncpy(mensaje, "creando el bloque DCB de comunicaciones", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
        if (!SetCommState(file, &port)){
            strncpy(mensaje, "ajustando la configuracion del puerto", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
    
        // Configura los tiempos fuera cortos para el puerto.
        timeouts.ReadIntervalTimeout = 1;
        timeouts.ReadTotalTimeoutMultiplier = 1;
        timeouts.ReadTotalTimeoutConstant = 1;
        timeouts.WriteTotalTimeoutMultiplier = 1;
        timeouts.WriteTotalTimeoutConstant = 1;
        if (!SetCommTimeouts(file, &timeouts)){
            strncpy(mensaje, "configurando los time-outs. del puerto", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
    
        // Configura el teclado para una lectura raw (aleatoria y libre).
        if (!GetConsoleMode(keyboard, &mode)){
            strncpy(mensaje, "obteniendo el modo del teclado", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
        mode &= ~ENABLE_PROCESSED_INPUT;
        if (!SetConsoleMode(keyboard, mode)){
            strncpy(mensaje, "configurando el modo del teclado", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
        //Mandamos un reset por hardware (algunos sistemas se resetean con el DTR)
        if (!EscapeCommFunction(file, CLRDTR)){
            strncpy(mensaje, "apagando el DTR", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
        Sleep(200);
        if (!EscapeCommFunction(file, SETDTR)){
            strncpy(mensaje, "encendiendo el DTR", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
    
        if (!WriteFile(file, init, sizeof(init), &written, NULL)){
            strncpy(mensaje, "escribiendo datos en el puerto", sizeof (mensaje));
            error_de_sistema(mensaje);
        }
        //Por si es necesario enviar algun dato al comenzar el proceso
        if (written != sizeof(init)){
            strncpy(mensaje, "porque no todos los datos se enviaron al  puerto", sizeof(mensaje));
            error_de_sistema(mensaje);
        }
    
        // ciclo basico de la terminal:
        do {
            // checa por datos en el puerto y los despliega en pantalla.
            ReadFile(file, buffer, sizeof(buffer), &read, NULL);
            if (read)
                WriteFile(screen, buffer, read, &written, NULL);
    
            // checa por tecla presionada, y si hay alguna, envia el caracter leido al puerto.
            if (_kbhit()) {
                ch = _getch();
                WriteFile(file, &ch, 1, &written, NULL);
            }
        } while (ch != 127);    // termina el ciclo hasta que el usuario pulse ctrl-backspace.
    
        // cierra todo y bye bye.
        CloseHandle(keyboard);
        CloseHandle(file);
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-07 15:00

    Serial Communications: http://msdn.microsoft.com/en-us/library/ff802693.aspx

    This article still remains actual after so many years... Code sample included.

    0 讨论(0)
提交回复
热议问题