t e m p o r a l 
 d o o r w a y 

Opening And Setting Up The Serial Port

 

It's not very hard to open and work with a serial port. The following example shows how to open the serial port as a file and set its parameters using the DCB.

Note: The variables SerialPort, BaudRate, Parity, BitsPerByte, StopBits, HardwareHandshaking, PortDesignator and WriteMode are presented with this code, but would normally be part of a header file or class definition.

typedef enum{COM1,COM2} PortDesignatorType;
typedef enum{None,Even,Odd,Mark} ParityType;
typedef enum{OneBit} StopBitsType;
typedef enum{Threaded,EchoHandshake,Dialog} WriteModeType;

PortDesignatorType        PortDesignator = COM1;
int                       BaudRate = 19200;
int                       ByteSize = 8;
ParityType                Parity = None;
StopBitsType              StopBits = OneBit;
int                       TimeOutInSeconds = 0;
bool                      HardwareHandshaking = true;
WriteModeType             WriteMode = Threaded;

AnsiString CommPort = (PortDesignator == COM1 ? "COM1" : "COM2");

HANDLE SerialPort =
    CreateFile
    (
      CommPort.c_str(),
      GENERIC_READ | GENERIC_WRITE,
      0, /* comm devices must be opened w/exclusive-access */
      NULL, /* no security attrs */
      OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
      WriteMode == Threaded ? FILE_FLAG_OVERLAPPED : FILE_ATTRIBUTE_NORMAL, /* Ansynchronous or Synchronous I/O   */
      NULL /* hTemplate must be NULL for comm devices */
    );

if (SerialPort == INVALID_HANDLE_VALUE)
{
    Application->MessageBox("Unable to open serial port","Error",0);
    return;
};

DCB    DeviceParameter;

GetCommState((void *) SerialPort,&DeviceParameter);

DeviceParameter.BaudRate = BaudRate;
DeviceParameter.ByteSize = ByteSize;

switch (Parity)
{
    case None: DeviceParameter.Parity = NOPARITY; break;
    case Even: DeviceParameter.Parity = EVENPARITY; break;
    case Odd: DeviceParameter.Parity = ODDPARITY; break;
    case Mark: DeviceParameter.Parity = MARKPARITY; break;
};

switch (StopBits)
{
    case OneBit: DeviceParameter.StopBits = ONESTOPBIT; break;
};

DeviceParameter.fParity = (Parity != NOPARITY);
DeviceParameter.fBinary = TRUE;

if (HardwareHandshaking)
{
}
else
{
    DeviceParameter.fOutxCtsFlow = FALSE; // CTS output flow control
    DeviceParameter.fOutxDsrFlow = FALSE; // DSR output flow control
    DeviceParameter.fDtrControl = DTR_CONTROL_DISABLE; // DTR flow control type
    DeviceParameter.fDsrSensitivity = FALSE;
    DeviceParameter.fRtsControl = RTS_CONTROL_DISABLE; // RTS flow control
    DeviceParameter.fInX = TRUE;
    DeviceParameter.fOutX = TRUE;
    DeviceParameter.fTXContinueOnXoff = FALSE;
    DeviceParameter.fNull = FALSE;
    DeviceParameter.XonLim = 10;
    DeviceParameter.XoffLim = 10;
};

DeviceParameter.fAbortOnError = FALSE;
DeviceParameter.wReserved = 0;

SetCommState((void *) SerialPort,&DeviceParameter);

COMMTIMEOUTS CommTimeOut;

GetCommTimeouts((void *) SerialPort,&CommTimeOut);

CommTimeOut.ReadIntervalTimeout = (int) (TimeOutInSeconds * 1000);

SetCommTimeouts((void *) SerialPort,&CommTimeOut);


Note that a ReadIntervalTimeout is specified, allowing for partial transmissions from a device to be detected.

Also note that this code allows for threaded / overlapping I/O operations on the port.

For more information, see Help\MSHelp\Win32.hlp under "Communications".

Copyright © 2004 by Mark Cashman (unless otherwise indicated), All Rights Reserved