VB6 实时 串口通信 数据采集代码
VB6.0下MSComm控件实现串口通信

VB6.0下用MSComm控件实现串口通信MSComm控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能,以下先对其属性进行详细的说明后再举一个例子进行说明:1基本属性CommPortO mPort[=value]Object为MSComm控件,value为整数值,标志端口号。
说明:该属性设置并返回通讯端口号,value的值可以设为1-16间的任意数(默认为1)。
在打开端口之前必须先设置CommPort属性,当端口不存在时,如果用PortOpen属性打开它,MSComm控件会产生错误68(即设备无效的错误)。
SettingsObjiect.Setting[=value]Object为MSComm控件,value为字符串类型,表示通讯端口的设置值。
说明:本属性用来设置并返回端口的波特率、奇偶校验位、数据位和停止位参数。
当端口打开时,如果指定的value参数非法,则MSComm控件产生380号(非法属性值)错误。
有效的value参数值由四个设置值组成,有如下格式:“BBBB,P,D,S”,其中BBBB为波特率,P为奇偶校验,D为数据位数,S为停止位数。
Value的默认值为:“9600,N,8,1”,下面给出合法的波特率、奇偶校验位、数据位和停止位参数:波特率:110,300,600,1200,2400,4800,9600(默认),14400,19200,28800,38400,56000,57600,115200,128000,256000。
奇偶校验值:E(偶校验,Even)、M(标记,Mark)、N(默认,Default,None)、O(奇校验,Odd)、S(空格,Space)。
数据位值:4,5,6,7,8(默认),9。
停止位值:1(默认),1.5,2。
PortOpenO bject.PortOpen[=value]Object为MSComm控件。
Value为布尔类型,表明通讯端口的状态。
vb程序实现串口通信,将接到的数据动态保存,并可以图表绘制曲线(X:时间,Y:数据)

vb程序实现串口通信,将接到的数据动态保存,并可以图表绘制曲线(X:时间,Y:数据)将接到的数据赋值于全局变量,通过ADO数据控件连接数据库及表,用以下代码保存数据: Private Sub Timer1_Timer()If Label1.Caption <> CStr(Time$) ThenLabel1.Caption = Time$sum_zj = sum_zj + 1Text3 = sum_zj'校准If sum_zj >= 3 Thensum_zj1 = sum_zj1 + 1sum_zj = sum_zj - 3Text4 = sum_zj1Adodc1.Recordset.AddNew '每3秒记录一组数据Adodc1.Recordset(0) = shiY AnHAdodc1.Recordset(1) = Mid(Time$, 1, 2) & Mid(Time$, 4, 2) & Mid(Time$, 7, 2) '记录time Adodc1.Recordset(2) = record_jm(0) '记录数据Adodc1.Recordset(3) = record_jm(1) '记录数据Adodc1.Recordset(4) = record_jm(2) '记录数据Adodc1.Recordset(5) = record_jm(3) '记录数据Adodc1.Recordset(6) = record_jm(4) '记录数据Adodc1.Recordset(7) = record_jm(5) '记录数据Adodc1.Recordset(8) = record_jm(6) '记录数据Adodc1.Recordset(9) = record_jm(7) '记录数据Adodc1.Recordset(10) = record_jm(8) '记录数据Adodc1.Recordset(11) = record_jm(9) '记录数据Adodc1.Recordset(12) = record_jm(10) '记录数据Adodc1.Recordset(13) = record_jm(11) '记录数据Adodc1.Recordset.UpdateEnd IfEnd IfEnd SubPrivate Sub Timer2_Timer()Picture4.DrawStyle = 0以下代码绘制实时曲线(6点):Picture4.DrawWidth = 3 ' = dashPicture4.Line (sum_z1 * 18 + 500, record_jm(0) * -150 + 7900)-(sum_z1 * 18 + 500, record_jm(2) * -150 + 7900), vbRed ', BFPicture4.Line (sum_z1 * 18 + 500, record_jm(1) * -150 + 7900)-(sum_z1 * 18 + 500, record_jm(3) * -150 + 7900), vbCyan ', BFPicture4.Line (sum_z1 * 18 + 500, record_jm(2) * -150 + 7900)-(sum_z1 * 18 + 500, record_jm(4) * -150 + 7900), vbBlack ', BFPicture4.Line (sum_z1 * 18 + 500, record_jm(3) * -150 + 7900)-(sum_z1 * 18 + 500, record_jm(5) * -150 + 7900), vbMagenta ', BFPicture4.Line (sum_z1 * 18 + 500, record_jm(4) * -150 + 7900)-(sum_z1 * 18 + 500, record_jm(6) * -150 + 7900), vbGreen ', BFPicture4.Line (sum_z1 * 18 + 500, record_jm(5) * -150 + 7900)-(sum_z1 * 18 + 500, record_jm(7) * -150 + 7900), vbBlue ', BFEnd SubPrivate Sub Timer3_Timer()If Label32 <> CStr(Time$) Then 'Label1.CaptionLabel32.Caption = Time$sum_z = sum_z + 1Text31 = sum_z'校准If sum_z >= 5 Thensum_z = sum_z - 5sum_z1 = sum_z1 + 1Text30 = sum_z1End IfEnd IfEnd Sub以下代码绘制曲线的坐标:Private Sub Form_Load()With Adodc1Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\kongtiao\cartemp.mdb;Persist Security Info=False"Adodc1.RecordSource = "select * form car_bm"End WithText1 = ""Text2 = "": Text3 = "": Text4 = "":Text5 = "": Text6 = "": Text7 = "": Text12 = ""Text8 = "": Text9 = "": Text10 = "": Text11 = ""Text13 = "": Text14 = "": Text15 = "": Text16 = ""'Load frmMaincolvb = vbBlackxx = 100yy = 150txt = "℃"wp = xp(colvb, xx, yy, txt)xx = 200yy = 350txt = "50"wp = xp(colvb, xx, yy, txt)xx = 200yy = 1850wp = xp(colvb, xx, yy, txt) yy = 3350xx = 200txt = "30"wp = xp(colvb, xx, yy, txt) xx = 200yy = 4850txt = "20"wp = xp(colvb, xx, yy, txt) xx = 200yy = 6350txt = "10"wp = xp(colvb, xx, yy, txt) 'Time坐标colvb = vbRedyy = 6500xx = 400txt = "0"wp = xp(colvb, xx, yy, txt) xx = 1480txt = "5"wp = xp(colvb, xx, yy, txt) xx = 2560txt = "10"wp = xp(colvb, xx, yy, txt) xx = 3640txt = "15"wp = xp(colvb, xx, yy, txt) xx = 4720txt = "20"wp = xp(colvb, xx, yy, txt) xx = 5800txt = "25 min"wp = xp(colvb, xx, yy, txt) xx = 6880txt = "30"wp = xp(colvb, xx, yy, txt) xx = 7960txt = "35"wp = xp(colvb, xx, yy, txt) xx = 9040txt = "40"wp = xp(colvb, xx, yy, txt)txt = "45"wp = xp(colvb, xx, yy, txt)xx = 11200txt = "50"wp = xp(colvb, xx, yy, txt)'画格Picture1.DrawWidth = 1 ' = dashPicture1.DrawStyle = 0Picture1.ForeColor = vbCyanFor i = 0 To 39Picture4.Line (450, 550 + i * 150)-(500, 550 + i * 150) NextPicture4.DrawStyle = 2For i = 0 To 8Picture4.Line (450, 400 + i * 750)-(11300, 400 + i * 750) NextFor i = 0 To 15Picture4.Line (450, 1000 + i * 300)-(500, 1000 + i * 300) NextFor i = 0 To 10Picture4.Line (500 + i * 1080, 400)-(500 + i * 1080, 6400) NextPicture4.DrawStyle = 0End Sub。
VB6使用API实现串口通信

需要和客户的产品通讯,但波特率是非常规的,MScomm无法实现,原有的软件框架和条件又不能转用VC开发底层,于是用VB6调用API实现了这个通讯功能,虽然在VB6下这个程序还是单进程的,但实现了异步非阻塞的通信,性能相当稳定,下面是测试程序代码Private Sub cmdSend_Click()Sub cmdSend_Click()'定义文件读写属性结构Dim sa As SECURITY_ATTRIBUTES'定义串口状态结构Dim typCommStat As COMSTAT'定义串口状态错误Dim lngError As Long'********打开串口********Dim hCF As LonghCF = CreateFile("COM4", _GENERIC_READ Or GENERIC_WRITE, 0, sa, _OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL Or FILE_FLAG_OVER LAPPED, 0)Debug.Print "打开串口:" & hCF'********获取出错信息********Dim errNum As LongerrNum = GetLastError()Debug.Print "出错信息:" & errNum'定义标志值Dim flag As Long'定义设备控制块Dim typDCB As DCB'********获取设备控制块********flag = GetCommState(hCF, typDCB)Debug.Print "获取串口DCB:" & flagtypDCB.BaudRate = 2500 '定义波特率typDCB.Parity = NOPARITY '无校验位typDCB.ByteSize = 8 '数据位typDCB.StopBits = 0 '停止位0/1/2 = 1/1.5/2'********设置串口参数********flag = SetCommState(hCF, typDCB)Debug.Print "设置串口参数:" & flag'********设置缓冲区大小********flag = SetupComm(hCF, 1024, 1024)'Debug.Print "设置缓冲区:" & flag'********清空读写缓冲区********flag = PurgeComm(hCF, PURGE_RXABORT Or PURGE_RXCLEAR Or PURGE_T XABORT Or PURGE_TXCLEAR)'Debug.Print "强制清空缓冲区:" & flag'定义超时结构体Dim typCommTimeouts As COMMTIMEOUTStypCommTimeouts.ReadIntervalTimeout = 0 '相邻两字节读取最大时间间隔(为0表示不使用该超时间隔)typCommTimeouts.ReadTotalTimeoutMultiplier = 0 '一个读操作的时间常数typCommTimeouts.ReadTotalTimeoutConstant = 0 '读超时常数typCommTimeouts.WriteTotalTimeoutMultiplier = 0 '一个写操作的时间常数(为0表示不使用该超时间隔)typCommTimeouts.WriteTotalTimeoutConstant = 0 '写超时常数(为0表示不使用该超时间隔)'********超时设置********flag = SetCommTimeouts(hCF, typCommTimeouts)'Debug.Print "超时设置:" & flag'********发送数据********'定义要发送字节数Dim lngNumberofBytesToWrite As Long'定义实际发送字节数Dim lngNumberofBytesToWritten As Long'定义重叠结构体Dim typOverLapped As OVERLAPPED'定义发送数据Dim arrbytTest(0 To 23) As Byte'载波收发器同步头arrbytTest(0) = CByte(&H53) arrbytTest(1) = CByte(&H4E) arrbytTest(2) = CByte(&H44)'后续数据包长度arrbytTest(3) = CByte(&H14)'载波表预同步头arrbytTest(4) = CByte(&HFF) arrbytTest(5) = CByte(&HFF) arrbytTest(6) = CByte(&HFF) arrbytTest(7) = CByte(&HFF) arrbytTest(8) = CByte(&HFF) arrbytTest(9) = CByte(&HFF)'载波表帧同步头arrbytTest(10) = CByte(&H9) arrbytTest(11) = CByte(&HAF)'载波表地址arrbytTest(12) = CByte(&H59) arrbytTest(13) = CByte(&H20) arrbytTest(14) = CByte(&H0)'控制码arrbytTest(15) = CByte(&H1)'数据长度arrbytTest(16) = CByte(&H5)'功能码arrbytTest(17) = CByte(&H10)arrbytTest(18) = CByte(&H90)'集中器地址arrbytTest(19) = CByte(&HBB)arrbytTest(20) = CByte(&HBB)arrbytTest(21) = CByte(&HBB)'校验和arrbytTest(22) = CByte(&H50)arrbytTest(23) = CByte(&H3)'获取要发送字节数lngNumberofBytesToWrite = UBound(arrbytTest) + 1'声明等待开始时间、结束时间值Dim writeStarTime, writeEndTime As LongwriteStarTime = GetTickCount()Debug.Print "发送开始时间:" & writeStarTime'定义发送循环步长值Dim i As Integer'定义累计发送字节数Dim intTotalNumberOfBytesToWritten As Integer'定义发送间隔时间(毫秒)Dim intIntervalTime As IntegerintIntervalTime = 0'发送数据For i = 0 To UBound(arrbytTest)flag = WriteFile(hCF, arrbytTest(i), 1, lngNumberofBytesToWritten, typOverLappe d)'获取出错码errNum = GetLastError()'Debug.Print "发送操作出错码:" & errNum'若返回值不是IO异步操作未决,则关闭串口If (errNum <> ERROR_IO_PENDING) And (errNum <> 0) Then GoTo closeCo mm'异步IO事件获取(返回值为0 表示出错)flag = WaitForSingleObject(typOverLapped.hEvent, 0)'Debug.Print "异步IO事件获取:" & flag'判断异步IO事件获取是否成功If flag <> 0 Then'异步IO操作结果获取(等待标记值,必须为true ,否则需要事件激活返回结果) flag = GetOverlappedResult(hCF, typOverLapped, lngNumberofBytesToWritten, 1)'Debug.Print "异步IO操作获取:" & flag'判断异步IO操作结果获取是否成功If flag <> 0 ThenintTotalNumberOfBytesToWritten = intTotalNumberOfBytesToWritten + _lngNumberofBytesToWrittenEnd IfEnd If'间隔时间(用于需要设定每字节间间隔时间的发送协议)Sleep (intIntervalTime)NextwriteEndTime = GetTickCount()Debug.Print "发送结束时间:" & writeEndTimeDebug.Print "发送总时间:" & (writeEndTime - writeStarTime)Debug.Print "串口发送操作:" & flagDebug.Print "实际发送字节数:" & intTotalNumberOfBytesToWritten'********清空缓冲区等待数据接收********flag = FlushFileBuffers(hCF)'Debug.Print "清空缓冲区:" & flag'********设置串口事件********'监听数据接收事件' flag = SetCommMask(hCF, EV_ERR Or EV_RXCHAR) ' Debug.Print "监听事件设置:" & flagflag = SetCommMask(hCF, 0)Debug.Print "监听事件设置:" & flag'********等待串口接收事件********'声明等待开始时间、结束时间值Dim sngStarTime, sngEndTime As Long'事件掩码Dim lngEventMask As Long'定义接收字节数变量Dim tempReceive As LongtempReceive = 0Debug.Print "监听开始"'生成开始时间sngStarTime = GetTickCount()Debug.Print "开始监听时间:" & sngStarTime'定义等待步骤参数Dim n As Integern = 1' '监听串口事件' flag = WaitCommEvent(hCF, lngEventMask, typOverLapped)' Debug.Print "监听操作:" & flag' '获取出错码' errNum = GetLastError()' Debug.Print "监听操作出错码:" & errNum'' '若返回值不是IO异步操作未决,则关闭串口' If (errNum <> ERROR_IO_PENDING) And (errNum <> 0) Then GoTo closeCom m'定义读取间隔时间(毫秒)Dim intReadIntervalTime As IntegerintReadIntervalTime = 1Do' '异步IO事件获取(返回值为0 表示出错)' flag = WaitForSingleObject(typOverLapped.hEvent, 0)' Debug.Print "异步IO事件获取:" & flag' '获取出错码' errNum = GetLastError()' Debug.Print "IO事件获取出错码:" & errNum'清除错误标志函数,获取串口设备状态flag = ClearCommError(hCF, lngError, typCommStat)Debug.Print "获取串口设备状态:" & flag'若获取状态成功If (flag <> 0) And (typCommStat.cbInQue > 0) Then Debug.Print "已接收字节数:" & typCommStat.cbInQue'判断接收缓冲区内的数据是否等于需要接收的字节数If typCommStat.cbInQue >= 22 Then'跳出循环Debug.Print "跳出循环"Exit DoEnd IfEnd If'生成结束时间sngEndTime = GetTickCount()Debug.Print "第" & n & "次监听事件时间:" & sngEndTime n = n + 1'读时间间隔Sleep (intReadIntervalTime)Loop Until (sngEndTime - sngStarTime) > 1000'生成结束时间sngEndTime = GetTickCount()Debug.Print "结束监听时间:" & sngEndTimeDebug.Print "监听结束"Debug.Print "总接收时间:" & (sngEndTime - sngStarTime)'********接收数据********'定义接收数组Dim arrbytReceive(0 To 22) As Byte'定义实际接收字节数Dim lngNBR As Long'重叠结构置0typOverLapped.hEvent = 0typOverLapped.Internal = 0typOverLapped.InternalHigh = 0typOverLapped.offset = 0typOverLapped.OffsetHigh = 0'接收数据flag = ReadFile(hCF, arrbytReceive(0), 23, lngNBR, typOverLapped) Debug.Print "串口接收操作:" & flagDebug.Print "实际接收字节数:" & lngNBR Debug.Print arrbytReceive(0)Debug.Print arrbytReceive(21)Debug.Print arrbytReceive(22) closeComm:'********关闭所有串口事件********flag = SetCommMask(hCF, 0)'Debug.Print "关闭串口事件:" & flag'********关闭串口********Dim closeFlag As LongcloseFlag = CloseHandle(hCF)Debug.Print "关闭串口:" & closeFlagEnd Sub。
VB串口通信程序代码

vb中怎样用mscomm控件实现串口通信本问分两部分均来自第一部分jessezappy(晶晶)================================================================================== If MSComm1.PortOpen Then MSComm1.PortOpen = FalsemPort = 1 '假定是用COM1口' 设定传输速率等,可依照您的需求更改MSComm1.Settings = "9600,N,8,1"MSComm1.PortOpen = True'---------初始化Modem-------------MSComm1.Output = "ATZ"MSComm1.Output = "AT&F"MSComm1.Output = "ATE0"MSComm1.Output = "ATM1"MSComm1.Output = "ATQ0"MSComm1.Output = "ATV0"'--------------------------拨号-------------MSComm1.Output ="ATDT163" '拨163'---------------------------接通后MSComm1.Output ="SDFJDKSJLKFA" '发送字符串'---------------------Private Sub MSComm1_OnComm() '用串口事件捕捉数据..If MSComm1.InBufferCount Then' 通讯埠中假如有资料的话, 则读取进来InStringB = InStringB & MSComm1.Input' 如果资料中有Chr(13) 和Chr(10) 的话, 则显示出来If InStr(InStringB, vbCrLf) Theninstring = instring & InStringBAddText Text3, InStringB, FalseInStringB = ""End IfEnd IfEND SUB'-------------------------挂断--------MSComm1.PortOpen = False '这个挂断方法不能适用所有MODEM,我正在研究...通用办法================================================================================================第二部分:===========================================================================最后借你一篇文章看,作者不是我,里面的不一定都对..'-----------------------------------------------------------VB Mscomm控件应用江苏戚墅堰机车车辆厂设计处(213011) 李秉璋--------------------------------------------------------------------------------Visual Basic 6.0(以下简称VB) 是一种功能强大、简单易学的程序设计语言。
基于VB6.0的上位机与PLC实时通信技术

基于VB6.0的上位机与PLC实时通信技术一、引言随着自动化技术的不断发展,PLC(可编程逻辑控制器)已经成为自动化领域中不可或缺的设备。
PLC通常用于控制工业生产线上的设备和机器,而上位机则是用来监控和管理PLC系统的设备。
众所周知,实时通信是保证PLC系统正常运行的重要因素之一。
在这篇文章中,我们将重点介绍基于VB6.0的上位机与PLC实时通信技术。
二、VB6.0简介VB6.0是微软公司于1998年发布的一款集成开发环境(IDE),它是一种编程语言,被广泛用于开发Windows平台下的应用程序。
VB6.0具有简单易学、功能丰富、开发效率高等特点,因此在工业领域得到了广泛应用。
考虑到VB6.0的这些优势,我们可以利用它来开发上位机程序,并实现与PLC的实时通信。
三、PLC实时通信技术1. 串口通信PLC通常通过串口与上位机进行通信。
在VB6.0中,我们可以利用MSCOMM控件来实现串口通信。
通过在VB6.0的界面中添加MSCOMM控件,并设置相应的串口参数(如波特率、数据位、校验位、停止位等),就可以实现与PLC的串口通信。
2. Modbus通信Modbus是一种通信协议,被广泛用于工业控制领域。
通过Modbus协议,我们可以实现上位机与PLC之间的实时通信。
在VB6.0中,我们可以使用第三方的Modbus通信库来实现Modbus通信,例如Modbus ActiveX控件等。
通过这些控件,我们可以轻松地实现Modbus通信,从而实现上位机与PLC的实时数据交换。
3. Socket通信1. 配置MSCOMM控件接下来,我们需要编写VB6.0代码,实现与PLC的串口通信。
您可以编写相应的串口通信代码,例如打开串口、发送数据、接收数据等。
示例代码如下:Private Sub Form_Load()mPort = 1 ' 串口号MSComm1.Settings = "9600,n,8,1" ' 波特率、校验位、数据位、停止位MSComm1.PortOpen = True ' 打开串口End SubPrivate Sub Command1_Click()MSComm1.Output = "010*********FF01" ' 发送数据End Sub3. 运行程序并测试您可以运行程序,并测试与PLC的串口通信是否正常。
VB6_0串口通信数据采集设计

XU Jun-feng,MA Chun-cao,LIU Chang
( Jiangsu Automation Research Institute,Lianyungang 222006,China)
Abstract: Based on serial communication principles and the MSComm control in VB6.0,the regular communica-
串行通信是计算机与其他设备进行数据交换时的 常用方法,因其通信线路简单、使用灵活方便,而广泛 应用于工业监控、数据采集和实时监控等领域。利用 VB6. 0 提供的标准 MSComm 控 件,开 发 者 只 需 知 道 MSComm 控件的属性和事件的用法,就能非常方便地 实现串口通信。本设计基于串口通信和 VB6.0 中的 MSComm 控件原理,实现计算机与自动化设备( GPS 接 收模块,场强仪) 之间 的 通 信 并 进 行 定 时 数 据 采 集。 它具有良好的人机交互界面,操作者可以进行数据采 集模式设置、串口设置等,将数据保存入数据库并对数
添加 ADO 控件后,需对其属性进行设置,如表 2 所示。
表 2 ADO 控件属性设置
属性
设置
说明
名称
data_scan
设置 ADO 控件名称
Align
2
பைடு நூலகம்
设置 ADO 布局
ConnectionString
Provider = Microsoft. Jet. OLEDB. 3. 51; Persist Security Info = False; Data Source = D: \ data. mdb
据进行处理。
1 系统设计
VB6.0环境下利用Mscomm控件实现串行通信

VB6.0环境下利用Mscomm控件实现串行通信Use Mscomm Control Component to Implement Serial Communication under Visual Basic摘要: 本文简要介绍了VB6.0中Mscomm通信控件的属性和使用方法,并结合具体实例给出了基本的通信程序。
主题词:串行通信Visual Basic Mscomm .vbx控件Abstract: This paper briefly introduces the principle and method of Mscomm object of Visual basic 6.0, and with a real example basic program codes are given.Key Words:Serial Communication; Visual Basic; Mscomm .vbx control component随着计算机技术的飞速发展及其广泛应用,远程控制以及数据采集系统多采用上位机和下位机的主从工作方式,由于串行通信具有高效可靠、价格便宜,遵循统一的标准等特点,因而成为主要的通信手段。
微机的分析处理能力较强,有很好的人机界面和大容量的多种存储方式,所以上位机一般采用微机。
而单片机具有价格低,功能强,抗干扰能力好,温限宽和面向控制等特点,所以下位机采用单片机来构成主从式多机工作模式。
在需要对采集的数据进行分析处理或在远程需要对控制对象的控制过程进行统计或有条件控制时,采用数据库访问技术能有效地解决这类问题。
Visual Basic 6.0以其强大的功能、使用简单、能在短时间内开发出高效的通信程序而成为Windows系统开发的主要编程语言。
首先表现在VB可直接使用户自定义控件VBX或OCX文件;其次表现在VB可通过调用动态链接库(DLL,dynamic link library)来加快应用程序关键部分的执行速度。
VB串口通信数据采集

VB串口通信数据采集2009-05-12 18:40前两天受人之托写的一个程序,发上来共享,从中可以看到串口通信的常用处理方式,希望对大家有所帮助。
一、系统需求:使用三线制串口,利用vb与dsp通信,采集数据并存储为文本文件。
二、通信协议1. RS232串行通信的波特率设为9600,8位数据位,一位停止位,无校验位。
2. 每组数据包含T1(16位)和T2(16位),将每个数据分成2个8位的数据,先是低8位,然后是高8位。
数据为无符号整型。
先发T1,然后发T2,然后是下一组T1、T2。
T1以头数据0x0A(16进制,10进制位10)为头字节,然后是T1的低8位,T1的高8位。
T2以头数据0xA0(16进制,10进制位160)为头字节,然后是T2的低8位,T2的高8位。
发送时序举例:0x0A, t1低8位,t1高8位,0xA0, t2低8位,t2高8位……将收到的数据T1、T2的高低8位合并,转换成10进制数,以每行T1 T2的形式存储到txt文本文件中。
三、要点说明0. 如果通信协议没有考虑周全就着手开始做,可能会经受无比的痛苦1. 文本框textbox的大小限制为32k,不符合大量数据的需要,因此使用richtextbox2. 换行符为Chr(&HD) + Chr(&HA)3. 需要用状态栏给出必要的信息4. 保存文件的默认名字为当前日期5. 收到comm事件后,需要关闭com事件接收,避免再次触发事件Dim av As VariantDim datacount As LongPrivate Sub cmdClear_Click()txtData.Text = ""End SubPrivate Sub cmdStop_Click()'关闭端口If MSComm.PortOpen = True ThenMSComm.InBufferCount = 0 '清空缓冲区MSComm.PortOpen = FalseEnd IfcmdReceive.Enabled = TruelblStatus.Caption = "停止接收,空闲"End SubPrivate Sub cmdReceive_Click()'串口设置With MSComm.CommPort = 1.Settings = "9600,N,8,1".RThreshold = 1 '接收1字节触发oncomm事件.InputMode = comInputModeBinary.InputLen = 1 '输入长度为1.InBufferCount = 0 '清除接收缓冲区End With'打开端口If MSComm.PortOpen = False ThenMSComm.PortOpen = TrueIf Err ThenMsgBox (Err.Description)Exit SubEnd IfEnd IflblStatus.Caption = "打开端口,等待接收" datacount = 0cmdReceive.Enabled = FalseEnd SubPrivate Sub cmdSave_Click()Dim outfn As StringMsgBox ("接收了" + CStr(datacount) + "组数据") lblStatus.Caption = "接收完成,请选择输出文件"cmdReceive.Enabled = True'选择输出文件CommonDialog1.FileName = CStr(Date) + ".txt"CommonDialog1.Filter = "Text Files|*.txt"CommonDialog1.Flags = CommonDialog1.Flags Or cdlOFNOverwritePrompt CommonDialog1.CancelError = TrueOn Error GoTo errhandlerCommonDialog1.ShowSaveoutfn = CommonDialog1.FileNameOpen outfn For Output As #1Print #1, txtData.TextClose #1'txtData.SaveFile outfnlblStatus.Caption = "输出完成,空闲"errhandler:Exit SubEnd SubPrivate Sub Form_Load()lblStatus.Caption = "空闲"End SubPrivate Sub Form_Unload(Cancel As Integer)'关闭端口If MSComm.PortOpen = True ThenMSComm.InBufferCount = 0 '清空缓冲区MSComm.PortOpen = FalseEnd IfEnd SubPrivate Sub MSComm_OnComm()Dim T1, T2 As LongSelect Case mEventCase comEvReceive '收到Rthreshold个字节产生的接收事件MSComm.RThreshold = 0 '关闭OnComm事件接收lblStatus.Caption = "接收"av = MSComm.Input '读取一个接收字节dataframe(1) = av(0) '转换为字节If dataframe(1) = &HA Then '接收到T1DoDoEventsLoop Until MSComm.InBufferCount >= 2 '循环等待接收缓冲区>=2个字节av = MSComm.Inputdataframe(2) = av(0)av = MSComm.Inputdataframe(3) = av(0) '接收T1T1 = dataframe(2) + CLng(dataframe(3)) * 256 '计算T1End IfDoDoEventsLoop Until MSComm.InBufferCount >= 1 '循环等待接收缓冲区>=1个字节av = MSComm.Input '读取一个接收字节dataframe(4) = av(0) '转换为字节'接收到T2If dataframe(4) = &HA0 Then'MSComm.RThreshold = 0 '关闭OnComm事件接收'循环等待接收缓冲区>=2个字节DoDoEventsLoop Until MSComm.InBufferCount >= 2av = MSComm.Inputdataframe(5) = av(0)av = MSComm.Inputdataframe(6) = av(0) '接收T2T2 = dataframe(5) + CLng(dataframe(6)) * 256 '计算T2'显示T1 T2 entertxtData.Text = txtData.Text + CStr(T1) + " " + CStr(T2) + Chr(&HD) + Chr(&HA)datacount = datacount + 1 '数据组数+1End IfMSComm.RThreshold = 1 '打开OnComm事件接收Case ElseEnd SelectEnd Sub。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
VB6 实时串口通信数据采集代码介绍VB6.0利用MSComm通信控件,开发微机通过串口对工业仪表进行实时数据采集的编程技术。
给出的程序代码具有通用性,并有详细的注释,可以直接或稍加改动后用于其他数据采集或实时控制程序中。
----一台工业专用实时检测仪表,接高精度位移传感器,用于测量微小形变或微量位移,仪表测量精度为0.01毫米,测量范围最大值为50毫米。
该仪表带有一个9针的RS-232C 串口,能与微机进行串口数据通信,实时传送检测数据,通过微机软件处理可实现工业实时监控。
----该仪表的串口数据通信协议是:数据传输速率为9600bps,1位开始位,8位数据位,1位停止位,无奇偶校验位。
仪表每秒发送50帧检测数据,每帧数据由4个字节组成。
第一个字节定义为二进制常数0F0H,是每帧数据开始的标志字节;后面连续2个字节为数据字节,采用压缩的BCD码编码方式,高位在前,低位在后,即一个字节表示两位十进制数,则两个字节表示四位十进制数,小数点采用固定形式,定义在两字节中间;第四个字节为符号字节,该字节第八位为1,即:1 x x x x x x x 则为负数;第八位为0,即:0 x x x x x x x 则为正数。
----例如:0F0H 26H 87H 80H 0F0H 34H 62H 00H 表示-26.87 34.62。
----通信传输速率为9600bps,则最快速度1.04ms发送一帧数据。
9600bps = 1200Bps这样计算出来的结果相当于8bits/Frame,现在串口中协议是10bits/Frame,求解方程1200 * 8 = x * 10得到x = 960Frame/s。
1000/960 = 1.04167Frame/ms。
仪表每秒发送50帧数据,每帧数据有4个字节,即每秒发送200个字节,平均5.0ms 发送一个字节,连续读取串口数据时要在程序中添加循环等待程序。
----为了实现实时监测功能,接收数据的读取要尽可能的快速,则设置MSComm1的属性如下:RThreshold = 1 接收缓冲区收到一个字节产生OnComm事件InputLen = 1 每次读取一个字节----仪表每秒发送50帧数据,微机收到一帧完整数据至少需要20 ms 时间(1000/50=20),然后再进行数据处理。
①如果微机在下一帧数据接收前即20ms内能将数据计算处理完毕,则接收缓冲区内只会保存有一帧数据,不会存有两帧以上数据,接收缓冲区的大小不会影响实时监测效果(接收缓冲区>4字节),这时完全可以实现实时监测或实时控制;②如果微机在20ms内不能将数据计算处理完毕,接收缓冲区设置得又很大,在数据计算处理完毕前,接收缓冲区内就会保存有两帧以上数据,而且一次工作时间越长,缓冲区内滞留数据帧就越多,数据采集和数据处理之间产生逐渐增大的额外时间差,当接收缓冲区充满后,时间差不再增大,固定在某一值,部分数据因不能及时采集到接收缓冲区中,数据产生丢失现象,真实工作情况就会和微机处理结果产生较大的时间差,对实时监测和实时控制很不利,这种情况下接收缓冲区的大小就会影响实时监测效果,所以接收缓冲区设置不能过大,以保证数据处理的实时性。
----设置接收数据模式采用二进制形式,即InputMode=comInputModeBinary,但用Input属性读取数据时,不能直接赋值给Byte 类型变量,只能通过先赋值给一个Variant 类型变量,返回一个二进制数据的数组,再转换保存到Byte类型数变量中。
----VB中有Byte类型变量,但没有字节的位处理语句,符号字节的位处理要判断符号字节的值是否大于127,大于127则为负数;压缩的BCD码存入Byte类型变量。
VB系统中16进制数只按十进制数处理,这要通过一个简单算法换算,解压BCD码才能还原成十进制表示数值。
假如a是Byte类型变量,将一个压缩的BCD 码存入a中,如0x81=129,D是Single类型变量0x81的转换结果为81。
整个BCD转10进制算法是:D=(a\16)*10 +a - (a\16)*16 ,其中(a\16)*10是BCD的十位部分,[a-(a\16)*16]是个位部分,将个位部分和十位部分提取公因式合并在一起有最终的转换算法D= a- (a\16)*6 如:a=0x81=129,D=129-(129\16)*6=81。
----程序清单:----在通用声明中定义程序所用变量:Dim ab(4) As Byte ‘字节数据类型数组,用来存储接收到的一组字节数据Dim av As Variant ‘用来从接收缓冲区读取数据Dim i As IntegerDim j As IntegerDim w As Integer ‘接收数据个数计数器Dim b1 As SingleDim b2 As SingleDim WW As Single ‘十进制检测值Dim MaxW As Single ‘最大值Dim MinW As Single ‘最小值----在窗体中添加名为Command1的[开始]按钮和名为MSComm1的MSComm控件。
---- [开始]按钮的Click事件处理程序主要是对MSComm1控制的参数初始化设置,程序中大部分参数在设计时可在MSComm1控制的属性窗口中设置:Private Sub Command1_Click() ‘开始按钮With MSComm1.CommPort=2 ‘使用COM2.Setting=“9600,N,8,1"‘设置通信口参数.InBufferSize=40 ‘设置MSComm1接收缓冲区为40字节 .OutBufferSize=2 ‘设置MSComm1发送缓冲区为2字节 .InputMode = comInputModeBinary ‘设置接收数据模式为二进制形式.InputLen = 1 ‘设置Input 一次从接收缓冲读取字节数为1.SThreshold = 1 ‘设置Output 一次从发送缓冲读取字节数为1.InBufferCount = 0 ‘清除接收缓冲区.OutBufferCount = 0 ‘清除发送缓冲区MaxW = 99 ‘最大值赋初值MinW = -99 ‘最小值赋初值w = 0 ‘数据个数计数器清零.RThreshold = 1 ‘设置接收一个字节产生OnComm事件If .PortOpen = False Then ‘判断通信口是否打开.PortOpen = True ‘打开通信口If Err Then ‘错误处理MsgBox “串口通信无效"Exit SubEnd IfEnd IfEnd WithEnd Sub----为了达到实时数据采集目的,实时数据采集处理程序采用MSComm事件驱动方式。
----MSComm1_OnComm的事件处理程序只处理comEvReceive事件,首先判断帧数据的开始字节,关闭OnComm接收事件,然后接收数据字节,将压缩BCD进行还原转换,再接收符号字节,判断数据符号,判断数据最大最小值,最后打开OnComm接收事件,等待下一次OnComm事件产生:Private Sub MSComm1_OnComm()With MSComm1Select Case .CommEvent‘判断MSComm1通信事件Case comEvReceive ‘收到Rthreshold个字节产生的接收事件av = .Input ‘读取一个接收字节ab(1) = av(0) ‘转换保存到字节数据类型数组If ab(1) = &HF0 Then ‘判断是否为数据开始标志RThreshold = 0‘关闭OnComm事件接收DoDoEvents ‘响应其他事件,Delphi中是Application.ProcessMessages;否则循环中不会响应其他事件,如同死机Loop Until .InBufferCount >= 3 ‘循环等待MSComm1接收缓冲区>=3个字节w = w +1 ‘计数器累加计数av = .Input ‘读取第二个数据字节(BCD码高位字节)ab(2) = av(0) ‘转换保存到字节数据类型数组av = .Input ‘读取第三个数据字节(BCD码低位字节)ab(3) = av(0) ‘转换保存到字节数据类型数组av = .Input ‘读取第四个数据字节(符号位字节)ab(4) = av(0) ‘转换保存到字节数据类型数组b1 = ab(2) -6 *(ab(2)\16) ‘高位字节压缩BCD码转换为实数b2 = ab(3) -6 *(ab(3)\16) ‘低位字节压缩BCD码转换为实数WW = b1 +b2 / 100 ‘数值组合,标定小数点If ab(4) > 127 Then WW = -WW ‘判断数据符号位Label1(0) = Format(WW, “0.00")‘显示毫米单位数值,2位小数Label1(1) =Format(WW /25.4, “0.000") '显示英寸单位数值,3位小数If WW > MaxW Then----判断最大值,仪表在刚开始工作时有干扰,会传导一些乱码,位移传感器有参数偏差,最大值一般都略大于50毫米,所以取51为极限最大值,取-51为极限最小值。
MaxW = 51Label1(2) = Format(MaxW, “0.00")‘显示毫米单位最大值,2位小数Label1(3) = Format(MaxW/25.4,“0.000")‘显示英寸单位最大值,3位小数End IfIf WW < MinW Then‘判断最小值MinW = -51Label1(4) = Format(MinW, “0.00")‘显示毫米单位最小值,2位小数Label1(5) = Format(MinW/25.4,“0.000")‘显示英寸单位最小值,3位小数End If.RThreshold = 1 ‘打开MSComm1事件接收End If ' 对应If ab(1) = &HF0 Then ‘判断是否为数据开始标志Case ElseEnd SelectEnd WithEnd Sub。