Introduction
This article is about controlling the com port in windows. You can't just tell the computer to open the com port like you would with Pascal or C++ in DOS. But there are still some tricks that makes it possible to open and use the com port. The only thing is, you will need to know something about windows - Win2k has a HAL (Hardware Abstraction Layer).
First of all, windows 2000, windows xp and windows 2003 have protected hardware access. This is the HAL. Very useful when it comes to security, but for programmers like me it's a nightmare. I found a solution: Let windows do the job for you.
How did I make this?
I used some basic windows function for my com port controlling functionality:
CreateFile
ReadFile
WriteFile
CloseHandle
BuildCommDCB
SetCommState
You can find these functions in the old VB6 API Viewer program (Or you might take a look in the source of course).
I simply told windows to do the hardware controlling for me. I will trick my program that the com port is a file. This is made possible through the Windows API Functions I use.
The code
The first function of my code is the open function. The function will be trying to make a com port handle. After that I check if the handle is correct. If the handle is ok, I will continue by making a DCB Structure instance ready for use. With this structure we can control all comport settings. (I will only use, speed, parity, stop bits and data bits)
Public Sub Open(ByVal portname As String, _
ByVal Spd As Integer, ByVal Pty As enumParity, _
ByVal Dtb As Integer, ByVal Stp As enumStopBits)
Dim m_CommDCB As String
Dim m_Baud As String
Dim m_Parity As String
Dim m_Data As String
Dim m_Stop As Byte
hPort = CreateFile(portname, GENERIC_READ + GENERIC_WRITE, _
0, 0, OPEN_EXISTING, 0, 0)
If hPort < 1 Then
Throw New Exception("Can't open the comport! (Errorcode :" _
& GetLastError().ToString() & ")")
End If
m_Baud = Spd.ToString()
m_Parity = PARITYSTRING.Substring(Pty, 1)
m_Data = Dtb.ToString()
m_Stop = Stp
m_CommDCB = String.Format("baud={0} parity={1} data={2} stop={3}", _
m_Baud, m_Parity, m_Data, m_Stop)
BuildCommDCB(m_CommDCB, dcbPort)
If SetCommState(hPort, dcbPort) = 0 Then
Throw New Exception("kan de compoort niet openen(" & _
GetLastError().ToString() & ")")
End If
m_opened = True
End Sub
The next function is the Write
Function. This function controls the writing to the com port. I choose to write one byte at a time to the com port since I wanted to control a microcontroller with my com port. But you can change this of course to a multi-byte write function or add an extra function for multi-byte.
Public Sub Write(ByVal data As Byte)
Dim dt As Byte()
Dim written As Integer
dt(0) = data
If Opened = True Then
WriteFile(hPort, dt, 1, written, Nothing)
Else
Throw New Exception("Comport not opened")
End If
dt = Nothing
End Sub
Of course I also want to read from the com port. This is achieved by the read function. For this function the same story as for the
Write
function with the multi-byte add-on.
Public Function Read() As Byte
Dim rd As Integer
Dim ovl As New OVERLAPPED
Dim dt As Byte()
dt = Array.CreateInstance(GetType(Byte), 1)
If Opened = True Then
ReadFile(hPort, dt, 1, rd, ovl)
Else
Throw New Exception("Comport not opened")
End If
Return dt(0)
End Function
At last and more important than the open function we have the Close
function. This function closes the com port and releases the system handle to it. If we don't do this in NT4/win2k/xp/2003, we get big problems.
Public Sub Close()
CloseHandle(hPort)
hPort = -1
m_opened = False
End Sub
Conclusion
I hope my english wasn't too bad and my explaination not too chaotic. But above all, I hope you have fun with my com port driver!