摘要
本文介绍了在Windows平台下串口开发的方法
并给出一个使用Delphi设计的远程数据采集的实例
引言
在工业生产实践中使用PC机对Inprise公司推出的Delphi是一种功能强大的高级编程语言其具有可视化面向对象的特征特别适合Windows平台下的图形界面和用户程序的编制本文就介绍在Windows平台下用Delphi开发串口的方法和使用Delphi设计的一个实现远程串行数据采集的实例
串口工作原理及软件实现方法
串口进行通信的方式有两种同步通信方式和异步通信方式同步通信方式要求通信双方以相同的时钟频率进行而且准确协调通过共享一个单个时钟或定时脉沖源保证发送方和接收方的准确同步效率较高异步通信方式不要求双方同步收发方可采用各自的时钟源双方遵循异步的通信协议以字符为数据传输单位发送方传送字符的时间间隔不确定发送效率比同步传送效率低
在Windows平台下Win API支持同步和异步两种I/O操作同步操作的方式的程序设计相对比较简单但是I/O操作函数在I/O操作结束前不能返回这将挂起调用线程直到I/O操作结束异步操作方式要相对复杂一些但是可以让I/O操作在后台运行而不会挂起调用线程这在大数据量通信情况下对改善调用线程的响应速度是相当有效的同时由于Winx和WinNT下对串行通信的处理不同这就导致了在Winx下开发的同步方式串行通信程序在NT下会发生工作线程之间的协作阻塞即当读线程在等待WaitCommEvent的时候写线程不能正常工作停在那里整个程序处于瘫痪状态这个问题是Windows的API函数处理串行通信的一个BUG所以对于适应性强的程序都是选择异步方式下面本文对在Windows平台下对串口进行开发的方法进行介绍
. 汇编程序直接读写串口
汇编语言的编译效率和执行效率都很高使用汇编语言直接对串口进行操作可以部分弥补串行通信速度较慢的缺陷具体做法是用汇编语言编写读写串口的函数在通信程序中直接调用或者在Delphi中直接内嵌汇编程序进行对端口的读写
例如
asm
mov dxh
mov axeh
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参数是要打开的串口名称如COMDwFlagsAndAttributes参数决定对串口的操作是同步操作还是异步操作DwDesiredAccess参数是访问方式可取GENERIC_READ或GENERIC_WRITEDwShareMode参数是共享模式对串口物理设备必须取LpSecurityAttributes参数是安全属性取值为NULLDwFlagsAndAttributes是文件属性和标识一般取值为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函数编写串口通信程序比较复杂需要掌握大量的系统和通信知识其优点是实现的功能强大应用面广泛适合编写较为复杂的地层次应用程序
[] []