有关串口选择的出错处理!在线等!COMBOBOX

zd0428 2005-04-29 01:37:51
使用串口接收数据时, 先判断计算机有几个有效串口,通过COMBOBOX选择串口1、2、3 如果无效请提示错误信息。
...全文
385 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
samwzhang 2005-04-29
  • 打赏
  • 举报
回复
Option Explicit

Private Sub Form_Load()
On Error Resume Next
Dim i As Long
ComBo1.Clear
For i = 1 To 20 '心理最大值
If CheckComIsIn(i) Then
ComBo1.AddItem "Com" & i
End If
Next i
End Sub
Private Function CheckComIsIn(ComIndex As Long) As Boolean
On Error GoTo MyError
CheckComIsIn = False
MSComm1.CommPort = ComIndex
MSComm1.PortOpen = True

MSComm1.PortOpen = False
CheckComIsIn = True
MyError:
End Function
zd0428 2005-04-29
  • 打赏
  • 举报
回复
我以为用combobox选择一下 然后点击“打开串口”按纽command1
Private Sub Command1_Click()
If Not MSComm1.PortOpen Then
MSComm1.CommPort = Combobox1.Text
MSComm1.PortOpen = True
End If
End Sub
Private Sub Form_Load()
For i = 1 To 3
MSComm1.CommPort = i
Combo1.AddItem i
Next
end sub
你们看行吗,就是少了出错处理啊。我只有串口1是有效的,如果是别的就会出错提示,
并提示重新选择并检测有效串口。
zd0428 2005-04-29
  • 打赏
  • 举报
回复
好复杂 我好自卑啊 感觉自己什么也不懂
samwzhang 2005-04-29
  • 打赏
  • 举报
回复
设个心理最大值,再轮流portopen一下不就知道了
domhuang 2005-04-29
  • 打赏
  • 举报
回复
强烈关注
MmMVP 2005-04-29
  • 打赏
  • 举报
回复
Private Sub VerifySettings(Index As Long)
Dim disposition As Long
Dim sTmp As String
Dim iX As Long

iX = Index
On Error GoTo ErrTrap

sSettings = comPort(iX).Settings
sPortNum = comPort(iX).CommPort
sSubKey = "Software\Damage Inc\ComPort Utility"
If RegOpenKeyEx(lMainKey, sSubKey, 0, KEY_READ, hnd) Then
If RegCreateKeyEx(lMainKey, sSubKey, 0, 0, 0, 0, 0, hnd, disposition) Then
Err.Raise 1001, "VerifySettings() Sub", "Could Not Create Registry Key"
End If
End If

'The Key Has Been Found/or Created, Now Check To See If Previous Settings Are Present

'Check For The Settings Subkey and Retrieve Value If Present, Then Set ComPort 'Settings' Property

sKeyValue = Space$(lLength) 'Pad The sKeyValue Variable
If RegQueryValueEx(hnd, sSettingsKey & Chr$(iX + 65), 0, REG_SZ, ByVal sKeyValue, lLength) Then '0 Return OK
If RegOpenKeyEx(lMainKey, sSubKey, 0, KEY_WRITE, hnd) Then '0 Return if Successful
Err.Raise 1001, "VerifySettings() Sub", "Could Not Open Registry Key"
Else 'The Value Was Not Present, Set To Default Port 'Settings' Property
If RegSetValueEx(hnd, sSettingsKey & Chr$(iX + 65), 0, REG_SZ, ByVal sSettings, Len(sSettings)) Then
Err.Raise 1001, "VerifySettings() Sub", "Could Not Set Registry Key Settings Value"
End If
End If
Else 'Read Value From Key And Set The Port 'Settings' Property To The Value In The Registry
comPort(iX).Settings = sKeyValue
End If

'Check For The Port Subkey and Retrieve Value If Present, Then Set ComPort 'Port' Property

sKeyValue = Space$(lLength) 'Pad The sKeyValue Variable
If RegQueryValueEx(hnd, sPortKey & Chr$(iX + 65), 0, REG_SZ, ByVal sKeyValue, lLength) Then '0 Return OK
If RegOpenKeyEx(lMainKey, sSubKey, 0, KEY_WRITE, hnd) Then '0 Return if Successful
Err.Raise 1001, "VerifySettings() Sub", "Could Not Open Registry Key"
Else 'The Value Was Not Present, Set To Default Port 'Port' Property
If RegSetValueEx(hnd, sPortKey & Chr$(iX + 65), 0, REG_SZ, ByVal sPortNum, Len(sPortNum)) Then
Err.Raise 1001, "VerifySettings() Sub", "Could Not Set Registry Key Port Value"
End If
End If
Else 'Read Value From Key And Set The Port 'Port' Property To The Value In The Registry
comPort(iX).CommPort = sKeyValue
End If
RegCloseKey hnd
Exit Sub

ErrTrap:
MsgBox Err.Number & " " & Err.Description & vbCr & " Error Generated By " & Err.Source, vbCritical, _
"System Error Trap !"
End Sub



这段代码是读注册表得到串口数量的
aiur2000 2005-04-29
  • 打赏
  • 举报
回复
api中没找到啊,google查了下,懒得看了,看楼主有用没:
掌握串行通信API函数的用法是掌握串行通信编程技术的关键。在Win32中,系统将串行口与文件统一了起来,
对它们的打开、读写、关闭等操作都使用相同的API函数,但是它们之间又有差别,这些差别主要体现在API函
数中部分参数的设置上。有关通信的API主要包括打开串口、关闭串口、配置串口、设置缓冲区、设置超时、
事件驱动、读串口、写串口等。下面结合GPS的具体情况对串口操作函数的使用方法进行详细的介绍和分析。

一:串口的打开和关闭
1:串口的打开。由于在Windows环境中,串口作为一种文件来使用,打开串口用打开文件同样的API函数
CreateFile()。
函数原型为:
HANDLE CreateFile( LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile);
其中几个参数的含义分别为:
lpFileName指定文件名或设备名,串口通讯时,它必须是“COMx”,其中的“x”为串口编号,如第一个串口
则为“COM1”;dwDesiredAccess 为串口读写属性; dwShareMode指定该端口的共享属性,串行口不能作为共
享设备,故参数值必须为0;lpSecurityAttributes为安全属性,对于串口应该为0 ;
dwCreationDisposition指文件的创建模式,对于串口必须为OPEN—EXISTING;
dwFlagsAndAttributes描述了创建文件的其它属性,对于串行口,有效的设置只能是FILE-FLAG-OVERLAPPED
或者0,分别表示异步或同步读写;
参数hTemplateFile必须为NULL。
返回值:若成功,返回创建的句柄;否则返回INVALID—HANDLE—VALUE。

2:串口的关闭。关闭串口相对简单,通过关闭句柄BOOL CloseHandle(HANDLE hObject )函数进行,
hObject为打开串口时所得到的句柄。句柄关闭后,串口资源即释放,其它程序可以使用。

二:配置串口
串行口在打开后,将保持上一次使用的配置,要使之和外设进行通信,必须对串口进行配置,使之和外设保持
相同的串口配置,这样才能有效地配置外设并接收数据。在WIN32中,串口的配置主要通过一个称之为
COMMCONFIG的结构来实现,此结构包含了一个DCB结构,在DCB中,有波特率、数据位数、停止位、校验位等串
行口通信参数,对串口的配置主要即是对这些参数的配置。对COMMCONFIG进行配置的WIN32 API 主要有一下几
个:
1:获取默认配置函数。其原型为:
BOOL GetDefaultCommConfig( LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)
其参数如下:
LpszName为设备名,如“COM1”;
lpCC为COMMCONFIG结构体的指针。
LpdwSize是lpCC的大小。
通过使用此函数可以得到某串口的默认配置,此函数与机器硬件相关,在不同的机器上会有不同的结果,因而
容易出错,所以建议用户自己重写此函数,分别对COMMCONFIG的成员进行赋值,这样才稳定可靠。
2:得到串口的当前配置,原形如下:
BOOL GetCommConfig( HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize )
其参数同GetDefaultCommConfig();
3:配置串口
BOOL SetCommConfig( HANDLE hCommDev,LPCOMMCONFIG lpCC, DWORD dwSize);
此函数将由hCommDev指定的串口按lpCC结构体中的内容进行配置。LPCOMMCONFIG结构体中的主要成员是设备控
制块结构DCB,在DCB中指定了设备的波特率,奇偶校验位,流控,停止位等参数。
4:配置串口的对话框
BOOL CommConfigDialog(LPCSTR lpszName,HWND hWnd,LPCOMMCONFIG lpCC )
此函数提供了一个用户熟悉的串口配置对话框,其句柄为hWnd。用户可在此对话框中进行对lpszName指示的串
口配置,配置结果存放在lpCC所指向的COMMCONFIG结构体中。
5:设置缓冲区
WIN32环境下读写串口已经不是传统方式下针对串口的UART进行,而是提供一缓冲区,串口的读写都是针对于此
缓冲区进行。确定缓冲区的大小比较重要,太大浪费资源,太小又会使有效数据丢失。用户必须在串口读写前
计算出外设流量的大小,按照宁大勿小、有所冗余的原则确定合适大小的缓冲区,再使用SetupComm()函数对串
口进行设置。其原型如下:
BOOL SetupComm(HANDLE hFile,DWORD dwInQueue,DWORD dwOutQueue);
hFile为打开串口时所得到的句柄;
dwInQueue为输入缓冲区的大小,以字节为单位;
dwOutQueue为输出缓冲区的大小。
6:设置超时
数据通信过程中可能会发生的不可预测的事件,如数据传输电缆损坏、外设意外失效中断,或者发送数据突然
停止等等。通信应用程序的一个关键问题就是如何处理通信中的不可预测的事件,处理错误事件的能力是一个
通信应用程序优劣的重要标志。这些问题处理的不好可能会引起I/O线程挂起或者线程被无限阻塞。Windows对
于这类问题提供了安全措施,用户可以通过超时设置来决定通信是否异常并作相应处理。因此超时设置在串行
通信中显得尤为重要。在Win32中提供了SetCommTimeouts()函数设置串口的超时值。
BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
hFile为打开串口时所得到的句柄;
lpCommTimeouts为指向超时结构体的指针。
三:读写串口
在打开串口并对其进行正确地和必要的配置后就可以用它进行通信即读写数据。读数据就是接收输入,些
数据就是向外设发送数据。读写数据通过两个API函数完成。
1:读数据函数
BOOL ReadFile ( HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped data);
hFile是由CreateFile()返回的句柄;
lpBuffer是读取的数据缓冲区指针;
nNumberOfBytesToRead是要读取的字节数;
lpNumberOfBytesRead是实际读取的字节数的首地址;
lpOverlapped 是指向一个可重叠I/O(异步)的数据结构指针。如果lpOverlapped设置为NULL,则ReadFile()工
作在同步方式;如果lpOverlapped指向一个重叠结构,则工作在异步方式。不管是同步还是异步,
ReadFile()函数执行后将立刻返回。
2:写串口函数
BOOL WriteFile( HANDLE hFile,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped data);
其参数的意义与读串口相似。

四:工作模式
在串口读写操作时,存在多种操作模式,从同步控制角度讲,有同步和异步方式,从编程角度讲,有查询
方式和事件驱动方式。在同步读串口时,如果串口缓冲区中内容没有读完,系统将处于等待状态,直至读完才
返回;如果是异步读,即使缓冲区中没有读完,系统也将下行,执行下一句代码。如果串口的交互频繁,则宜
使用异步读写,但对于一般采集而言,主要是读数据,写命令不多,一次读取的数据量又不会太大,所以使用
同步较好,更易于控制。查询方式是指在一个无穷循环中直接读写串口数据,对于从串口读取数据来说,查询
是最为直接、最简单的方法,但是这种方法效率较低,要花费大量的CPU时间。事件驱动方式是指线程通过监
视通信资源中的一组事件来进行读写操作,这种方式类似于DOS下的中断工作方式,效率高。监视事件的工作
是通过SetCommMask()和WaitCommEvent()函数进行的。在读或写操作中可以通过SetCommMask()函数设置事件
屏蔽来监视指定通信资源上的事件,指定一组事件后,线程可以使用WaitCommEvent()函数等待其中一个事件发
生,在等待过程中线程将挂起,这样将花费极少的CPU时间,一旦有相应事件发生,WaitCommEvent()将返回,
告诉系统发生的事件,用户可以根据事件的内容确定相应的处理方式。在等待事件时,WaitCommEvent()函数将
独占串口,此时串口既不能读也不能写,读写工作必须等WaitCommEvent()函数返回后进行。
设置同步控制模式在打开串口时进行,由其第三个参数指定。
而在编程时采用事件驱动模式的函数有以下几个。

1:设置事件掩码
BOOL SetCommMask(HANDLE hFile,DWORD dwEvtMask);
其中hFile为打开串口的文件句柄。
DwEvtMask是设置的掩码,其形式和意义如下表所示
掩码 事件
EV_BREAK 在输入中检测到断点
EV_CTS CTS (clear-to-send) 信号改变状态
EV_DSR DSR (data-set-ready) 信号改变状态
EV_ERR 出现线路状态错误。
EV_RING 检测到振铃指示
EV_RLSD RLSD (receive-line-signal-detect) 信号改变状态
EV_RXCHAR 一个字符到达并存放于接收缓冲区
EV_RXFLAG 一个事件字符到达并存放于接收缓冲区,事件字符包含在设备的DCB中,由SetCommState 函数应用到串口
EV_TXEMPTY 发送缓冲区中的最后一个字符被送出

2:等待事件到来
BOOL SetCommMask(HANDLE hFile,DWORD dwEvtMask,LPOVERLAPPED lpOverlapped);
其参数意义与设置掩码相似。这个函数表示等待由SetCommMask()函数设置的事件的到来,在此函数工作时,串口处于阻
塞模式独占串口。
如果定义的事件到来,我们就可以采取相应的措施来处理。在数据采集时,通常设置的事件为:
EV_RXCHAR,在此事件到来时就可以读出接收缓冲区中的数据并交给后台线程处理。
如果使用的串口不止一个,则需要利用Win32的多任务特性。
zd0428 2005-04-29
  • 打赏
  • 举报
回复
那个API函数怎么用啊 高手再帮帮啊
aiur2000 2005-04-29
  • 打赏
  • 举报
回复
哦,还有这种api函数啊,555,我都是一个个试的
zd0428 2005-04-29
  • 打赏
  • 举报
回复
能不能详细点啊 不懂
qrlvls 2005-04-29
  • 打赏
  • 举报
回复
也就是枚举串口吧
参见API函数: GetDefaultCommConfig

1,453

社区成员

发帖
与我相关
我的任务
社区描述
VB 控件
社区管理员
  • 控件
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧