傅宏伟
(安徽先河消防科技工程有限公司,安徽 合肥 230000)
利用Delphi实现串口通信的常用的方法有3种:一是利用控件,如MSComm控件和Spcomm控件;二是使用API函数;三是调用其它串口通信程序。使用API方法的优点是比较适合于编写较为复杂的低层次通信程序,但缺点是编写串口通信程序较为复杂,需要掌握大量通信知识。相比较而言,利用Spcomm控件则相对较简单,Spcomm是Small-Pig Team开发的一个第三方Delphi串口控件,Spcomm控件并不是DELPHI 7.0自带的控件,需要自己到相关网站下载并安装到相关目录下,该控件具有丰富的与串口通信密切相关的属性及事件,提供了对串口的各种操作,编程简单、通用性强、可移植性好,而且还支持多线程,在Delphi软件开发中已经成为一个被广泛应用的串口通信开发控件。
Windows环境下的串口编程与DOS环境下的串口编程有很大的不同。Windows环境下的串口编程的最大特征之一就是设备无关性,它通过设备驱动程序将Windows应用程序与不同的外界设备隔离。Windows封装了Windows的通信机制,这种方式称为通信API,Windows程序员可以利用Windows通信API进行编程,不用直接对硬件操作。
WIN 32通信API基本上是一个串行端口API,不是很适合局域网(LAN)通信。它把串口操作(以及并口等)与文件操作统一起来,使用类似的操作来实现。
用Windows API函数实现串口通信的主要事件有:
(1)打开和关闭串口:分别是用CreatFile函数和Close Handle函数实现。
(2)串口配置和属性设置:使用GetCommState()函数获取串口当前配置,使用SetCommState()从新分配串口资源的各个参数。在配置串口属性时,应该先了解串口设备的属性。通过GetCommProperties()函数获得串口的属性。
(3)读/写串口:使用ReadFile()和WriteFile函数来实现。
(4)编写相应的OnClick事件的相关代码。
MSComm控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。
(1)MSComm控件两种处理通讯的方式
MSComm控件提供下列两种处理通讯的方式:事件驱动方式和查询方式。
(2)MSComm控件的常用属性
CommPort:设置并返回通讯端口号;
Settings:以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位;
PortOpen:设置并返回通讯端口的状态。也可以打开和关闭端口;
Input:从接收缓冲区返回和删除字符;
Output:向传输缓冲区写一个字符串;
EOFEnable:确定在输入过程中MSComm控件是否寻找文件结尾(EOF)字符。如果找到EOF字符,将停止输入并激活OnComm事件,此时CommEvent属性设置为comEvEOF。
MSComm控件的事件只有一个,就是OnComm事件。
(3)使用MSComm控件实现串口通信的基本流程:
1)添加MSComm控件
2)初始化并打开串口
3)捕捉串口事件
4)串口读写
5)关闭串口
Spcomm控件并不是Delphi 7.0自带的控件,需要自己到相关网站下载并安装到相关目录下。利用Spcomm控件就可以实现串口通信,因为该控件具有丰富的与串口通信密切相关的属性及事件,提供了对串口的各种操作,而且还支持多线程,能实现一般的串口通信需要。
Spcomm的安装:
(1)选择下拉菜单Component中的Install Component选项,在Unit file name处填写Spcomm控件所在的路径,其它各项可用默认值,点击OK按钮。
(2)安装后,在System控件面板中将出现一个红色控件Com。
Spcomm的属性、方法和事件:
(1)属性
CommName:表示Com1、Com2等串口的名字;
BaudRate:根据实际需要设定的波特率,在串口打开后也可更改此值,实际波特率随之更改;
ParityCheck:表示是否需要奇偶校验;
ByteSize:根据实际情况设定的字节长度;
Parity:奇偶校验位;
StopBits:停止位;
SendDataEmpty:这是一个布尔型属性,为true时表示发送缓存为空,或者发送队列里没有信息;为false时表示发送缓存不为空,或者发送队列里有信息。
(2)方法
StartComm方法用于打开串口,当打开失败时通常会报错。错误主要有7种:串口已经打开;打开串口错误;文件句柄不是通信句柄;不能够安装通信缓存;不能产生事件;不能产生读进程;不能产生写进程。
StopComm方法用于关闭串口,没有返回值。
WriteCommData(pDataToWrite:PChar;dwSizeofDataToWrite:Word)方法是个带有布尔型返回值的函数,用于将一个字符串发送到写进程,发送成功返回true,发送失败返回false。执行此函数将立即得到返回值,发送操作随后执行。该函数有两个参数,其中pDataToWrite是要发送的字符串,dwSizeofDataToWrite是发送字符串的长度。
(3)事件
ata:procedure(Sender:TObject;Buffer:Pointer;BufferLength:Word)of object当有数据输入缓存时将触发该事件,在这里可以对从串口收到的数据进行处理。Buffer中是收到的数据,BufferLength是收到的数据长度。
OnReceiveError:procedure(Sender:TObject;EventMask:DWORD)当接收数据出现错误时将触发该事件。
在使用Spcomm控件的时候,首先要添加一个Com控件,之后设定Com1属性,再设置Com控件的发送和接受的触发事件,最后编写源代码并进行调试。
(4)Spcomm串口通信的实现
Spcomm串行通信控件具有多线程的特性,接收和发送数据分别在两个线程内完成,接收线程负责收到数据时触发OnReceiveData事件;用WriteCommData()函数将待发送的数据写入输出缓冲器,发送线程在后台完成数据发送工作。在接收和发送数据前需要初始化串口,用StartComm方法打开串口,退出程序时用StopComm方法关闭串口。
除了使用Windows API函数、MSCOMM控件、Spcomm控件实现串口通信,还可以使用CommPortDrv控件、SerialPort控件等。除了通用的串口通信控件,还有一些专用的串行通信控件用于处理特定的设备模块,例如TGPS控件就是专门处理GPS接受机串行通信输出的NMEA-0183格式的数据,分析得到定位信息等。这些通信控件一般都极大地简化了对底层的设置,提供了许多强大的功能,可以加快程序的开发过程。
图1 发送窗口界面
代码实现:
保存数据功能代码如下:
图2 实现实时数据发送界面
设计的关键是使用Spcomm控件和Timer控件实现。
(1)初始化
需要选择本次通信使用的串口,设置波特率、校验方式、数据位、停止位等属性,打开该串口。示例代码如下:
这与具体实现的PC机有关,在设置软件Com口属性前应该先查看好该机器的Com属性,使得二者能匹配,这样能避免在用模拟软件实现实时数据发送时出现错误。
(2)发送测试数据
实现模拟的实时数据采集,首先要调试串口,测试信号可以随意选择某特定字符串,通过发送测试信号实现,当PC发出这样一些测试数据后,通过接收事件能收到特定的某字符串,则表示测试成功,串口发送数据可以正常进行。否则需重新发送测试信号。
以下为向计算机发送一个测试数据:
代码如下:
(3)发送数据
(4)关闭串口
(5)定时器设计
首先,Spcomm是通过 ReadIntervalTimeout属性的设置,来确定所接收到的数据是否属于同一帧数据,其默认值是100ms,也就是说,只要任何两个字节到达的时间间隔小于100ms,都被认为是属于同一帧数据,在与单片机协同工作时,要特别注意这个问题。
另外,Spcomm的默认属性设置是支持软件流控制的,用于流控制的字符是13H(XoffChar)和11H(XonChar),当以二进制方式发送数据时,必须要禁用Spcomm对于软件流控制的支持,否则,在数据帧中出现的13H,11H会被Spcomm作为控制字符而加以忽略。
实践证明,利用Spcomm串行通信控件在Delphi7.0中开发串口通信程序,具有灵活、方便、高效的特点。
[1]李军.Delphi 7项目开发实践[M].北京:中国铁道出版社,2003.
[2]赵兰涛苏彦华.Delphi串口通信技术与工程实践[M].北京:人民邮电出版社,2004.
[3]张宏林.Delphi 7程序设计与开发技术大全[M].北京:人民邮电出版社,2004.
[4]刘宗键.Delphi7程序设计入门[M].天津:天津电子出版社,2003.
[5]刘斌,李文革.Delphi 7高级教程[M].北京:清华大学出版社,2004.
[6]彭明明,程文刚.Delphi实用编程100例[M].北京:中国铁道出版社,2004.
[7]杨长春.Delphi程序设计教程[M].北京:清华大学出版社,2005.
[8]康祥顺.Delphi案例开发集锦[M].北京:电子工业出版社,2005.
[9]刘山,赵辉.Delphi系统开发实例精粹[M].北京:人民邮电出版社,2005.