关于MSCOMM控件的一些说明

关于MSCOMM控件的一些说明关于MSCOMM控件的一些说明。VB 5.0/6.0的MSComm通信控件为标准通信命令提供了一系列接口。它允许串口连接,可以连接到其他通信设备(如调制解调器)。它还可以发送命令、交换数据、监控和响应通信过程中可能出现的各种错误和事件,从而可以用来创建全双工、事件驱动、高效实用的通信程序。然而,在实际的通信软件设计过程中,MSComm控件并没有想象中的那么完善和容易控制,尤其是在中文WLN 95/98下通信时。下面是基本介绍,再逐步讨论MSComm控件在编程中的问题和编程技巧。1.与MSComm控件1的通信。串行通信基础知识一般较好。计算机有一个或多个串行端口,分别是com1、Com2、反过来。这些串行端口还为外部设备和PC之间的数据传输和通信提供通道。这些串行端口充当CPU和外设之间的解释器。当字符数据从CPU发送到外设时,这些字符数据将被转换成串行位流数据;当接收数据时,比特流数据被转换成字符数据并传送到CPU。再者,在操作系统方面,Windows使用通信驱动程序(COMM.DRV)调用API函数来发送和接收数据。当用通信控制或声明调用API函数时,它的门由通信DRV解释并传送到设备驱动程序。作为一个vB程序员,你应该写通信程序。你只需要知道通信控件给Windows通信API函数提供的接口。变化2。在开始使用MSComm控件之前,请先使用Mscomm控件。你需要先知道它的属性,事件或者错误属性描述。CommPort设置或返回通信端口号设置。以字符串形式设置或返回波特率、奇偶校验、数据位和停止位。设置或返回通信端口的状态。还可以打开和关闭端口输入,返回和删除接收缓冲区的字符输出,将字符串写入发送缓冲区。对于通信事件或错误,vent属性返回下列值之一。这些常数也可以在该控件的对象库中找到。常量描述ComEventBreak1001收到断开信号comeventcts to 1002 CleartosendTimeout。当发送字符时,CTS(ClearToSend)行是系统指定的一个事件内的低级ComeventDSRTO 1003 datasetreadyTimeout。当发送字符时,DSR(DataSetReady)行是一个低级的ComEventFrame1004数据帧错误内的事件,由系统指定。硬件检测到一个数据帧错误。ComEventOverrun1006端口溢出。硬件中的字符没有被读取,下一个字符再次到达,并且事件到1007载波检测时间丢失。发送字符时,CD(CarrierDetect)行在系统指定的事件内处于低电平。CD也称为RLSD(ReceiveLineSingalDetect)comeventrcover 1008接收缓冲区溢出。接收缓冲区中没有空间。ComEventRxParity1009奇偶错误。硬件检测到奇偶校验错误7 ComEventTxFull1010发送缓冲区已满。将发送字符排队时,发送缓冲区已满。当ComEventDCB1011获取端口DCB(DeviceControlBlick)时,会出现意外错误。该事件包含以下设置:常量值描述ComEvSend1的发送缓冲区中的字符数小于Sthreshold的值。ComEvReceive2接收到Rthreshold个字符。该事件一直持续到输入属性用于删除接收缓冲区中的数据,ComEvCTS3CTS(ClearToSend)行发生变化,COMEVSDR 4DSR(数据集就绪)行发生变化。当DSR从1变为0时,会发生此事件。comevcd 5d CD(carrier detect)行更改。ComEvRing6检测响铃信号。一些URAT(通用异步收发器)不支持此事件。ComEvEOF7收到EOF字符(ASCII字符26)错误消息(MSComm控件)下表列出了MSComm控件可以捕获的错误消息:常量值描述ComInvalidPropertyValue380无效属性值ComSetNotSupported383属性只读ComGetNotSupported394属性只读ComPortOpen8000当端口打开时,存在无效的8001超时设置。ComPortInvalid8002无效端口号8003属性仅在运行时有效。8004属性在运行时是只读的。ComPortAleadyOpen8005端口已经打开。8006设备标识符无效或8007不受支持。不支持设备8008的波特率。指定的字节大小无效8009。默认参数错误8010硬件不可用(被其他设备锁定)8011功能无法分配队列ComNoOpen8012设备未打开8013设备已打开8014无法使用通信通知ComSetCommStateFailed8015无法设置通信状态8016无法设置通信事件掩码ComPortNotOpen8018此端口打开有效时只有8019设备忙。ComReadError8020通信设备读取错误。ComDCBError8021检索端口设备控制块时出现内部错误。弄清楚以上基本属性后,就可以开始写通讯程序了。在VB5.0/6.0中创建新的项目文件。添加MicrosoftCommControl5.0组件,在简化的Form1中添加Command命令按钮并命名为CmdTest,MSComm控件命名为MSComm1,并添加以下程序代码。PrivateSubcmdTestClick()打开串行MSComml。CommPort=2 并设置com 2 ifms CML . port open=false然后mscomm1.settings= 9600,n,8,1 9600波特率,无校验,8位数据,1个停止位mscomm1。PortOpen=True 打开串行端口Endif MSComm1。OutBufferCount=0 空发送缓冲区MSComm1。InBufferCount=0 滑动接收缓冲区。发送字符数据时,注意以回车(vbcr)结束mscomm1。output= thisisaqoodbook!vbCr拨打电话号码或发送AT命令MSComm 1 . output= atdt 05778191898,VBCR发送字符数组数据时注意ByteArray。必须预先定义赋值DimByteArrayasbyte()。定义动态数组ReDimByteArray(1)重新定义数组大小bytearray(0)=0 bytearray(1)=1 mscom m1 . output=bytearray end subprivatesubmscomevent()selectmscomm 1 . commevent casecomvreceive dimbufferasvariant mscomm1 . input len=0 接收二进制数据MSComm 1 . input mode=cominputmodebinarybuffer=MSComm 1 . input .接收的字符数据MSComm 1。输入模式=cominputmodetextbuffer=mscomml。输入case else end select end sub(程序1)二。中文WIN 95/98下的通信问题及解决方法。1.接收的数据少于发送的数据。如果通过MSComm控件一次传输更多的二进制数据,很可能是接收的数据不足。例如,如果传输速率设置为24000 bps,一次可以传输2048个字符的数据,那么在大多数情况下。一次只能接收1200个左右的字符。这个地址是MSComm32的新版本。OCX,还有一个bug)。这会影响二进制数据的传输。注意,这不是一个特性。32位WindowsAPI函数(以下简称API)使用了几个由COMMTIMEOUTS结构表示的限时变量,WriteTotalTimeOutConstant就是其中之一。它被Windows内部设置为5000(即5秒)。该常数决定了在通信驱动程序停止传输之前,在缓冲区中发送数据所花费的时间。5秒意味着通信速度1200bps时只能发送600个字符,通信速度2400 bps时只能发送1200个字符左右。事实上,一次在一个缓冲区中发送更多数据是非常可能的。这个bug也会导致问题,即使在高速串口通信的情况下,即使系统使用的是流量控制系统,无论是软件流(Xon/XofI)还是硬件流(CTS/RTS)。如果流量控制在数据处于发送缓冲区时停止传输,如果停止时间超过5秒,数据将会丢失。在某些情况下,5秒钟可能很短。不过不用担心,VB5.0/6.0中的MSComm控件有一个重要的新属性叫做CommID。CommID指的是串口打开时API调用的串口句柄或标志,也意味着这个常量可以被API接口函数修改。每次关闭串口,Windows都会自动恢复到5000。因此,打开串口后,需要再次设置下面的API语句。有关其代码,请参见以下程序。type commtimeouts ReadIntervalTimeoutAsLong ReadTotalTimeoutMultiplierAsLong ReadTotalTimeoutConstantAsLong WriteTotalTimeoutMultiplierAsLong write total time out constantaslong end type DeclareFunctionSetCommTimeoutsLib kernel 32 (byvalhfileslong,lpcommtimeoutascommtouts)as long DeclareFunctionGetCommTimeoutsLib kernel 32 (byvalhfileslong,lpcommtimeoutascommtouts)as long dimtimeoutascommeuts DimRetAsLong if comm 1 .PortOpen=FalseThen Comm1。port open=True Endif Ret=GetCommTimeouts(com m1。CommID,time outs) setsomedefaulttimes超时。ReadIntervalTimeout=1超时。ReadTotalTimeoutMultiplier=1超时。ReadTotalTimeoutConstant=1超时。write totalti out multiplier=1 timeouts . writetotaltimeoutconstant=(com m1 . out buffer size val(com m1 . settings))* 10000 1000 ret=setcommtimeouts(com m1 . commid,time outs)(程序2)2.如何发送大于128的字符数据?在通信程序中,以单字符方式逐个发送数据时,每个数据范围为0-255(即十六进制的00-FF)。在英文Win95或DOS版BASIC程序的单字符版本中,只需将相应的数据转换成相应的字符,发送到通讯口即可。但是在中文Win95/98下就不行了。假设下面的程序运行在中文Win95/98下:dimi fori=0 to 255 mscom m1 . output=chr(I)nexti。希望在接收端得到0到255之间的预期数据,但结果是:前129个数据接收正确,是0-128,后127个数据是126个0和1个255。造成这个结果的原因是中文Windows使用双字节字符集(DBCS)系统。DBCS系统使用0到128之间的数字来表示ASCII字符。大于128的数字仅用作前导字符。只说明是非拉丁字符,不代表实际意思。上面的程序在调用CHR()函数时使用了DBCS字符集,导致了这样的错误。那么,128的人的数据怎么发呢?答案是用一个字符数组,上面的程序改为:dimcc(255)asbytefori=0 to 255 cc(I)=inextimscomm 1 . output=cc do events loopuntilmcom 1 . outbuffercount=0 接收进程MSComm 1 _ on com()selectcasemscomm 1。CommEvent CasecomEvReceive DimBufferAsVariant,b1,i MSComm1。input mode=comInputModeBinery MSComm 1。InputLen=0 Buffer=MSComm1。输入Fori=LBound(缓冲区)ToUBound(缓冲区)Debug。print buffer(I);Nexti案例.3.如何发送0字符(00H,NULL)在Visuai C++中使用串口控件发送0字符比较麻烦,但在VB5.0/6.0中,只需注意以下两点:(1)设置MSComm控件NullDiscard=False的属性;(2)使用二进制接收,即MSComm1。InputMode=CominputModeBinary可以解决问题;4.如何发送和传递中文字符串(DBcS字符)VB5.0/6.0中各种参考书都说明MSComm通信控件不能发送或接收双字节字符集系统(DBCS)的二进制数据,这对于中国和亚洲一些使用DBCS字符集的国家来说是一大遗憾。但是在实际操作中,我发现MSComm控件也可以发送汉字。具体方法有两种:(1)直接发送,即汉字等同于英文字符。比如:mscomm1.input=这是一行中文数据!但是这种方式发送的中文数据不能太长。发送缓冲区和接收缓冲区的大小应设置为汉字的两倍以上,并且发送和接收系统的操作系统版本应一致,否则会出现接收或发送缓冲区溢出等错误。这种方法通常用在一般要求不太高的场合。(2)在发送端间接传输一个将汉字或字符转换成机器内码或区号的数据数组,然后将转换后的数据发送到串口。在接收端接收到数据后,将逆序获得的数据转换成相应的汉字或字符。在转换过程中需要进行位操作,比如获取汉字内码后将高字节和低字节分开,但VB5.0/6.0中没有提供这种功能。下面是求整数。PublicFunctionHiByte(aAsInteger)Dimb b=aandhf00 b=b/256 if B0 thenb=b 256 HiByte=b end functionPublicFunctionLowByte(aasinteg ` er)Dimb b=aandhhff low byte=b end function5.如何测试与单台计算机的通信,通常需要两台PC机或一台pc机和一台单片机在编写好通信程序后进行。连接通信端口后,进行测试。但是很多情况下由于条件限制只有单台PC,测试项目很简单,那么能测试吗?当然,而且方法很简单。对于九针串口,找一个废弃的串口鼠标,把外接鼠标线剥掉,把连接两三针的线连上。对于25针串口,找一个回形针(最好有塑料套)拔直。两端的塑料去掉后,两端各弯一圈,居中后直接套在串口的2或3针上。但如果心脏不够安全,可以往地上按5针。MSCOMM控件是个好东西。如果你能充分理解它,它会全心全意为你服务。简单看了一下下午讨论MSCOMM的话题,觉得有必要说一下心里话。一般只做硬件,没有系统学过软件。我只是在业余时间学着用,也掌握了一点,就来玩玩。不知道对不对,但我觉得我做得很好_这是一个VB通用串口事件驱动接收器。一次接收一个数据包,数据包可以是任意字节,保证不丢失任何数据!privatesubmscom _ oncom()DimS()as byte DimSS(1024)as byte static naslong stat variantIf(MSComm . commevent=comevreceive)Then s=MSComm . input 只要有数据,就取进去,哪怕只有一个If(Timer-T0.01)Then 间隔大于10MS,就认为是新的包。Text1= Text1用于收集和显示接收情况(十六进制格式)。N=0endif t=定时器fori=0touband (s)。一个数据包可能会生成多个oncomm事件text 1 . text=text 1 . text right( 0 hex(s(I)) h ,3) ss (n i)=s (i)接收到的数据包缓存在ss()n=nubound(s)nexti endif end sub中。

关于MSCOMM控件的一些说明