使用VB.NET简化COM端口
在Windows中使用COM端口,使用任何.NET语言
引言
本文介绍如何在Windows中控制COM端口。你不能像在DOS中使用Pascal或C++那样直接告诉计算机打开COM端口。但是,仍然有一些技巧可以打开和使用COM端口。唯一需要的是,你需要了解一些Windows知识——Win2k有一个HAL(硬件抽象层)。
首先,Windows 2000、Windows XP和Windows 2003具有受保护的硬件访问权限。这就是HAL。在安全性方面非常有用,但对于像我这样的程序员来说,这是一个噩梦。我找到了一个解决方案:让Windows为你完成这项工作。
我是怎么做到的?
我使用了一些基本的Windows函数来控制我的COM端口功能。
CreateFile
ReadFile
WriteFile
CloseHandle
BuildCommDCB
SetCommState
你可以在旧的VB6 API查看器程序中找到这些函数(或者你可以查看源代码)。
我只是告诉Windows帮我控制硬件。我会欺骗我的程序,让它认为COM端口是一个文件。这可以通过我使用的Windows API函数实现。
代码
我的代码的第一个函数是打开函数。该函数将尝试创建一个COM端口句柄。之后,我检查句柄是否正确。如果句柄正确,我将继续创建一个DCB结构实例以备使用。使用此结构,我们可以控制所有COM端口设置。(我只会使用速度、奇偶校验、停止位和数据位)
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
下一个函数是`Write`函数。此函数控制写入COM端口。我选择一次写入一个字节到COM端口,因为我想用我的COM端口控制一个微控制器。但是,你当然可以将其更改为多字节写入函数或添加一个额外的多字节函数。
Public Sub Write(ByVal data As Byte)
Dim dt As Byte()
Dim written As Integer
dt(0) = data 'We have a multi-byte buffer, which you can of
'course enable...
If Opened = True Then
WriteFile(hPort, dt, 1, written, Nothing)
Else
Throw New Exception("Comport not opened")
End If
dt = Nothing
End Sub
当然,我还想从COM端口读取数据。这是通过读取函数实现的。对于此函数,与`Write`函数一样,也可以添加多字节功能。Public Function Read() As Byte
Dim rd As Integer
Dim ovl As New OVERLAPPED
Dim dt As Byte()
dt = Array.CreateInstance(GetType(Byte), 1) 'Initialize the buffer
If Opened = True Then
ReadFile(hPort, dt, 1, rd, ovl)
Else
Throw New Exception("Comport not opened")
End If
Return dt(0)
End Function
最后,比打开函数更重要的是`Close`函数。此函数关闭COM端口并释放其系统句柄。如果我们在NT4/Win2k/XP/2003中不这样做,我们会遇到大问题。
Public Sub Close()
CloseHandle(hPort)
hPort = -1
m_opened = False
End Sub
结论
我希望我的英语说得不太糟糕,我的解释不太混乱。但最重要的是,我希望你玩得开心我的COM端口驱动程序!