




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
串口数据接收方式1、 在OnComm 事件中接收数据:这种方式能充分MSCOMM控件的特性。OnComm 事件还可以检查和处理通讯错误;可以通过检查 CommEvent 属性的值来查询事件和错误;对于不定长数据以及对数据进行处理比较复杂的情况,此法不是很方便。Private Sub MSComm_OnComm ()Select Case MSComm1.CommEvent 错误Case comEventBreak 收到 Break。Case comEventCDTO CD (RLSD) 超时。Case comEventCTSTO CTS Timeout。Case comEventDSRTO DSR Timeout。Case comEventFrame Framing ErrorCase comEventOverrun 数据丢失。Case comEventRxOver接收缓冲区溢出。Case comEventRxParity Parity 错误。Case comEventTxFull 传输缓冲区已满。Case comEventDCB 获取 DCB 时意外错误 事件Case comEvCD CD 线状态变化。Case comEvCTS CTS 线状态变化。Case comEvDSR DSR 线状态变化。Case comEvRing Ring Indicator 变化。Case comEvReceive 收到 RThreshold # of chars.Case comEvSend 传输缓冲区有 Sthreshold 个字符 Case comEvEof 输入数据流中发现 EOF 字符End SelectEnd Sub2.轮循法采集数据:A、定时器轮循法对于数据包方式收发数据以及不需即时响应情况,用轮循法更好些。实际上轮循法最大的好处在于集中处理数据而且不太占用CPU。轮循法要注意定时采集的时间片段大小;这里用二进制收发模式;使属性RThreshold、SThreshold为0,屏蔽ONCOMM事件。InputMode = comInputModeBinaryRThreshold = 0SThreshold = 0Private Sub TmrComm_Timer()采用轮循法采集数据Dim Rx_buff() As ByteDim okstring As StringDim ReceivedLen As IntegerOn Error GoTo ErrorHandlerTmrComm.Enabled = False 关闭定时器If commport.InBufferCount 0 ThenReceivedLen = commport.InBufferCountRx_buff = commport.Inputokstring = StrConv(tempbyte, vbUnicode)If ReceivedLen = 6 ThenIf Chr(tempbyte(0) = : And tempbyte(3) = &h0a Then.End IfIf Instr(okstring ,:END*,vbBinaryCompare) Then.End IfEnd IfTmrComm.Enabled = True 打开定时器End SubB、直接轮循法此法用于接收少量控制命令字; 保存输入子串的缓冲区Dim Instring As String 使用 COM1。MSComm1.CommPort = 1 9600 波特,无奇偶校验,8 位数据,一个停止位。MSComm1.Settings = 9600,N,8,1 当输入占用时, 告诉控件读入整个缓冲区。MSComm1.InputLen = 0 打开端口。MSComm1.PortOpen = True 将 attention 命令送到调制解调器。MSComm1.Output = ATV1Q0 & Chr$(13) 确保 调制解调器以OK响应。 等待数据返回到串行端口。DoDoEventsBuffer$ = Buffer$ & MSComm1.InputLoop Until InStr(Buffer$, OK & vbCRLF) 从串行端口读 OK 响应。 关闭串行端口。MSComm1.PortOpen = False如何处理不定长数据的接收在处理串口通讯时,经常会遇到不定长数据的接收。由于通讯任务不同及编程要求的差异所以采用的方法也有所不同。本文就此问题进行探讨。不定长数据从数据格式上分,可分为有格式和无格式。一、无格式不定长数据的接收这种格式在实际串口通讯中用得不多,一般只用传送字符串数据。问题在于怎么判断接收结束。一般用时间延迟的方法解决。A、对于非握手式通讯,可用一个定时器定时轮循接收,并假定每个轮循接收完成。用ONCOMM事件接收也可,只是不如定时器定时轮循接收简便。B、对于握手方式通讯,可用直接轮循法提高接收的准确性。下面是实现此法的函数:Function sComm(sCommand As String, comReceive As MSComm) As StringDim nReceiveCount As IntegerIf comReceive.PortOpen = False ThencomReceive.PortOpen = TrueEnd IfcomReceive.Output = sCommandDonReceiveCount = comReceive.InBufferCountsleep (2) API 函数,挂起当前进程一段时间Loop Until comReceive.InBufferCount = nReceiveCountIf comReceive.PortOpen = True ThensComm = comReceive.InputEnd IfEnd Function注:此函数参照了xth一文。此法一般是能确保数据接收的正确,但由于WINDOWS是多任务操作系统,当有耗时的进程运行时会丢失数据。如果系统会出现这种情况,可增大函数sleep()的参数值。二、不定长格式数据的接收对于不定长数据接收最好的方法是制定通讯协议,比如定义开始字符和结束字符。由于单片机系统通讯一般不太复杂,没必要去制定一套象通用计算机间通讯的协议,而根据单片机系统的大小和性能要求制定通讯协议。实际上为便于交流、维护以及一致性,可制定一套可伸缩的通讯协议。定义了开始字符和结束字符就容易实现不定长格式数据通讯,但在实际通讯编程还是容易出现一些比较隐蔽的通讯错误。下面就常用方法分别进行分析。A、定时器轮循法。假定每个轮循期数据接收完毕,并在每个轮循期处理数据,由于有开始字符和结束字符很容易确定接收数据的完整性。好象合理设定轮循时间值就万无一失了,但被动接收数据时无论如何也找不合适的轮循时间值,因为启动定时器和数据到来基本不同步,这就会出现一次发送的数据被分在两个轮循期接收,所以被动接收数据时不能假定每个轮循期数据接收完毕。在接收到结束字符后才确定一次数据接收完毕就可解决此问题。B、OnComm事件法。方法和定时器轮循法基本相同,因为每次OnCommg事件也只能接收到一部分数据。在VB的在线帮助中这样注解“设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。”。但实际上OnComm事件并不是每收到一个字符便触发一次 OnComm 事件。OnComm事件是在缓冲区收到几个甚至几十个字节数据后才被触发的。版主认为这是WINDOWS多任务使操作系统不能实时响应造成的。如果要在每次OnComm事件接收一个字符似乎可设INPUTLEN属性为1,但实际行不通。VB在线帮助中“有该属性在从输出格式为定长数据的机器读取数据时非常有用”的注解,好象在说对定长字符有效,但版主发现INPUTLEN设为16,接收16个字符定长数据时却被当作两次接收了,一次12个,一次4个。建议在OnComm事件中接收数据要定义通讯协议并检测数据的完整性。 对于不定长格式数据的接收程序员更喜欢定时器轮循法,也许OnComm事件不好控制吧。对于不定长数据的接收,最佳方法可能是在OnComm事件中启动定时器轮循接收,并同时停止OnComm事件的触发,接收完毕后或超时开启OnComm事件。用字符方式收发码值大于127的字符数据VB的通讯控件友好、功能强大,编程速度快是众人皆知的。加上VB的易学、易用,快速开发等特点,数据通讯量不是很大时,在单片机通讯领域广泛地使用VB开发PC上层通讯软件。实际开发时会有不少问题,这里就用字符方式收发码值大127的字符数据进行讨论。在实际开发中经常遇到通讯只是用来发送一些控制字符命令和少量数据。在VB的中文在线帮助中有“若数据只用 ANSI 字符集,则用 comInputModeText”的表述。 ANSI字符集是0-127这容易使人误解为&h88也可用“INPUTMIDE=comInputModeText”方式收发。我刚开始用VB编通讯模块时就为此迷惑过,网上不少网友也时常问及这种问题。实际上在VB中0-127是可以正常收发的,大于127即&H7F的只有&H80和&HFF能够收发,其余ANSI字符都被过滤为0。由于串口通讯是以字节收发的,数据如以comInputModeText模式收发则非字符串数据会被过滤。在VB中用“INPUTMIDE = comInputModeBinary” 就可以解决这个问题,只是收发都必须用动态数组来完成。用comInputModeBinary模式编程稍有点复杂,调试也不直观,对于初学者不易掌握。另外软件完成后,在实际应用时会增加工程维护难度,因为对于二进制代码不是易于理解的。比如下端机发送现场统计数据233,comInputModeBinary模式下串口监测到“:A &H233;,它代表A探针的温度。一般串口监测软件要么用ASCII方式显示,要么用二进制方式显示。用ASCII方式则不能看到&H233,而二进制方式则示不好理解,如果显示58 65 233 59,我想没有人喜欢这种方式(如果有更好的方式的话)。但如果显示“:A 2 3 3 ;”不就解决问题了!用comInputModeText方式就可完成任务了,只是多了一段数据分离程序。对于一般通讯要求这种方法不为是一种好方法。由于通讯任务是多种多样的,有时候这种方法就有点力不从心了,如传送较多的的数据时,这会显著地增加通讯量,通讯变得复杂了,对于单片机系统就不太合适了;还有一些特殊要求,如数据包的识别符也不适此法,但能确定传送数据码值范围也可用此法。下面介绍另一种方法,此法适用比较广,传送二进制数据通讯量增加也不大。这种方法实际上很简单,实际运用中有不少采用此法。原理是一码分为二码。如设7E为临界字符,对于7E则分为7E和0两个ASCII码,依此类推,8F分为7E和11。接收合并时遇到7E则将7E和后一个ASCII码相加为下字符。下面给出C语言函数,VB转换一下便可。由于C语言不能返回两个参数,所以用数组指针。void Filt(char code,char c)if(c=F)if(code0=0X7E)code1=code0-0X7E;code0=0X7E;elsecode1=0XFF; /*0XFF作为标记code1不可能产生0XFF*/else if(c=H)if(code0!=0X7E)code1=0xFE; /*转换完成标记*/elseif(code1=0XFE)code1=0XFF; /*接收下一个码的标记*/elsecode0=code0+code1;code1=0XFE;发送时:char SendChar2; /*存储发送的值*/.SendChar0=c; /*c为待发ASCII码*/Filt(SendChar,F);if(SendChar(1)=0XFF). /*发送SendChar0*/else. /*发送SendChar0,SendChar1*/接收时:char ReceiveChar2; /*存储接收的值*/.ReceiveChar0=c0; /*c0接收的ASCII码*/Filt(ReceiveChar,H);if(ReceiveChar1=0xFF)ReceiveChar1=c1; /*c1为下一个*/Filt(ReceiveChar,H);else if(ReceiveChar1=0xFE). /*存储转换后的ReceiveChar0*/以上代码仅提供一种思路,实际情况视编程需要而定。串口通讯问答录1、Q:各位vb高手:我有一个问题想请教一下。我从COM口用BIN方式接收到数据(一串汉字),存入一BYTE数组,但无法还原为一串汉字,我认为是ANSI和UNICODE的转换,请问如何转换。例:字符串“我”,按BIN方式接收成一BYTE数组,其值为“206,210”,如用“CHR(206)+CHR(210)”却无法得到“我”,实际上“我”=CHR(-12860)请问如何能实现BYTE数组(206,210)与字符串“我”之间的转换?万分感谢!JY1999.10A:经CHR(206)+CHR(210)转换后实际上变成了两个UNICODE字符,四个字节了。汉字的收发必须用BINARY方式。下面的程序能实现汉字收发。发:Dim ytemp() As ByteDim stemp As Stringstemp = 你好!ytemp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025湖北咸宁市通城县高层次和急需紧缺人才企业招聘185人模拟试卷及答案详解(夺冠系列)
- 2025完工为期限劳动合同范本
- 2025年合同规定:餐厅厨师不得在附近开设分店
- 2025海南定安县建设工程质量安全监督站就业见习基地见习生招录5人模拟试卷及答案详解(有一套)
- 2025租赁合同写作注意事项
- 2025江苏南京鼓楼医院人力资源服务中心岗位招聘(五)模拟试卷参考答案详解
- 2025内蒙古航开城市建设投资有限责任公司及子公司公开招聘模拟试卷(含答案详解)
- 2025江苏苏州工业园区天域幼儿园教学辅助人员招聘1人模拟试卷及完整答案详解一套
- 2025年泉州德化县公办学校专项招聘编制内新任教师19人(二)考前自测高频考点模拟试题(含答案详解)
- 协考员考试题库及答案
- 乐乐课堂版奥数三年级
- 口腔疾病的预防与治疗措施
- 汽车机械基础 课件 绪论
- 客车检车员-中国铁路兰州局集团有限公司编
- 胖东来收银管理制度
- 中医护理操作并发症预防及处理
- 《混凝土结构耐久性电化学修复技术规程》
- 产后骨盆修复培训课件
- 桥式起重机Q2练习测试题附答案
- 哈里伯顿Sperry定向钻井介绍专题培训课件
- 2021年江苏省徐州市中考生物试卷(附详解)
评论
0/150
提交评论