Introduction
This Article covers the basics of programming and managing serial port RS232 communication using the Windows API. The Serial port communication is now almost obsolete but it is still used in computer to Micro controller communication. The Article assumes that you have basic knowledge about C/C++. We will be covering the following things here.- Opening the serial port
- Setting the serial port Properties
- Setting time outs
- Reading from serial port
- Writing to serial port
- Closing the Serial Port
Opening the serial port
Opening the serial Port is very easy if you have already worked with file I/O before. Include Windows.h and then use the following code to open Serial Port.| HANDLE hSerial; | |
| hSerial =CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, 0, 0, 0,                                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); | |
| if(hSerial == INVALID_HANDLE_VALUE) { | |
|   if(GetLastError() == ERROR_FILE_NOT_FOUND) { | |
|     cout<<"Port not found\n"; | |
|   } | |
| } |
Setting the serial port Properties
As we have a HANDLE to the serial port, we need to set parameters for it i.e., communication format baud rate etc.,dcbSerialParams.BaudRate=CBR_9600; dcbSerialParams.ByteSize=8; dcbSerialParams.StopBits=ONESTOPBIT; dcbSerialParams.Parity=NOPARITY;
| DCB dcbSerialParams = {0}; |
| if (!GetCommState (hSerial, &dcbSerialParams)) {
     cout<<"Error getting port state\n"; } |
| if (!SetCommState (hSerial, &dcbSerialParams)) {
     cout<<"Error getting port state\n"; } |
Now we need to set the parameters we care about. The important ones are the baud rate is the transfer rate (number of symbols per seconds) which can set to various predefined values e.g., 9600, 19200, 57600.
Byte size can be just specified directly, but stop bits and parity again need special constants.
There are loads of other fields in DCB structure that can be used for some other more obscure serial parameters. You can see the MSDN Library to know about them.
These settings are applied to serial port using SetCOmmState function
Setting timeouts
One big problem of Serial port communication is that if there is no data to be received than attempting to read from port can cause your application to hang while waiting for data to show up.This problem can be fixed by telling windows not too wait forever when no data shows up i.e., by setting out the timeout intervals
| COMMTIMEOUTS timeouts={0}; |
| timeouts.ReadIntervalTimeout=50;
timeouts.ReadTotalTimeoutConstant=50 timeouts.ReadTotalTimeoutMultiplier=10 timeouts.WriteTotalTimeoutConstant=50 timeouts.WriteTotalTimeoutMultiplie=10 |
| if (!SetCommTimeouts (hSerial, & timeouts)) {      cout<<"Error setting Tmeouts\n"; } |
- ReadIntervalTimeout specifies how long (in milliseconds) to wait between receiving characters before timing out.
- ReadTotalTimeoutConstant specifies how long to wait (in milliseconds) before returning
- ReadTotalTimeoutMultiplier specifies how much additional time to wait (in milliseconds) before returning for each byte that was requested in read operation.
- WriteTotalTimeout and WriteTotalTimeoutMultiplier do the same thing, just for writes instead of reads.
One special case that comes up pretty often is setting the ReadIntervalTimeout to MAXDWORD and both ReadTotalTimeoutConstant and ReadTimeoutMultiplier to zero. This casues read operations to return immediately if there is no data in buffer to be received.
After we have setup the COMMTIMEOUTS structure, we need to apply the settings to the serial port using the SetCommTimeouts function.
Reading from serial port
So once you have opened the port successfully and assigned it the desired paramters you can start doing the actual read.Suppose we want to read n bytes from the serial port. We just need to do this. char szBuff[n+1]={0};
DWORD bytesread=0;
if (!ReadFile(hSerial, szBuff, n, &bytesread, NULL)) {
    cout<<"Read error\n";
}
ReadFile takes in a HANDLE to a file (our serial port), a buffer to store the data in, number of bytes to read, a pointer to an integer that will set to number of bytes actually read, and NULL.
Note that bytesread will contain the number of bytes actually read by the ReadFile operation.
Writing to serial port
Writing data to serial port is exactly the same as ReadFile except the function is called WriteFile and n represents the number of bytes to write while bytesread is replaced by number of bytes actually writtenClosing the Serial Port
Once you are done using the srial port make sure you close the handle or no other program would be able to access the port and you will need to restart the Computer. to close the serial port just do thisCloseHandle(hSerial);
Some advanced Properties of Serial Port
There are some advanced properties related to serial port which are not used in normal cases. Nearly all advanced functions are accomplished using EscapeCommFunction(HANDLE, DWORD). In any event the first parameter is just the HANDLE to the serial port while DWORD represents the folloowing constants.- CLRDTR
- SETDTR
- SETRTS
- CLRRTS
- SETBREAK
- CLRBREAK
Download a sample program Here
No comments:
Post a Comment