카테고리 없음

[비주얼 -C ++] Visual C ++ 2010과의 직렬 포트 (RS232) 통신

행복을전해요 2020. 12. 12. 01:53

직렬 통신 : http://msdn.microsoft.com/en-us/library/ff802693.aspx

이 기사는 수년이 지난 후에도 여전히 실제 상태로 남아 있습니다. 코드 샘플이 포함되어 있습니다.

-------------------

다음은 동일한 프로그램의 두 샘플입니다. 하나는 Visual Studio 2013 용이고 다른 하나는 Windows 7 32 비트 Eclipse의 minGW 용입니다.

비주얼 스튜디오 :

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


출처
https://stackoverflow.com/questions/7415038