VB和51单片机串口通信讲解

上传人:z**** 文档编号:124584056 上传时间:2022-07-25 格式:DOCX 页数:8 大小:36.99KB
返回 下载 相关 举报
VB和51单片机串口通信讲解_第1页
第1页 / 共8页
VB和51单片机串口通信讲解_第2页
第2页 / 共8页
VB和51单片机串口通信讲解_第3页
第3页 / 共8页
亲,该文档总共8页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
VB和51单片机串口通信讲解Commport;设置或返回串口号。SettingS:以字符串的形式设置或返回串口通信参数。Portopen:设置或返回串口状态。InputMode:设置或返回接收数据的类型。Inputlen:设置或返回一次从接收缓冲区中读取字节数。InBufferSize:设置或返回接收缓冲区的大小,缺省值为1024字节。InBufferCount:设置或返回接收缓冲区中等待计算机接收的字符数。Input:从接收缓冲区中读取数据并清空该缓冲区,该属性设计时无效,运行时只读。OutBufferSize:设置或返回发送缓冲区的大小,缺省值为512字节。OutBufferCount:设置或返回发送缓冲区中等待计算机发送的字符数。Output:向发送缓冲区发送数据,该属性设计时无效,运行时只读。设置好这些属性和方法,程序很容易就可以编出来了,其中要注意的是串口的波特串设置,OnComm事件的程序编写。程序的设计是这样的,计算机向单片机发送一个,表示通信开始。然后紧接着又发送9个字符,其中最后一个字符是前面9个字符(包括)的校验和。单片机正确接收到10个字符后,把10个字符从新又送回来。II初始化串口设计PrivateSubForm_Load()Comml.Setting=9600,n,8,1,设置波特率和发送字符格式Comm1.CommPort=1设置通讯串口Comm1.InputLen=0设置或返回一次从接收缓冲区中读取字节数,0表示一次读取所有数据Comm1.InBufersize=512Comm1.InBuferCount=0Comm1.OutBufferCount=OComm1.Rthreshold=1Comm1.PortOpen=TrueEndSub打开串口/给单片机发送,开始通信PrivateSubCommand1_C1ick()Timer1.Enabled=TrueEndSubPrivateSubCommand2C1ick()Varbuffet=“S”Comm1.Ouput=varbuffeTimer2.Enabled=TrueEndSubPrivateSubForm_Unload(CancelAsInteger)Comm1.PortOpen=FalseEndSub/向单片机发送数据PrivateSubTimer2_Timer()Outputsignal=Str(Text2.text)向单片机发送数据Temp(1)=Cbyte(outputsignal)Varbuffer=tempComml.Output=varbufferTimer2.Enabled=FalseEndSubII接收单片机发送的数据,并显示PrivateSubComm1_OnComm()SelectCaseComml.CommEvent设置oncomm事件,读取片机内存的值CasecomEvReceiveInputsignal=comml.InputTextl.Text=Asc(Inputsignal)单片机内存的值用textbox显示出CaseElseEndselectEndSub关于MSCOMM控件的一些说明VB5.0/6.的MSComm通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工、事件驱动的、高效实用的通信程序。但在实际通信软件设计过程中,MSComm控件并非像想像中那样完美和容易控制.特别是在中文Win95/98下通信时更会出现问题。下面就从基础开始介绍,然后逐步讨沦MSComm控件在编程中出现的问题以及编程技巧。一、用MSComm控件通信1.串口通信基础知识一般悦来,计算机都有一个或多个串行端口,它们依次为coml、Com2、,这些串口还提供了外部设备与pC进行数据传输和皿信的通道。这些串口在CPU和外设之间充当解释器的角色。当字符数据从CPU发送给外设时,这些字符数据将被转换成串行比特流数据;当接收数据时,比特流数据被转换为字符数据传递给CPU,再进一步说,在操作系统方面,Windows用通信驱动程序(COMM.DRV)调用API函数发送和接收数据,当用通信控件或声明调用API函数时,它门由COMM.DRV解释并传递给设备驱动程序,作为一个vB程序员,要编写通信程序只需知道通信控件提供给Windows通信API函数的接口即可换句话说,只需设定和监视通信控件的属性和事件即可。2.使用Mscomm控件在开始使用MSComm控件之前。需要先了解其属性、事件或错误CommPort设置或返回通信端口号Settings以字符串的形式设置或返回波特率、奇偶校验、数据位和停止位PortOpen设置或返回通信端口的状态。也可以打开和关闭端口Input返回和删除接收缓冲区中的字符Output将字符串写入发送缓冲区CommEvent属性为通信事件或错误返回下列值之一。在该控件的对象库中也可以找到这些常量。描述常量值ComEventBreak1001收到了断开信号ComEventCTSTO1002ClearToSendTimeout。在发送字符时,在系统指疋的事1件内,CTS(ClearToSend)线是低电平ComEventDSRTO1003DataSetReadyTimeout。在发送字符时,在系统指疋的事件内,DSR(DataSetReady)线是低电平ComEventFrame1004数据帧错误。硬件检测到一个数据帧错误ComEventOverrun1006端口溢出。硬件中的字符尚未读,下一个字符又到达,并且丢失ComEventCDTO1007CarrierDetectTime。在发送字符时,在系统指疋的事件内,CD(CarrierDetect)线是低电平。CD也称为RLSD(ReceiveLineSingalDetect,接收线信号检测)ComEventRxOver1008接收缓冲区溢出。在接收缓冲区中没有空间ComEventRxParity1009奇偶校验错。硬件检测到奇偶校验错误7ComEventTxFull1010发送缓冲区满。在对发送字符排队时,发送缓冲区满ComEventDCB1011检取端口DCB(DeviceControlBlick)时发生了没有预料到的错误通信事件包含了下面的设置:常量值描述ComEvSend1发送缓冲区中的字符数比Sthreshold值低ComEvReceive2接收到了Rthreshold个字符。持续产生该事件,直到使用了Input属性删除了接收缓冲区中的数据ComEvCTS3CTS(ClearToSend)线改变ComEvDSR4DSR(DataSetReady)线改变。当DSR从1至U0改变时,该事件发生ComEvCD5CD(CarrierDetect)线改变ComEvRing6检测到响铃信号。一些URAT(UniversalAsynchronousReciver-Transmitters,通用异步收发器)不支持该事件ComEvEOF7收到了EOF字符(ASCII字符26)Error消息(MSComm控件)下表列出了MSComm控件可捕获的错误消息:常量值描述383属性只读ComInvalidPropertyValue380无效的属性值ComSetNotSupportedComGetNotSupported394属性只读ComPortOpen8000端口打开时该存在无效8001超时设置必须比0值大ComPortlnvalid8002无效的端口号8003属性只在运行时有效8004属性在运行时是只读的ComPortAleadyOpen8005端口已经打开8006设备标识符无效或不支持8007不支持设备的波特率8008指疋的字节大小无效8009缺省参数错误8013 8010硬件不可用(被其他设备锁住)8011函数不能分配队列ComNoOpen8012设备没有打开设备已经打开不能使用通信通知ComSetCommStateFailed8015不能设置通信状态8016不能设置通信事件屏蔽ComPortNotOpen8018该存在只在端口打开是有效8019设备忙ComReadError8020通信设备读错误ComDCBError8021检取端口设备控制块时出现内部错误搞清楚以上基本属性后,就可以开始编写通信许程序了。在VB5.0/6.0中新建一个工程文件。添加MicrosoftCommControl5.0组件,在简体Form1中加入Command命令按钮并取名为CmdTest,MSComm控件取名为MSComm1,加入如下程序代码。PrivateSubcmdTestClick()打开串口MSComml.CommPort=2设定Com2IfMSComml.PortOpen=FalseThenMSComm1.Settings=9600,n,8,19600波特率,无校验,8位数据位,1位停止位MSComm1.PortOpen=True打开串口EndifMSComm1.OutBufferCount=0清空发送缓冲区MSComm1.InBufferCount=0滑空接收缓冲区发送字符数据时注意必须用回车符(vbcr)结束MSComm1.Output=Thisisaqoodbook!&vbCr泼打电话号码或发送AT命令MSComm1.Output=ATDT,&vbCr发送字符数组数据时注意ByteArray必须事先定义赋值DimByteArrayasbyte()定义动态数组ReDimByteArray重定义数组大小ByteArray(0)=0ByteArray(1)=1MSComml.Output=ByteArrayEndSubprivateSubMScommEvent()SelectCaseMSComm1.CommEventCasecomEvReceiveDimBufferAsVariantMSComm1.InputLen=0接收二进制数据MSComm1.InputMode=ComInputModeBinaryBuffer=MSComm1.lnput接收字符数据MSComm1.InputMode=comlnputModeTextBuffer=MSComml.InputCaseelseEndSelectEndsub(程序1)二、中文Win95/98下的通信问题与解决方法1接收的数据少于发送的数据如果通过MSComm控件一次性传送较多的二进制数据,那么,很可能收到的数据不足。例如在设置为24oobps传输率的情况下,一次性可以传输2048个字符数据那么在大多数情况下。一次只能收到1200个字符左右,这址出为新版的MSComm32.OCX中存在一个影响传输二进制数据的臭虫(bug).注意这不是特性。32位WindowsAPI函数(以下简称API)使用了几个用COMMTIMEOUTS结构表示的限时变量,WriteTotalTimeOutConstant即是其中的一个,它被Windows内部设定为5000(即5秒),这个常量决定了在通信驱动程序停止传输之前花费在发送缓冲区中数据的时间的长短,5秒钟意味着通信速度为1200bps情况下仅能发送600个字符,24oobps情况下仅能发送1200个左右的字符。事实上,在一个缓冲区内一次性发送更多的数据是非常可能的。这个bug同样也能引发问题,甚至在高速串口门通信情况下,即使系统在使用流控制,无论丛软件流(Xon/XofI)还是硬件流(CTS/RTS)。假如数据在发送缓冲区中时,流控制停止了传输,如果停止时间超过5秒钟.则数据就会丢失。在某些环境下,5秒钟可能相当短.不过也不必担心,VB5.0/6.0版本的MSComm控件有一个新增的重要的属性称为CommID,CommID指的是当串口被打开时,被API所调用的串口句柄或称标志,这也意味着能利用API接口函数去修改这个常量。每次串口关闭后,Windows会自动将之恢复为5000,所以,每次打开串口后需要重斩设定以下API声明,其代码见下程序。TypeCOMMTIMEOUTSReadIntervalTimeoutAsLongReadTotalTimeoutMultiplierAsLongReadTotalTimeoutConstantAsLongWriteTotalTimeoutMultiplierAsLongWriteTotalTimeoutConstantAsLongEndTypeDeclareFunctionSetCommTimeoutsLibKernel32(BYValhLong,lpCommTimeoutsAsCOMMTIMEOUTS)AsLongDeclareFunctionGetCommTimeoutsLibKernel32(ByValhLong,lpCommTimeoutsAsCOMMTIMEOUTS)AsLong|DimtimeoutsAsCOMMEOUTSDimRetAsLongIfComm1.PortOpen=FalseThenComm1.PortOpen=TrueEndifRet=GetCommTimeouts(Comm1.CommID,timeouts)SetsomedefaulttimeoutstimeOuts.ReadIntervalTimeout=1timeouts.ReadTotalTimeoutMultiplier=1timeouts.ReadTotalTimeoutConstant=1timeouts.WriteTotalTimeoutMultiplier=1timeouts.WriteTotalTimeoutConstant=(Comm1.OutBufferSizeVal(Comm1.Settings)*10000+1000|Ret=SetCommTimeouts(Comm1.CommID,timeouts)(程序2)2如何发送大于128的字符数据在通信程序中,以单字符方式逐个发送数据时,每一个数据范围0-255(即十六进制的00-FF)。在单字符版本的英文Win95或DOS版的BASIC程序中,只需要将相应的数据转换成相应的字符发送到通信端口即可。但在中文Win95/98下却行不通,假设在中文Win95/98下运行以下程序:DimiFori=0to255MSComm1.Output=chr(i)Nexti希望在接收端得到预期的0-255之间的数据,结果却是:前129个数据接收正确,为0-128,后面127个数据为126个0和一个255,使用0-128之间的数字表示ASCII字符,大于128的数字仅作为前导字符,它只是显示是一个非拉丁语系的字符,而并不代表实际意义。上述程序在调用CHR()函数时用到了DBCS字符集,冈此产生了此类错误。那么,如何发送人于128的数据呢?答案是使用字符数组,将以上程序改为:Dimcc(255)AsByteFori=0To255cc(i)=iNextiMSComm1.Output=ccDoDoEventsLoopUntilMSComm1.OutBufferCount=0接收过程MSComm1_OnComm()SelectCaseMSComm1.CommEventCasecomEvReceiveDimBufferAsVariant,b1,iMSComm1.InputMode=comlnputModeBineryMSComm1.InputLen=0Buffer=MSComm1.InputFori=LBound(Buffer)ToUBound(Buffer)Debug.PrintBuffer(i);NextiCase3.如何发送0字符(OOH,NULL)在VisualC+中使用串口控件发送0字符有些麻烦,但在VB5.0/6.0中只要注意以下两点即可:(1)设置MSComm控件的属性NullDiscard=False;。(2)使用二进制接收,即用MSComm1.lnputMode=ComlnputModeBinary便可以解决问题;4如何发送递中文字符串(DBcS字符)VB5.0/6.0的各种参考书上均指明MSComm通信控件不能发送或接收双字节字符集系统DBCS)的二进制数据,这对于我国及亚洲一些使用DBCS字符集的国家不能不说是一大人遗憾。但是我在实践中发现,用MSComm控件也可以发送中文字符,具体方法有以下两种:(1)直接发送直接发送即把中文字符等同于英文字符。女口:MSComml.Intput=这是一行中文数据!,但这种方法发送的中文数据不能太长,发送缓冲区和接收缓冲区的大小需设定为中文字符的两倍以上,而且发送与接收系统所处的操作系统版本最好要一致,否则会出现接收或发送缓冲区溢出之类的错误。这种方法时用于一般要求不太高的场合。(2)间接发送在发送端将汉字或字符转换为机器内码或区位码数据数组,然后将咏转换后的数据发送到串口,在接收端接收到数据后,按照相反的顺序得到的数据转换为相应的汉字或字符,在转换过程中要用到位运算,如取得汉字的内码后需要将高字节和低字节分开,而VB5.0/6.0中并没有提供此类函数,以下是求整数高、低字节的函数。PublicFunctionHiByte(aAsInteger)Dimbb=aAnd&HFF00b=b/256Ifb0.01)Then间隔10MS以上就认为是一个新的包text仁text1用于搜集和显示接收(HEX格式)N=0EndIfT=TimerFori=0ToUBound(S)一个数据包可能产生若干个oncomm事件Text1.Text=Text1.Text&Right(0&Hex(S(i)&H,3)+-
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 活动策划


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!