0% found this document useful (0 votes)
57 views

Serial Port Programming Using Win32 API

This document provides an overview of how to program serial ports on Windows using the Win32 API in C language. It discusses opening and closing serial ports with CreateFile() and CloseHandle(), configuring the serial port settings like baud rate and data bits using the DCB structure with GetCommState() and SetCommState(), setting timeouts with COMMTIMEOUTS, and writing data to the serial port using WriteFile(). The document also provides information on finding COM port numbers and compilers that can be used.

Uploaded by

Khaled Medadha
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
57 views

Serial Port Programming Using Win32 API

This document provides an overview of how to program serial ports on Windows using the Win32 API in C language. It discusses opening and closing serial ports with CreateFile() and CloseHandle(), configuring the serial port settings like baud rate and data bits using the DCB structure with GetCommState() and SetCommState(), setting timeouts with COMMTIMEOUTS, and writing data to the serial port using WriteFile(). The document also provides information on finding COM port numbers and compilers that can be used.

Uploaded by

Khaled Medadha
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

Serial Port Programming using Win32 API

Submitted by Rahul.Sreedharan on 7 June 2015 - 10:33am

In this tutorial we will learn How to communicate with an external device like a microcontroller
board or modem using the Serial port of a windows PC(Windows XP,7). The software is written
using C language and communicates with the Serial Port using Win32 API.

In Windows ,Serial ports are named as COM1,COM2 ,COM3.. etc .COM1 and COM2 usually
refer to the hardware serial ports present in the PC while COM numbers in double digits like
COM32,COM54,COM24.. etc are given to USB to Serial Converters or PCI serial port extenders.
If your PC does not have any hardware serial ports (RS232 DB9 ports), you can use USB to
Serial Converter's like USB2SERIAL.

If you are interested in setting up an RS485 network controlled by your PC to control a robot or a
sensor network ,you can use USB2SERIAL board (buy here).

The Board can also be used as an FT232 development board.

Sourcecodes

All the C sourefiles used in this tutorial can be downloaded from our GitHub Page.

Please note that the sourcecodes on the website show only the relevant sections to highlight
the process of programming the serial port.

Please use the complete sourcecodes from our github repo when building your own program.

If you are new to Github Check this article to download code .

Compilers and IDE's used


To Compile the C file you can use either Visual Studio Community edition from Microsoft or
MinGW (Windows port of GCC).
Visual Studio 2013 Express Edition for Desktop can be freely downloaded (its a large download)
from Microsoft's website. 
If you don’t want to download the Visual Studio and want something simpler you can use MinGW,
which is an open source port of GCC for windows environment. After you have installed the
MinGW, package make sure to add gcc to system path so that you can call it from anywhere.

Finding out your COM port Number


To find out the COM number corresponding to your serial port, Open Device Manager by right
clicking on My Computer icon and selecting Manage → Device Manager.Under Ports(COM &
LPT) you can see the parallel and serial ports (COM) detected by your system.
If your PC has any hardware ports, it will be shown either as COM1 or COM2 under the Ports
Section. I am using a FTDI based USB to Serial Converter (USB2SERIAL)which is recognized as
COM24 (this may be different under your system). If you double click on COM24,you can see the
details of the corresponding port.

Opening and Closing a Serial Port


In Windows we use the CreateFile() function to open a serial port.
CreateFile() is a Win 32 function which is used to create or open a file, stream or an IO device
like serial port.On success CreateFile() will return a handle which is then used to refer the
connection in all subsequent operations.

After opening a serial port using the CreateFile() function you should close it with
CloseHandle() function, otherwise port will become unavailable to other programs.
Now let's write a small program to open and close a serial port on Windows. Open a text editor
like notepad or Notepad++ and type the below code and save it as “serial.c”.If you are using IDE
like VS Express, use the one integrated with it. 

#include<windows.h>
#include<stdio.h>
int main()
{
  HANDLE hComm;

  hComm = CreateFile(“\\\\.\\COM24”,                //port
name
                      GENERIC_READ |
GENERIC_WRITE, //Read/Write
                      0,                            // No
Sharing
                      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(“Error in opening serial port”);
  else
      printf(“opening serial port successful”);

  CloseHandle(hComm);//Closing the Serial Port

  return 0;
}
Find out the COM port corresponding to your system and substitute in CreateFile() instead
of COM24.

Now compile and run the program by pressing F5 in Visual Studio


or
by running the following command for gcc (MingW).Please make sure that gcc is added to you
system path.

D:\> gcc -o serial serial.c

Now let me explain the code ,


windows.h header file contain all the definitions, function prototypes and constants required by
the program.

In Windows everything is controlled by using handles.In the first line


HANDLE hComm;
we declare a handle hcomm to access and control the serial port.

Next we open a connection to serial port using CreateFile() function. The CreateFile() function on
success, returns a valid handle to the hComm variable.

CreateFile() function takes 7 arguments,

1. Name of the serial port to be opened here \\\\.\\COM24.


2. Mode of access, here Read and Write
3. Sharing options, Serial ports can't be shared so 0
4. NULL for Serial ports, used for File operations
5. Open the existing port, OPEN_EXISTING
6. Overlapped IO or Non overlapped IO, here 0 means we are using NonOverlapped IO.
Overlapped IO is used for multithreaded programs where
several threads can interact with the port simultaneously.
7. NULL for Serial port, used for file operations

If the function succeeds in opening the serial port, it returns a valid handle to hcomm which is then
used for error checking.

After that the connection to the port is closed using

CloseHandle(hComm);

Please note that in Windows, COM port numbers from COM1 to COM9 are reserved by the
system. If you are using a serial port whose COM port number falls in that range, you don’t need
the back slashes (\\\\.\\)shown in the above code.

You can access the serial port like this,

hComm = CreateFile(“COM1”,          // for COM1—COM9 only


                   GENERIC_READ | GENERIC_WRITE, //Read/Write
                   0,               // No Sharing
                   NULL,            // No Security
                   OPEN_EXISTING,   // Open existing port only
                   0,               // Non Overlapped I/O
                   NULL);

Configuring the DCB Structure


In Windows ,settings like Baud rate ,Number of start/Stop bits,data formats etc for the serial port
are controlled by the DCB structure.

To Configure the DCB structure we use two functions,


GetCommState() function which retrieves the current control settings of the serial port and
SetCommState() function which configures the serial port with the new values in DCB structure
provided by us.

First you declare a new structure of type DCB and initializes it.

DCB dcbSerialParams = { 0 }; // Initializing DCB structure


dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

After that retrieve the current settings of the serial port using the GetCommState() function.

Status = GetCommState(hComm, &dcbSerialParams);

and set the values for Baud rate, Byte size, Number of start/Stop bits etc.

dcbSerialParams.BaudRate = CBR_9600;  // Setting BaudRate = 9600


dcbSerialParams.ByteSize = 8;         // Setting ByteSize = 8
dcbSerialParams.StopBits = ONESTOPBIT;// Setting StopBits = 1
dcbSerialParams.Parity   = NOPARITY;  // Setting Parity = None

if you want to change the Baud rate values prefix standard values with CBR like
this CBR_4800,CBR_9600,CBR_192600 etc.

Number of Stop bits can be changed to ONESTOPBIT or TWOSTOPBITS.


Parity can also be changed to EVENPARITY,ODDPARITY,NOPARITY etc.

Now its time to configure the serial port according to the DCB structure using SetCommState()
function.

SetCommState(hComm, &dcbSerialParams);

Setting Timeouts
Timeouts helps to prevent your program from waiting endlessly till data arrives. It helps the read
or write calls to return after a set time period has elapsed.
 

COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout         = 50; // in milliseconds
timeouts.ReadTotalTimeoutConstant    = 50; // in milliseconds
timeouts.ReadTotalTimeoutMultiplier  = 10; // in milliseconds
timeouts.WriteTotalTimeoutConstant   = 50; // in milliseconds
timeouts.WriteTotalTimeoutMultiplier = 10; // in milliseconds
 
All values are in milliseconds.

ReadIntervalTimeout Specifies the maximum time interval between arrival of two bytes. If the
arrival time exceeds these limits the ReadFile() function returns.

ReadTotalTimeoutConstant is used to calculate the total time-out period for read operations.
For each read operation, this value is added to the product of the ReadTotalTimeoutMultiplier
member and the requested number of bytes.

ReadTotalTimeoutMultiplier is used to calculate the total time-out period for read


operations. For each read operation, this value is multiplied by the requested number of bytes to
be read.

WriteTotalTimeoutConstant similar to ReadTotalTimeoutConstant but for write


operation.

WriteTotalTimeoutMultiplier similar to ReadTotalTimeoutMultiplier but for write


operation.

After this you have to set the values using SetCommTimeouts() function.

Writing Data to Serial Port


Writing data to the opened serial port is accomplished by the WriteFile() function. WriteFile()
function can be used to write both into the files and I/O ports.

char lpBuffer[] = "A";
DWORD dNoOFBytestoWrite;         // No of bytes to write
into the port
DWORD dNoOfBytesWritten = 0;     // No of bytes written to
the port
dNoOFBytestoWrite = sizeof(lpBuffer);

Status = WriteFile(hComm,        // Handle to the Serial


port
                   lpBuffer,     // Data to be written to
the port
                   dNoOFBytestoWrite,  //No of bytes to
write
                   &dNoOfBytesWritten, //Bytes written
                   NULL);

hComm Handle of the serial port to write.

lpBuffer[] character array containing the data to write into the serial port.

dNoOFBytestoWrite is the total number of bytes to be written into the serial port.Here we
are using the sizeof() operator to find out that .

dNoOFBytestoWrite = sizeof(lpBuffer);

dNoOfBytesWritten is the total number of bytes written successfully to the port by the
WriteFile() operation.
Now in the Zip File containing the source codes you can find “USB2SERIAL_Write_W32.c” which
contains the complete code for writing into serial port. You can compile the code using Visual
Studio Express or GCC.

If your PC does not have any hardware serial ports you can use any USB to Serial
Converters(I am using USB2SERIAL).

I have interfaced a microcontroller board(MSP430G2553 on Launch Pad) to the serial port using
a null modem cable like this

You can use any microcontroller of your choice like 8051,AVR or ARM(LPC2148).The Controller
waits for a character to be received and lights up the corresponding LED. The code for MSP430
is included in the zip file.If you want to know how to configure the MSP430 controller UART you
can check this tutorial.

Please note that if you are using a DB9 RS232 Serial Port of your PC, you will have to build a
RS232 signal level converter at the microcontroller side to decode the RS232 signal.
Directly connecting the PC's RS232 Serial port to MSP430 's pins will damage the chip.
Here is the screen shot of the Program writing into serial port.

Reading from the Serial Port


Reading from the serial port is accomplished by the ReadFile() function.

One way to do that is to use polling where the ReadFile() continuously reads from the serial port
and checks for any received characters.
Other way is to setup an event and let windows notify us when a character is received.

We are going to use the second method here, following are the steps.

1. Create an Event for a particular action like character reception, change in modem lines etc
using SetCommMask() function .
2. Ask windows to wait for the event set by SetCommMask() function using WaitCommEvent()
and notify us when the condition happens.
3. Call ReadFile () to read the received data from the Serial port.

Functions used are

SetCommMask() is used to set the events to be monitored for a communication device. Here
we are going to set the event as character received (EV_RXCHAR).The function takes two
arguments, Handle of the serial port (hComm) and the code for the event (EV_RXCHAR) to be
monitored.
Status = SetCommMask(hComm, EV_RXCHAR);

WaitCommEvent() is used to wait for the events set by SetCommMask() to happen, in this
case reception of a character. The flow of execution of the program stops and the program waits
until a character is received.   

DWORD dwEventMask; 
Status = WaitCommEvent(hComm, &dwEventMask, NULL);  

dwEventMask contains a hex value indicating the event, which has caused WaitCommEvent()
to return.

After WaitCommEvent() has returned, call ReadFile() function to read the received
characters from the Serial Port Buffer.

char TempChar; //Temporary character used for reading


char SerialBuffer[256];//Buffer for storing Rxed Data
DWORD NoBytesRead;
int i = 0;

do
 {
   ReadFile( hComm,           //Handle of the Serial port
             &TempChar,       //Temporary character
             sizeof(TempChar),//Size of TempChar
             &NoBytesRead,    //Number of bytes read
             NULL);

   SerialBuffer[i] = TempChar;// Store Tempchar into buffer


   i++;
  }

while (NoBytesRead > 0);

ReadFile() function is similar to the WriteFile() function we had seen earlier,instead of writing we
are reading from the serial port.

&TempChar Temporary variable used to store the byte read from serial port buffer.

sizeof(TempChar) used to calculate the number of bytes to read.

&NoBytesRead Bytes successfully read by the ReadFile().

Now in the Zip File containing the source codes you can find “USB2SERIAL_Read_W32.c” which
contains the complete code for writing into serial port. You can compile the code using Visual
Studio Express or GCC.

On running “USB2SERIAL_Read_W32.exe” ,The code will wait for the characters to be


transmitted by the microcontroller.
Reset the Micro controller to transmit the string “Hello from MSP430”.

Check out our next section, If you want to know how to control the RTS and DTR pins of the
serial port .

Back to Serial Programming Tutorials 

You might also like