A veces necesitamos comunicarnos con un dispositivo externo como una impresora, placa de microcontrolador o cualquier dispositivo serial usando el puerto serial de una máquina con Windows. Hay muchas aplicaciones seriales disponibles como Hercules, HyperTerminal, Docklight, ..etc.
Podemos usar cualquiera de ellos para la comunicación en serie, pero a veces necesitamos crear nuestra propia aplicación en serie personalizada para la comunicación. En Windows, es fácil crear la aplicación serial personalizada usando la API win32.
En esta publicación de blog, aprenderemos a programar el puerto serie utilizando la API de Win32. En Windows, la programación del puerto serie es muy fácil, MSDN proporciona toda la información API win32 necesaria para la programación del puerto serie.
También puede ver los artículos a continuación sobre cómo cambiar las propiedades del puerto COM, como la velocidad en baudios, la paridad usando la API de Windows.
- Cambiar las propiedades del puerto COM usando la API win32
- Obtenga el PUERTO COM del dispositivo serie USB usando el VID y el PID
Encontrar el número de puerto COM de un dispositivo
En Windows, el dispositivo serial se mostrará en la sección de puerto com del administrador de dispositivos con el nombre COM1, COM2, COM3, COM4... etc. Generalmente, COM1 y COM2 se refieren a los puertos seriales de hardware presentes en la PC y otro número de puerto com es exportar cuando cualquier dispositivo serial o USB a dispositivo serial conectado a la PC. También es posible que la identificación COM sea virtual (por ejemplo, un puerto COM virtual estático).
En mi computadora portátil, conecté una placa Arduino (Atmega 2560) y su ID COM se mostraría en la sección del puerto com (Panel de control> Administrador de dispositivos> Puertos).
Compiladores e IDE utilizados
Aquí he usado Visual Studio 2013. También puede usar MinGW (Minimalist GNU para Windows) una herramienta de programación de código abierto. Aquí, asumo que sabe cómo crear la aplicación de consola con Visual Studio y que está familiarizado con la API de win32.
Apertura de un puerto serie
En Windows usando CreateFile(), podemos abrir el puerto serie. CreateFile() es una API de Win32 que crea o abre un archivo o dispositivo de E/S.
En caso de éxito, CreateFile() devuelve un identificador que se puede usar para acceder al archivo o dispositivo según las banderas y los atributos especificados.
HANDLE CreateFile( LPCTSTR lpFileName, // pointer to name of the file DWORD dwDesiredAccess, // access (read-write) mode DWORD dwShareMode, // share mode LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes DWORD dwCreationDisposition, // how to create DWORD dwFlagsAndAttributes, // file attributes HANDLE hTemplateFile // handle to file with attributes to // copy );
Cerrar un puerto serie
Debe recordar que después de abrir el puerto com usando CreateFile(), debe cerrarlo llamando a CloseHandle(); de lo contrario, no estará disponible para otras aplicaciones.
BOOL CloseHandle( HANDLE hObject );
En caso de éxito, CloseHandle() devuelve cero.
Aplicación de comunicación de puerto serie
Veamos un código de ejemplo donde estoy hablando con un dispositivo Arduino Mega2560. He escrito un pequeño código para mega2560 en el que recibe datos en serie. Si los datos recibidos son "aticleworld", enviará un mensaje "¡Bienvenido a AticleWorld!" o de lo contrario, enviará el mensaje "Envíe el mensaje correcto".
Código de serie Mega2560,
#include <SoftwareSerial.h> void setup() { // initialize serial ports Serial.begin(9600); // USB serial port 0 } void loop() { String msg = ""; // check for data byte on USB serial port if (Serial.available()) { // get byte from USB serial port while(Serial.available()) { msg = Serial.readString();// read the incoming data as string } if( msg == "aticleworld") { //Send data to usb serial port Serial.write(" Welcome to AticleWorld !"); } else { //Send data to usb serial port Serial.write("Please Send Correct Message"); } } }
Puede comprar Mega2560 en Amazon, haga clic aquí
Aplicación Serie para la consola,
En la siguiente aplicación de consola, estoy usando la API win32 para abrir el puerto COM y enviar los datos al puerto COM abierto. Vea el video a continuación donde descargué el código Arduino en la placa Arduino y me comunico con esta placa usando la aplicación de consola.
#include "stdafx.h" #include <Windows.h> #include <stdio.h> #include <string.h> int main(void) { HANDLE hComm; // Handle to the Serial port BOOL Status; // Status DCB dcbSerialParams = { 0 }; // Initializing DCB structure COMMTIMEOUTS timeouts = { 0 }; //Initializing timeouts structure char SerialBuffer[64] = { 0 }; //Buffer to send and receive data DWORD BytesWritten = 0; // No of bytes written to the port DWORD dwEventMask; // Event mask to trigger char ReadData; //temperory Character DWORD NoBytesRead; // Bytes read by ReadFile() unsigned char loop = 0; wchar_t pszPortName[10] = { 0 }; //com port id wchar_t PortNo[20] = { 0 }; //contain friendly name //Enter the com port id printf_s("Enter the Com Port: "); wscanf_s(L"%s", pszPortName, (unsigned)_countof(pszPortName)); swprintf_s(PortNo, 20, L"\\\\.\\%s", pszPortName); //Open the serial com port hComm = CreateFile(PortNo, //friendly name GENERIC_READ | GENERIC_WRITE, // Read/Write Access 0, // No Sharing, ports cant be shared NULL, // No Security OPEN_EXISTING, // Open existing port only 0, // Non Overlapped I/O NULL); // Null for Comm Devices if (hComm == INVALID_HANDLE_VALUE) { printf_s("\n Port can't be opened\n\n"); goto Exit2; } //Setting the Parameters for the SerialPort dcbSerialParams.DCBlength = sizeof(dcbSerialParams); Status = GetCommState(hComm, &dcbSerialParams); //retreives the current settings if (Status == FALSE) { printf_s("\nError to Get the Com state\n\n"); goto Exit1; } dcbSerialParams.BaudRate = CBR_9600; //BaudRate = 9600 dcbSerialParams.ByteSize = 8; //ByteSize = 8 dcbSerialParams.StopBits = ONESTOPBIT; //StopBits = 1 dcbSerialParams.Parity = NOPARITY; //Parity = None Status = SetCommState(hComm, &dcbSerialParams); if (Status == FALSE) { printf_s("\nError to Setting DCB Structure\n\n"); goto Exit1; } //Setting Timeouts timeouts.ReadIntervalTimeout = 50; timeouts.ReadTotalTimeoutConstant = 50; timeouts.ReadTotalTimeoutMultiplier = 10; timeouts.WriteTotalTimeoutConstant = 50; timeouts.WriteTotalTimeoutMultiplier = 10; if (SetCommTimeouts(hComm, &timeouts) == FALSE) { printf_s("\nError to Setting Time outs"); goto Exit1; } printf_s("\n\nEnter your message: "); scanf_s("%s", SerialBuffer, (unsigned)_countof(SerialBuffer)); //Writing data to Serial Port Status = WriteFile(hComm,// Handle to the Serialport SerialBuffer, // Data to be written to the port sizeof(SerialBuffer), // No of bytes to write into the port &BytesWritten, // No of bytes written to the port NULL); if (Status == FALSE) { printf_s("\nFail to Written"); goto Exit1; } //print numbers of byte written to the serial port printf_s("\nNumber of bytes written to the serail port = %d\n\n", BytesWritten); //Setting Receive Mask Status = SetCommMask(hComm, EV_RXCHAR); if (Status == FALSE) { printf_s("\nError to in Setting CommMask\n\n"); goto Exit1; } //Setting WaitComm() Event Status = WaitCommEvent(hComm, &dwEventMask, NULL); //Wait for the character to be received if (Status == FALSE) { printf_s("\nError! in Setting WaitCommEvent()\n\n"); goto Exit1; } //Read data and store in a buffer do { Status = ReadFile(hComm, &ReadData, sizeof(ReadData), &NoBytesRead, NULL); SerialBuffer[loop] = ReadData; ++loop; } while (NoBytesRead > 0); --loop; //Get Actual length of received data printf_s("\nNumber of bytes received = %d\n\n", loop); //print receive data on console printf_s("\n\n"); int index = 0; for (index = 0; index < loop; ++index) { printf_s("%c", SerialBuffer[index]); } printf_s("\n\n"); Exit1: CloseHandle(hComm);//Closing the Serial Port Exit2: system("pause"); return 0; }
Publicaciones recomendadas para ti:
- Los 5 mejores libros C.
- Obtenga el PUERTO COM del dispositivo serie USB usando el VID y el PID.
- Lectura y escritura del registro de Windows usando WinAPI
- Instalar el monitor de puerto de forma silenciosa sin interacción del usuario.
- Preguntas de la entrevista de C++ con respuestas.
- Preguntas de la entrevista de C-Sharp.
- Preguntas de entrevista de Python con respuesta.
- Diseño de memoria en C.
- Preguntas de la entrevista de 100 C, su entrevistador podría preguntar.
- C Preguntas de entrevista para la experiencia.
- 10 preguntas sobre la asignación de memoria dinámica
- Manejo de archivos en C, en pocas horas.