⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 190.htm

📁 一些简单的编程例子 都是网页的形式
💻 HTM
字号:
<p>使用Visual Basic开发通讯软件</p>
<p></p>
<p>一、pc串行通信程序机制 </p>
<p></p>
<p>常用的pc串行通信程序大多利用biosint14h中断,以查询i/o方式完成异步串行通信。 </p>
<p></p>
<p></p>
<p>windows系统提供中断方式驱动的串行通信驱动程序comm.drv。通信程序无需直接对串行端口进行操作,而是通过驱动程序这一编程接口进行间接操作。 </p>
<p></p>
<p></p>
<p>windows操作系统中,串行通信采用“事件通知”方式,支持数据按块传送。进行通信时,windows开辟一个用户定义的输入输出缓冲区,每接收一个字符就产生一个低级硬件中断,串行驱动程序立即取得控制权,并将字符放入输入数据缓冲区,然后将控制权返还正在运行的应用程序。如果输入数据缓冲区满了,驱动程序用当前定义的流控制机制通知发送方停止发送数据。发送数据也采用类似的处理方式,应用程序将需要发送的数据放入输出数据缓冲区,串口每发送一个字符就产生一个低级硬件中断。 </p>
<p></p>
<p></p>
<p>二、pc串行口远程通信的硬件配置 </p>
<p></p>
<p></p>
<p>串行通信数据链中,计算机一端称为dte,即数据终端设备;调制解调器一端称为dce,即数据通信设备。pc串行通信的硬件连接方式分为零modem连接和modem连接。 </p>
<p></p>
<p></p>
<p>零modem连接即直接用调制解调器电缆将两台设备连接起来,modem连接则通过dce(modem)将两台pc连接起来。 </p>
<p></p>
<p></p>
<p>零modem连接用于距离15m内两台dte或dce设备之间的连接。而modem连接则通过电话网或专线用于长距离的通信。 </p>
<p></p>
<p></p>
<p>txd和rxd信号线用于计算机和modem间传输数据信息;rts从计算机端发送信号到modem,表示希望把数据传给modem,若modem能接收这个数据,它将发送cts信号给计算机;dtr从计算机端发送信号到modem,表示计算机已作好通信准备,modem将dtr信号作为初始化自己的信号,然后给计算机回送数据设置就绪信号dsr;当本地modem接收到远地modem的呼叫,则发送ring信号给计算机;modem应答呼叫后,发送数据载波检测dcd信号到计算机,表示已建立连接。 </p>
<p></p>
<p></p>
<p>modem的工作状态分为命令状态和在线状态。处于命令状态时,modem对串口发送的信息进行解释,可通过pc串口向modem发送at命令对其进行初始化、设置和操作。 </p>
<p></p>
<p></p>
<p>例如,初始化命令为:“atqov1wosoκ1&c1&d2&yo&wo”,其含义为: </p>
<p></p>
<p></p>
<p>qo:返回结果码; </p>
<p></p>
<p></p>
<p>v1:以字符形式显示结果码; </p>
<p></p>
<p></p>
<p>wo:不返回协商进程结果码; </p>
<p></p>
<p></p>
<p>soκ1:振铃一次,即应答; </p>
<p></p>
<p></p>
<p>&c1:追踪数据载波信号cd; </p>
<p></p>
<p></p>
<p>&d2当dtr从开到关时,modem挂机进入命令状态; </p>
<p></p>
<p></p>
<p>&yo:modem上电时重新调出用户方案; </p>
<p></p>
<p></p>
<p>&wo:将以上设置存为动态设置用户方案0; </p>
<p></p>
<p></p>
<p>一旦本地modem与远地modem建立连接,modem即处于在线状态,可进行数据传输。此时,modem不响应at命令,直接传送所收到的数据。 </p>
<p></p>
<p></p>
<p>三、modem连接远程通信软件的编制 </p>
<p></p>
<p></p>
<p>通信过程中大部分的工作由串行通信驱动软件承担。 </p>
<p></p>
<p></p>
<p>本文软件的运行环境为ast+4/66d,hayes公司的accura144+fax144modem,windows3.2,vb3.0专业版。vb3.0专业版中提供了一个mscomm.vbx通信控件。它使用户能很方便地通过对控件属性的设置、检测,访问串行通信驱动程序的大多数特性,而不必考虑其实现细节。该控件为“事件驱动”,只响应“oncomm”事件,该事件可对已发生的事件或错误进行处理,与commevent属性紧密相关。 </p>
<p></p>
<p></p>
<p>通信软件、通信驱动软件和modem之间的通信关系 </p>
<p></p>
<p></p>
<p>以下程序实现了通信的基本过程。包括初始化串口和modem,上位机拨号呼叫下位机,下位机应答并开始定时传输数据,挂机停止传输等功能。 </p>
<p></p>
<p></p>
<p>vb3.0编制的通信软件清单如下: </p>
<p></p>
<p></p>
<p>上位机控件清单: </p>
<p></p>
<p></p>
<p>控件名称 属性 </p>
<p></p>
<p></p>
<p>form1form1caption ″上位机通信″ </p>
<p></p>
<p></p>
<p>mscomm comm1 </p>
<p></p>
<p></p>
<p>commandbutton1callcaption ″拨号″ </p>
<p></p>
<p></p>
<p>commandbutton2hangcaption ″挂机″ </p>
<p></p>
<p></p>
<p>commandbutton3exitcaption ″退出″ </p>
<p></p>
<p></p>
<p>下位机控件清单 </p>
<p></p>
<p></p>
<p>控件名称 属性 </p>
<p></p>
<p></p>
<p>form1form1caption ″下位机通信″ </p>
<p></p>
<p></p>
<p>mscomm comm1 </p>
<p></p>
<p></p>
<p>commandbutton1hangcaption ″挂机″ </p>
<p></p>
<p></p>
<p>commandbutton2exitcaption ″退出″ </p>
<p></p>
<p></p>
<p>timer1timer1interval 3000 </p>
<p></p>
<p></p>
<p>text(i)text(i) </p>
<p>使用Visual Basic开发通讯软件 </p>
<p></p>
<p></p>
<p>[enet学院] </p>
<p></p>
<p></p>
<p><<<上一页 </p>
<p></p>
<p></p>
<p>1.串口初始化、设置程序 </p>
<p></p>
<p></p>
<p>在程序初始化时,先对串口初始化。因为使用rts/cts握手信号的硬件设备只有rts信号置为高才能接收数据,所以需将mscomm通信控件的rtsenable属性设为true。由于modem在处于命令状态时,通过串口发送的命令以及命令结果均会回显在输入缓冲区中,因此在进入在线状态前,禁止产生ev-receive事件,避免数据误处理。 </p>
<p></p>
<p></p>
<p>由于windows是多任务系统,在进行数据收发循环处理时,应调用doevents事件,将控制权交还系统,允许windows执行其他任务。但应注意,在处理oncomm事件时小心使用doevents,避免系统又产生oncomm事件,造成嵌套,出现堆栈溢出错误。 </p>
<p></p>
<p></p>
<p>sub form-load() </p>
<p></p>
<p></p>
<p>comm1.commportκ1′com1口通信 </p>
<p></p>
<p></p>
<p>comm1.settingsκ″9600,n,8,1″′波特率9600,无校验,8位数据位1位停止位 </p>
<p></p>
<p></p>
<p>comm1.outbuffersizeκoutpack′设置输出缓冲区大小 </p>
<p></p>
<p></p>
<p>comm1.inbuffersizeκinpack′设置输入缓冲区大小 </p>
<p></p>
<p></p>
<p>comm1.inputlenκ1′每次从输入缓冲区中取一个字符 </p>
<p></p>
<p></p>
<p>comm1.rtsenableκ-1′rts信号为高 </p>
<p></p>
<p></p>
<p>comm1.rthresholdκ0′不产生mscomm-ev-receive事件 </p>
<p></p>
<p></p>
<p>comm1.portopenκ-1′打开串口 </p>
<p></p>
<p></p>
<p>cdκcomm1.cdholding′取载波检测信号线原始状态 </p>
<p></p>
<p></p>
<p>comm1.outputκ″atqov1wosoκ1&c1&d2&yowo″′初始化modem </p>
<p></p>
<p></p>
<p>do doeventsloopuntilcomm1.outbuffercountκ0 </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>2.上位机拨号呼叫下位机 </p>
<p></p>
<p></p>
<p>subcallcom-click() </p>
<p></p>
<p></p>
<p>comm1.outputκ″atdt″&phonnum$&chr$(13)′向modem发拨号命令 </p>
<p></p>
<p></p>
<p>do doeventsloopuntilcomm1.outbuffercountκ0 </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>3.下位机modem应答,连通后开始定时传输数据 </p>
<p></p>
<p></p>
<p>下位机检测cd,判断是否连通: </p>
<p></p>
<p></p>
<p>sub comm1-oncomm() </p>
<p></p>
<p></p>
<p>select casecomm1.commevent </p>
<p></p>
<p></p>
<p>case5 ′mscomm-ev-cd </p>
<p></p>
<p></p>
<p>timer1.enabledκ-1′启动定时器 </p>
<p></p>
<p></p>
<p>end select </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>vb传送定长字符串,数据接收处理相对简单。但在发送实时数据时,若将数据转换成定长字符串,这样会大大降低传输效率。在接收端,通知程序从输入缓冲区中取字符有两种方法:一是用轮询方法循环判断inbuffercount是否为0;另外就是利用rthreshold属性触发“oncomm”事件及“commevent”属性中ev-receive事件。当rthreshold的值不为0时,允许产生ev-receive事件。该属性设置和返回在通信控件设定commevent特性为接收和产生oncomm事件之前要接收的字符数。vb传送变长字符串时,接收端的rthreshold值要作相应的改变,以确保接收数据及时准确。 </p>
<p></p>
<p></p>
<p>下位机定时发送字符串“strin3$κformat$(len(strin1$),″0000″)&chr$(8)&strin2$”。strin1$为当前字符串,strin2$为上一字符串。上位机根据接收strin3$中len(strin1$),相应改变rthresholdκlen(strin1$)+4。这样,通过提前发送字符串长度,改变rthreshold值可实现发送变长数据。 </p>
<p></p>
<p></p>
<p>windows串行通信驱动程序的事件驱动特性仍有不稳定的缺陷。如inputlenκ0时,有可能取出不完整的数据。为保证可靠,采取降低处理速率的方法,保证下位机发送的数据流完整地进入输入缓冲区。设inputlenκ1,即每次从缓冲区中取一个字符。也可采用轮询方法,定时检测输入缓冲区。下位机定时发送数据: </p>
<p></p>
<p></p>
<p>sub timer1-timer() </p>
<p></p>
<p></p>
<p>if comm1.cdholdingιλcdthen </p>
<p></p>
<p></p>
<p>str1$-text1(i).text </p>
<p></p>
<p></p>
<p>strin2$κstrin1$′上一字符串 </p>
<p></p>
<p></p>
<p>strin1$κstr1$′当前字符串 </p>
<p></p>
<p></p>
<p>strin3$κformat$(len(strin1$),″0000″)&chr$(8)&strin2$ </p>
<p></p>
<p></p>
<p>′传送当前字符串长度,以及上一字符串内容 </p>
<p></p>
<p></p>
<p>com m1.outputκstrin3$ </p>
<p></p>
<p></p>
<p>do doeventsloopuntilcomm1.outbuffercountκ0 </p>
<p></p>
<p></p>
<p>else </p>
<p></p>
<p></p>
<p>timer1.enabledκ0 </p>
<p></p>
<p></p>
<p>end if </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>上位机检测cd状态,判断是否连通、并接收处理数据。 </p>
<p></p>
<p></p>
<p>sub comm1-oncomm() </p>
<p></p>
<p></p>
<p>select case comm1.commevent </p>
<p></p>
<p></p>
<p>case5 ′mscomm-ev-cd检测cd状态,判断是否连通 </p>
<p></p>
<p></p>
<p>comm1.inbuffercountκ0′清输入缓冲区 </p>
<p></p>
<p></p>
<p>comm1.rthresholdκ4′当输入缓冲区中有五个字符, </p>
<p></p>
<p></p>
<p>case2′mscomm-ev-receive产生ev-receive事件,接收处理数据 </p>
<p></p>
<p></p>
<p>do doevents </p>
<p></p>
<p></p>
<p>ifcomm1.inbuffercountthen′循环从缓冲区中取数据 </p>
<p></p>
<p></p>
<p>str1$κstr1$+comm1.input </p>
<p></p>
<p></p>
<p>else </p>
<p></p>
<p></p>
<p>exit do </p>
<p></p>
<p></p>
<p>end if </p>
<p></p>
<p></p>
<p>loop </p>
<p></p>
<p></p>
<p>len2κ1en1′当前字符串长度 </p>
<p></p>
<p></p>
<p>len1κva1(left$(str1$,5))′即将发送的字符串长度 </p>
<p></p>
<p></p>
<p>comm1.rthresholdκlen1+4 </p>
<p></p>
<p></p>
<p>strin$κright$(str1$,len2)′数据处理 </p>
<p></p>
<p></p>
<p>…… </p>
<p></p>
<p></p>
<p>end select </p>
<p></p>
<p></p>
<p>str1$κ″″ </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>4.根据设置的at命令“&d2”,当置dtr信号为低时,modem挂机进入命令状态。也可通过串口输出““+++ath”+chr$(13)”字符串挂机。 </p>
<p></p>
<p></p>
<p>sub hang-click() </p>
<p></p>
<p></p>
<p>if comm1.cdholdingιλcdthen′检测cd,判断是否挂机 </p>
<p></p>
<p></p>
<p>comm1.dtrenableκ0 </p>
<p></p>
<p></p>
<p>comm1.dtrenableκ-1′置dtr信号为高,为下一次通信准备 </p>
<p></p>
<p></p>
<p>end if </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>5.退出程序时,一定要关闭串口 </p>
<p></p>
<p></p>
<p>sub exitcomm() </p>
<p></p>
<p></p>
<p>comm1.portopenκfalse </p>
<p></p>
<p></p>
<p>end </p>
<p></p>
<p></p>
<p>end sub </p>
<p></p>
<p></p>
<p>四、windows通信机制和vb3.0通信控件潜在缺陷 </p>
<p></p>
<p></p>
<p>在通信软件编制过程中,我们发现windows下通信机制采用的“事件驱动”在实际运行中不稳定。如在文件传输过程中,误码和数据丢失的情况时有发生;若串口波特率过高,会产生无法通信或在通信过程中随机挂机的情况。这主要是由于windows本身通信机制和通信线路介质及质量的影响。为保证数据传输稳定可靠,可采用通信协议如xmodem-crc或ymodem。在mscomm.vbx通信控件中,rthreshold属性值大小与输入缓冲区inbuffersize大小有关,当rthreshold值较接近inbuffersize值时,有可能不产生ev-receive事件,为保证产生该事件,可将inbuffersize值取得较大。 </p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -