Welcome to Scribd, the world's digital library. Read, publish, and share books and documents. See more
Standard view
Full view
of .
Look up keyword
Like this
0 of .
Results for:
No results containing your search query
P. 1
Serial Port Communication

Serial Port Communication



|Views: 4,183|Likes:
Published by api-3738664

More info:

Published by: api-3738664 on Oct 15, 2008
Copyright:Attribution Non-commercial


Read on Scribd mobile: iPhone, iPad and Android.
download as DOC, PDF, TXT or read online from Scribd
See more
See less





This article is meant to give you a jump start on doing serial communication inWindows (NT family). The article will provide a class called CSerialCommHelperwhich you can use directly to do serial communication in your application. The classthat is provided here with this article does uses overlapped IO. You donot need toknow much about serial communication or overlapped IO for this article. However,you need to know some about the synchronization objects like Events and someWindows APIs like WaitForSingleObject and WaitForMultipleObject etc. Also somebasic understanding of windows threads is required - like thread creation andtermination.
In order for your computer to be able to do serial communication, computer has tohave a serial port. Most of the computers have at least one serial port also known asCOM port ( communication port ) and are generally called COM1 COM2 etc. Thenthere are the device drivers for the serial ports. If you think it over, all you that youneed to do in serial communication is either send data or receive data. In otherwords, you are doing input/output (IO) to the serial port. The same IO is done withdisk based files. Hence there is no surprise that the APIs for reading and writing to afile apply to serial ports as well. When you send data to the serial port its in terms of bytes but when it leaves the serial port it is in the form of bits. Similarly, when thedata arrives at the serial port, its in bit format and when you get data you get it inbytes.Without any further discussion lets get started.
Opening the COM port
The first and the foremost step in doing a serial communication is to open thedesired port. Lets say you have your device hooked to COM1 you can open the COMport using following API:
HANDLE m_hCommPort = ::CreateFile(szPortName,GENERIC_READ|GENERIC_WRITE,
//access ( read and write)
//(share) 0:cannot share the COM port
//security (None)
// creation : open_existing 
// we want overlapped operation
// no templates file for COM port...
The third fifth and seventh parameters have to be what they are in the aboveexample by law. We want to open the file ( the COM port ) in an overlapped fashion -that's why the sixth param is
. We will get into the details of overlapped IO a bit later. As you must have guessed from the name ,
API can be used to create a file (disk based) and also it can be used to open anexisting file.
To Windows a serial port or a disk based file both are IO devices . So, in order toopen an existing file ( serial port ) all we need to know the name of the device( COM1) and pass the creation flags as
.If a COM port is opened successfully, the API returns handle to the com port just likea handle to a file. However, if the system could not open the COM port, it wouldreturn
. And you can get the reason by calling
. One of the common errors while opening a COM port is that the COMport is already opened by some other application and in that case you would get
(5). Similarly if you by mistake opened a COM port thatdoesn't exist , you would get
as the last error.Note: Remember not to do make any function calls (like
) before calling
or you would get 0. Once you have opened the com port all you needto do now is to start using it.
Reading and Writing
Now, once you have a com port open, you may want to send some data to theconnected device. For example, lets say you want to send "Hello" to the device(e.g.,another PC). When you want to send the data across the serial port, you need towrite to the serial port just like you would write to a file. You would use followingAPI:
iRet = WriteFile (m_hCommPort,data,dwSize,&dwBytesWritten ,&ov);
where data contains "Hello" . Lets say in response to your "Hello" , the device sendsyou "Hi" . So you need to read the data. Again ,you would use following API:
abRet = ::ReadFile(m_hCommPort,szTmp ,sizeof(szTmp ),&dwBytesRead,&ovRead) ;
For now do not try to understand everything. We will get to all this later. All thissounds very simple. Right?Now lets start digging into issues.
Issues with serial communication
Just now I said, in response to your "Hello", the device may send you "Hi" back andyou would like to read that. But the problem here is that you don't know when thedevice is going to respond? Or will it ever respond? When should you start to readfrom the port. One option is that as soon as you made call to WriteFile, you makecall to ReadFile . If no data is there you need to make read again later on. This leadsto what is called polling. You keep polling the port for data. This model does notreally seem to be a good one. It would be nice if somehow you were notified by thesystem when data has arrived and only then would you make call to ReadFile. This isevent driven approach and fits well into Windows programming. And good news isthat such a model is possible .
Another issue with the serial communication is that since it always occurs betweentwo devices, the two devices need to agree on how they talk to each other. Each sideneeds to follow certain protocols to conduct business. Since its the serial port thatactually carries out the communication, we need to configure the serial port. There isan API available for exact same purpose. Following is the API:
SetCommState ( HANDLE hFile, LPDCB lpDCB)
The first parameter is the handle to COM port and the second paramter is what iscalled device control block (DCB) . The DCB is a struct defined in winbase.h and has28 data members. For example, we need to specify baud rate at which the COM portoperates, you need to set the BaudRate member of the struct . Baud rate is usual9600 (bps) . But the two devices have to use the same baud rate to conductbusiness. Similarly if you want to use parity you need to set Parity member of thestruct. Again the two devices have to use same parity. Some of the data membersare reserved and have to be 0. I have found it easier to get the current DCB structand then set those members which we are interested in changing. Following codegets the current dcb and sets some of the fields:
DCB dcb = {0};dcb.DCBlength =sizeof(DCB);if(!::GetCommState (m_hCommPort,&dcb)){TRACE ("CSerialCommHelper : Failed to Get Comm State Reason: %d",GetLastError()); returnE_FAIL;}dcb.BaudRate = dwBaudRate;dcb.ByteSize = byByteSize;dcb.Parity = byParity;if( byStopBits ==1) dcb.StopBits = ONESTOPBIT;else if(byStopBits ==2) dcb.StopBits = TWOSTOPBITS;else dcb.StopBits = ONE5STOPBITS;if(!::SetCommState (m_hCommPort,&dcb)){ASSERT(0);TRACE ("CSerialCommHelper : Failed to Set Comm State Reason: %d",GetLastError()); returnE_FAIL;}TRACE ("CSerialCommHelper : Current Settings, (Baud Rate %d; Parity %d; " "Byte Size %d; Stop Bits %d", dcb.BaudRate,
Most of the time you won't need to change the other fields of this structure. But if you need to change the structure you need to be very careful about the fields aschanging the fields will affect the behavior of the serial communication and henceyou should be very sure what you want to change.
Event Driven Approach

Activity (42)

You've already reviewed this. Edit your review.
cwl1945 added this note
The best website for Serial Comm I have encountered on the web. Great description and logically arranged. To get the other great site for Serial COMM use Google.com and search for "Microsoft serial communication" and home in on the article by Allen Denver. This article is the better of the two for a newbie. c
cwl1945 liked this
1 thousand reads
1 hundred reads
Giang Le liked this
Do Bo liked this
Do Bo liked this
Naser Husic liked this
dinu_2647 liked this

You're Reading a Free Preview

/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->