直接上参考程序:
Dim av As VariantDim datacount As Long
Private Sub cmdClear_Click()
txtData.Text = ""
End Sub
Private Sub cmdStop_Click()
'关闭端口
If MSComm.PortOpen = True Then
MSComm.InBufferCount = 0 '清空缓冲区
MSComm.PortOpen = False
End If
cmdReceive.Enabled = True
lblStatus.Caption = "停止接收,空闲"
End Sub
Private 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 Then
族仿 MSComm.PortOpen = True
If Err Then
MsgBox (Err.Description)
Exit Sub
End If
End If
lblStatus.Caption = "打开端口,等待接收"
datacount = 0
cmdReceive.Enabled = False
End Sub
Private Sub cmdSave_Click()
Dim outfn As String
MsgBox ("接收了" + 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 = True
On Error GoTo errhandler
CommonDialog1.ShowSave
outfn = CommonDialog1.FileName
Open outfn For Output As #1
Print #1, txtData.Text
Close #1
'txtData.SaveFile outfn
lblStatus.Caption = "输出完成,空闲"
errhandler:
Exit Sub
End Sub
Private Sub Form_Load()
lblStatus.Caption = "空闲"
End Sub
Private Sub Form_Unload(Cancel As Integer)
'关闭端口
If MSComm.PortOpen = True Then
MSComm.InBufferCount = 0 '清空缓冲区
MSComm.PortOpen = False
End If
End Sub
Private Sub MSComm_OnComm()
Dim T1, T2 As Long
Select Case MSComm.CommEvent
Case comEvReceive '收到Rthreshold个字节兆手纤产生的接收事件
MSComm.RThreshold = 0 '关闭OnComm事件接收
lblStatus.Caption = "接收"
av = MSComm.Input '读取一个接收字节
dataframe(1) = av(0) '转换为字节
If dataframe(1) = &HA Then '接收到T1
Do
DoEvents
Loop Until MSComm.InBufferCount >= 2 '循环等待接收缓冲区>=2个字节
av = MSComm.Input
dataframe(2) = av(0)
av = MSComm.Input
dataframe(3) = av(0) '接收T1
T1 = dataframe(2) + CLng(dataframe(3)) * 256 '计算T1
End If
薯销 Do
DoEvents
Loop Until MSComm.InBufferCount >= 1 '循环等待接收缓冲区>=1个字节
av = MSComm.Input '读取一个接收字节
dataframe(4) = av(0) '转换为字节
'接收到T2
If dataframe(4) = &HA0 Then
'MSComm.RThreshold = 0 '关闭OnComm事件接收
'循环等待接收缓冲区>=2个字节
Do
DoEvents
Loop Until MSComm.InBufferCount >= 2
av = MSComm.Input
dataframe(5) = av(0)
av = MSComm.Input
dataframe(6) = av(0) '接收T2
T2 = dataframe(5) + CLng(dataframe(6)) * 256 '计算T2
'显示T1 T2 enter
txtData.Text = txtData.Text + CStr(T1) + " " + CStr(T2) + Chr(&HD) + Chr(&HA)
datacount = datacount + 1 '数据组数+1
End If
MSComm.RThreshold = 1 '打开OnComm事件接收
Case Else
End Select
End Sub
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文本文件中
如果需要 做其他‘文件格式的处理, 数据已经拿到了,想怎么弄就变通下吧。
摘要 本文介绍了在Windows平台下串口开发的方法 并给出一个使用Delphi设计的远程数据采集的实例 引言在工业生产实践中 使用PC机对Inprise公司推出的Delphi是一种功能强大的高级编程语言 其具有可视化面向对象的特征 特别适合Windows平台下的图形界面和用户程序的编制 本文就介绍在Windows平台下用Delphi开发串口的方法和使用Delphi设计的一个实现远程串行数据采集的实例 串口工作原理及软件实现方法串口进行通信的方式有两种 同步通信方式和异步通信方式 同步通信方式要求通信双方以相同的时钟频率进行 而且准确协调 通过共享一或衡个单个时钟或定时脉冲源保证发送方和接收方的准确同步 效率较高 异步通信方式不要求双方同步 收发方可采用各自的时钟源 双方遵循异步的通信协议 以字符为数据传输单位 发送方传送字符的时间间隔不确定 发送效率比同步传送效率低 在Windows平台下 Win API支持同步和异步两种I/O *** 作 同步 *** 作的方式的程序设计相对比较简单 但是I/O *** 作函数在I/O *** 作结束前不能返回 这将挂起调用线程 直到I/O *** 作结束 异步 *** 作方式要相对复杂一些 但是可以让I/O *** 作在后台运行 而不会挂起调用线程 这在大数据量通信情况下对改善调用线程的响应速度是相当有效的 同时由于Win x和WinNT下对串行通信的处理不同 这就导致了在Win x下开发的同步方式串行通信程序在NT下会发生工作线程之间的协作阻塞 即当读线程在等待WaitCommEvent的时候 写线程不能正常工作 停在那里 整个程序处于瘫痪状态 这个问题是Windows的API函数处理串行通信的一个BUG 所以对于适应性强的程序都是选择异步方式 下面 本文对在Windows平台下对串口进行开发的方法进行介绍 . 汇编程序直接读写串口汇编语言的编译效率和执行效率都很高 使用汇编语言直接对串口进行 *** 作可以部分弥补串行通信速度较慢的缺陷 具体做法是 用汇编语言编写读 写串口的函数 在通信程序中直接调用 或者在Delphi中直接内嵌汇编程序进行对端口的读写 例如a *** mov dx h mov ax eh int h end 这样可以达到直接读到端口的效果 但是在WinNT和Win 下 系统使用了保护机制 不允许用户态的程序直接读取端口 所以在WinNT和Win 下 这种方法不能被允许执行 Ring 的用户态的程序要进入Ring 去读写端口必须先提供一个驱动(sys)程序 然后通过DLL导出函数供用户程序调用 显然 这种方法比较不容易实现 . 使用API函数进行串口编程Windows系统通信一般都以WOSA(Windows Open Service Architecture 即Windows开放式服务体系)模型为基础 在此模型中位于上层的应用程序通过调用各种通信API(Application Programming Interfaces 即应用程序接口)与位于下层的设备驱动程序进行数据交换 在Windows平台下 Windows将设备看作是文件进行启团手管理 对设备的 *** 作也可以看作是对文件的 *** 作 Win API提供了CreateFile() WriteFile() ReadFile() WaitForSingleObject() WaitForMultipleObjects() CreateEvent() CreateMutex() CreateSemaphore() CreateThread()等函数 其基本步骤如下 ( )悄嫌 利用CreateFile()函数打开串口 该函数有七个参数 其中dwCreationDistribution参数取OPEN_EXISTING 表明打开的串口对应于实际的物理串口 lpFileName参数是要打开的串口名称 如 DwFlagsAndAttributes参数决定对串口的 *** 作是同步 *** 作还是异步 *** 作 DwDesiredAccess参数是访问方式 可取GENERIC_READ或GENERIC_WRITE DwShareMode参数是共享模式 对串口物理设备必须取 LpSecurityAttributes参数是安全属性 取值为NULL DwFlagsAndAttributes是文件属性和标识 一般取值为FILE_ATTRIBUTE_NORMAL 该函数返回串口 *** 作的句柄 ( ) 对该串口句柄对应的设备进行配置 如波特率 数据位 停止位 是否奇偶校验等 这部分首先使用GetCommState()函数得到当前的串口配置信息 将这些信息存放在一个DCB结构中 然后对该DCB结构里面的内容进行重新按要求设置 最后调用SetCommState()函数使修改的设置生效 ( ) 配置串口事件 SetCommMask()函数可以设置多个串口信息事件 其串口的信息事件可以是以下任意的组合 EV_BREAK 在输入时Windows检测到中断 EV_CTS CTS信号改变状态 EV_DSR DSR信号改变状态 EV_ERR 发生线状态错误 EV_RING 检测到振铃指示 EV_RLSD 接收线信号探测状态发生改变 EV_RXCHAR 接收缓冲区里收到字符 EV_RXFLAG 收到事件字符 并放入接收缓冲区 EV_TXEMPTY 输出缓冲区空 ( ) 创建串口监视线程监视串口事件 首先使用WaitForSingleObject() WaitForCommEvent() WaitForMultipleObjects()等等待函数对线程进行控制 当没有数据收发时 将线程阻塞 减少其CPU的资源占用 当有数据收发时 线程自动启动 完成数据的收发 最后调用CreateThread()函数启动线程 ( ) 串口使用结束 用CloseHandle()函数关闭串口 回收资源 由此可见 利用Win API函数编写串口通信程序比较复杂 需要掌握大量的系统和通信知识 其优点是实现的功能强大 应用面广泛 适合编写较为复杂的地层次应用程序 lishixinzhi/Article/program/Delphi/201311/24926
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)