DELPHI串口编程剖析

DELPHI串口编程剖析 1

第一章 背景知识 3
1. 概述 3
2. 什么是接口? 3
3. 接口分类. 3
4. 为何须要I/O接口? 3
5. I/O接口的功能 4
6. I/O接口的通讯方式 5
7. I/O接口的分类 5
8. 串口的分类 8
9. 串口通讯分类 11
10. 奇偶校验 12
第二章 串口通讯编程简介 13
1. 串口的通讯编程流程 13
2. Unix平台下对串口进行开发的方法 13
3. Windows平台下对串口进行开发的方法 13
第三章 使用DELPHI工具进行串口通讯编程 15
第四章 串口编程的调试及其相关工具 27


 
串口通讯编程剖析
第一章 背景知识
1. 概述
串口是计算机上I/O接口的一种,要掌握串口通讯编程的相关知识,必须先了解I/O接口的相关知识。
I/O接口是接口的一种。

2. 什么是接口?
众所周知计算机是由CPU,存储器,外部终端设备组成.
接口就是用于CPU与外部设备、存储器的链接和数据交换的设备。


3. 接口分类.
广义的计算机接口有二种,见下表:
类別 用途 电路实现复杂性
存储器接口: 用于CPU与外部设备、存储器的链接 简单
I/O接口 数据交换 复杂

习惯上说到接口只是指I/O接口。本文沒做特別介绍的地方都叫I/O接口.


4. 为何须要I/O接口?
计算机的外围设备品种繁多,几乎都采用了机电传动设备,所以,CPU在与I/O设备进行数据交换时存在如下问题:

速度不匹配:
I/O设备的工做速度要比CPU慢许多,并且因为种类的不一样,他们之间的速度差别也很大,例如硬盘的传输速度就要比打印机快出不少。

时序不匹配:
各个I/O设备都有本身的定时控制电路,以本身的速度传 输数据,没法与CPU的时序取得统一。

信息格式不匹配:
不一样的I/O设备存储和处理信息的格式不一样,例如能够分为串行和并行两种;也能够分为二进制格式、ACSII编码和BCD编码等。

信息类型不匹配:
不一样I/O设备采用的信号类型不一样,有些是数字信号,而有些是模拟信号,所以所采用的处理方式也不一样。
  
基于以上缘由,CPU与外设之间的数据交换必须经过I/O接口来完成。

5. I/O接口的功能
一般I/O接口有如下一些功能:
1)设置数据的寄存、缓冲逻辑,以适应CPU与外设之间的速度
差别,接口一般由一些寄存器或RAM芯片组成,若是芯片足够大还能够实现批量数据的传输;

2)可以进行信息格式的转换,例如串行和并行的转换;

3)可以协调CPU和外设二者在信息的类型和电平的差别,如电平
转换驱动器、数/模或模/数转换器等;
  
4)协调时序差别;
  
5)地址译码和设备选择功能;
  
6)设置中断和DMA控制逻辑,以保证在中断和DMA容许的状况下产生中断和DMA请求信号,并在接受到中断和DMA应答以后完成中断处理和DMA传输。
  
6. I/O接口的通讯方式
CPU经过接口对外设进行控制的方式有如下几种:
1)程序查询方式
这种方式下,CPU经过I/O指令询问指定外设当前的状态,若是外设
准备就绪,则进行数据的输入或输出,不然CPU等待,循环查询。
这种方式的优势是结构简单,只须要少许的硬件电路便可,缺点是由
于CPU的速度远远高于外设,所以一般处于等待状态,工做效率很
低。

2)中断处理方式
在这种方式下,CPU再也不被动等待,而是能够执行其余程序,一旦
外设为数据交换准备就绪,能够向CPU提出服务请求,CPU若是响
应该请求,便暂时中止当前程序的执行,转去执行与该请求对应的
服务程序,完成后,再继续执行原来被中断的程序。
  中断处理方式的优势是显而易见的,它不但为CPU省去了查询外设
状态和等待外设就绪所花费的时间,提升了CPU的工做效率,还满
足了外设的实时要求。但须要为每一个I/O设备分配一个中断请求号
和相应的中断服务程序,此外还须要一个中断控制器(I/O接口芯
片)管理I/O设备提出的中断请求,例如设置中断屏蔽、中断请求
优先级等。此外,中断处理方式的缺点是每传送一个字符都要进行
中断,启动中断控制器,还要保留和恢复现场以便能继续原程序的
执行,花费的工做量很大,这样若是须要大量数据交换,系统的性
能会很低。

3)DMA(直接存储器存取)传送方式
DMA最明显的一个特色是它不是用软件而是采用一个专门的控制
器来控制内存与外设之间的数据交流,无须CPU介入,大大提升
CPU的工做效率。  
在进行DMA数据传送以前,DMA控制器会向CPU申请总线控
制 权,CPU若是容许,则将控制权交出,所以,在数据交换时,
总线控制权由DMA控制器掌握,在传输结束后,DMA控制器将
总线控制权交还给CPU。
  
7. I/O接口的分类
7.1. 并行接口

  目前,计算机中的并行接口主要做为打印机端口,接口使用的再也不是36针接头而是25针D形接头。所谓“并行”,是指8位数据同时经过并行线进行传送,这样数据传送速度大大提升,但并行传送的线路长度受到限制,由于长度增长,干扰就会增长,容易出错。
  如今有五种常见的并口:4位、8位、半8位、EPP和ECP,大多数PC机配有4位或8位的并口,许多利用Intel386芯片组的便携机配有EPP口,支持所有IEEE1284并口规格的计算机配有ECP并口。
  标准并行口4位、8位、半8位:
  4位口一次只能输入4位数据,但能够输出8位数据;8位口能够一次输入和输出8位数据;半8位也能够。
  EPP口(加强并行口):由Intel等公司开发,容许8位双向数据传送,能够链接各类非打印机设备,如扫描仪、LAN适配器、磁盘驱动器和CDROM 驱动器等。
  ECP口(扩展并行口):由Microsoft、HP公司开发,能支持命令周期、数据周期和多个逻辑设备寻址,在多任务环境下可使用DMA(直接存储器 访问)。
  目前几乎全部的586机的主板都集成了并行口插座,标注为 Paralle1或LPT1,是一个26针的双排针插座。

7.2. 串行接口

  计算机的另外一种标准接口是串行口,如今的PC机通常至少有两个串行口COM1和COM2。串行口不一样于并行口之处在于它的数据和控制信息是一位接一位串行地传送下去。这样,虽然速度会慢一些,但传送距离较并行口更长,所以长距离的通讯应使用串行口。一般COM1使用的是9针D形链接器,而COM2有些使 用的是老式的DB25针链接器。
  

7.3. 磁盘接口

1)IDE接口
  IDE接口也叫作ATA端口,只能够接两个容量不超过528M的硬盘驱动器,接口的成本很低,所以在38六、486时期很是流行。但大多数IDE接口不支持DMA数据传送,只能使用标准的PCI/O端口指令来传送全部的命令、状态、数据。几乎全部的586主板上都集成了两个40针的双排针IDE接口插座,分别标注为IDE1和IDE2。
2)EIDE接口
  EIDE接口较IDE接口有了很大改进,是目前最流行的接口。
首先,它所支持的外设再也不是2个而是4个了,所支持的设备除了硬盘,还包括CD-ROM驱动器磁盘备份设备等。  

其次,EIDE标准取消了528MB的限制,代之以8GP限制。  
第三,EIDE有更高的数据传送速率,支持PIO模式3和模式4标准。
  

7.4. SCSI接口

  SCSI(SmallComputerSystemInterface)小计算机系统接口,在作图形处理和网络服务的计算机中被普遍采用SCSI接口的硬盘。除了硬盘之外,SCSI接口还能够链接CD-ROM驱动器、扫描仪和打印机等,它具备如下特色:
  *可同时链接7个外设;
  *总线配置为并行8位、16位或32位;
  *容许最大硬盘空间为8.4GB(有些已达到9.09GB);
  *更高的数据传输速率,IDE是2MB每秒,SCSI一般能够达到5MB每秒,FASTSCSI(SCSI-2)能达到10MB每秒,最新的SCSI-3甚至可以达到40MB每秒,而EIDE最高只能达到16.6MB每秒;
  *成本较IDE和EIDE接口高不少,并且,SCSI接口硬盘必须和SCSI接口卡配合使用,SCSI接口卡也比IED和EIDE接口贵不少。
  *SCSI接口是智能化的,能够彼此通讯而不增长CPU的负担。在IDE和EIDE设备之间传输数据时,CPU必须介入,而SCSI设备在数据传输过程当中起主动做用,并能在SCSI总线内部具体执行,直至完成再通知CPU。
  

7.5. USB接口

  最新的USB串行接口标准是由Microsoft、Intel、Compaq、IBM等大公司共同推出,它提供机箱外的热即插即用链接,用户在链接外设时不用再打开机箱、关闭电源,而是采用“级联”方式,每一个USB设备用一个USB插头链接到一个外设的USB插座上,而其自己又提供一个USB插座给下一个USB设备使用,经过 这种方式的链接,一个USB控制器能够链接多达127个外设,而每一个外设间的距离可达5米。USB统一的4针圆形插头将取代机箱后的众多的串/并口(鼠标、MODEM)键盘等插头。USB能智能识别USB链上外围设备的插入或拆卸。   除了可以链接键盘、鼠标等,USB还能够链接ISDN、电话系统、数字音响、打印机以及扫描仪等低速外设。
  

7.6. I/O扩展槽


  I/O扩展槽即I/O信号传输的路径,是系统总线的延伸,能够插入任意的标准选件,如显示卡、解压卡、MODEM卡和声卡等。经过I/O扩展槽,CPU可对链接到该通道的全部I/O接口芯片和控制卡寻址访问,进行读写。
  根据总线的类型不一样,主板上的扩展槽可分为ISA、EISA、MAC、VESA和PCI几种。
  1)ISA插槽
  黑色,分为8位、16位两种。16位的扩展槽能够插8位和16位的控制卡,但8位的扩展槽只能插8位卡。
  2)EISA插槽
  棕色,外型、长度与16位的ISA卡同样,但深度较大,可插入ISA与EISA控制卡。
  3)VESA插槽
  棕色,位于16位ISA扩展插槽的下方,与ISA插槽配合使用。
  4)PCI插槽
白色,与VESA插槽同样长,与ISA插槽平行,不须要与ISA插槽配合使用,并且只能插入PCI控制卡。因为主板的空间有限,PCI插槽要占用ISA插槽的位置


8. 串口的分类
8.1. RS-232-C接口
RS-232-C接口(又称 EIA RS-232-C)是目前最经常使用的一种串行通信接口。它是在1970年由美国电子工业协会(EIA)联合贝尔系统、 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通信的标 准。它的全名是“数据终端设备(DTE)和数据通信设备(DCE)之间 串行二进制数据交换接口技术标准”该标准规定采用一个25个脚的 DB25链接器,对链接器的每一个引脚的信号内容加以规定,还对各类信 号的电平加以规定。
(1) 接口的信号内容 实际上RS-232-C的25条引线中有许可能是不多使用的,在计算机与终端通信中通常只使用3-9条引线。RS-232-C最经常使用的9条引线的信号内容见下所示

引脚序号 信号名称 符号 流向 功能
2 发送数据 TXD DTE→DCE DTE发送串行数据
3 接收数据 RXD DTE←DCE DTE接收串行数据
4 请求发送 RTS DTE→DCE DTE请求DCE将线路切换到发送方式
5 容许发送 CTS DTE←DCE DCE告诉DTE线路已接通能够发送数据
6 数据设备准备好 DSR DTE←DCE DCE准备好
7 信号地     信号公共地
8 载波检测 DCD DTE←DCE 表示DCE接收到远程载波
20 数据终端准备好 DTR DTE→DCE DTE准备好
22 振铃指示 RI DTE←DCE 表示DCE与线路接通,出现振铃

(2)接口的电气特性 在RS-232-C中任何一条信号线的电压均为负逻辑关系。即:逻 辑“1”,-5— -15V;逻辑“0” +5— +15V 。噪声容限为2V。即 要求接收器能识别低至+3V的信号做为逻辑“0”,高到-3V的信号 做为逻辑“1”.

 
(3) 接口的物理结构 RS-232-C接口链接器通常使用型号为DB-25的25芯插头座,一般插头在DCE端,插座在DTE端. 一些设备与PC机链接的RS-232-C接口,由于不使用对方的传送控制信号,只需三条接口线,即“



发送数据”、“接收数据”和“信号地”。因此采用DB-9的9芯插头座,传输线采用屏蔽双绞线。

4)传输电缆长度 由RS-232C标准规定在码元畸变小于4%的状况下,传输电缆长度应为50英尺,其实这个4%的码元畸变是很保守的,在实际应用中,约有99%的用户是按码元畸变10-20%的范围工做的,因此实际使用中最大距离会远超过50英尺,美国DEC公司曾规定容许码元畸变为10%而得出附表2 的实验结果。其中1号电缆为屏蔽电缆,型号为DECP.NO.9107723 内有三对双绞线,每对由22# AWG 组成,其外覆以屏蔽网。2号电缆为不带屏蔽的电缆。型号为DECP.NO.9105856-04是22#AWG的四芯电缆。 下面是C 公司的实验结果
波特率 1 号电缆传输距离(英尺) 2 号电缆传输距离(英尺)
110 5000 3000
300 5000 3000
1200 3000 3000
2400 1000 500
4800 1000 250
9600 250 250
 
8.2. RS-485接口
因为RS-232-C接口标准出现较早,不免有不足之处,主要有如下四点:
(1) 接口的信号电平值较高,易损坏接口电路的芯片,又由于与TTL 电平不兼容故需使用电平转换电路方能与TTL电路链接。
(2) 传输速率较低,在异步传输时,波特率为20Kbps。
(3) 接口使用一根信号线和一根信号返回线而构成共地的传输形式, 这种共地传输容易产生共模干扰,因此抗噪声干扰性弱。
(4) 传输距离有限,最大传输距离标准值为50英尺,实际上也只能 用在50米左右。
针对RS-232-C的不足,因而就不断出现了一些新的接口标准,RS-485就是其中之一,它具备如下特色:
1. RS-485的电气特性:逻辑“1”以两线间的电压差为+(2—6) V表示;逻辑“0”以两线间的电压差为-(2—6)V表示。接口信号电平比RS-232-C下降了,就不易损坏接口电路的芯片, 且该电平与TTL电平兼容,可方便与TTL 电路链接。
2. RS-485的数据最高传输速率为10Mbps
3. RS-485接口是采用平衡驱动器和差分接收器的组合,抗共模干能力加强,即抗噪声干扰性好。
4. RS-485接口的最大传输距离标准值为4000英尺,实际上可达 3000米,另外RS-232-C接口在总线上只容许链接1个收发器, 即单站能力。而RS-485接口在总线上是容许链接多达128个收发器。即具备多站能力,这样用户能够利用单一的RS-485接口方便地创建起设备网络。
因RS-485接口具备良好的抗噪声干扰性,长的传输距离和多站能力等上述优势就使其成为首选的串行接口。 由于RS485接口组成的半双工网络,通常只需二根连线,因此RS485接口均采用屏蔽双绞线传输。 RS485接口链接器采用DB-9的9芯插头座,与智能终端RS485接口采用DB-9(孔),与键盘链接的键盘接口RS485采用DB-9(针)。
3. 采用RS485接口时,传输电缆的长度如何考虑?
在使用RS485接口时,对于特定的传输线经,从发生器到负载其数据信号传输所容许的最大电缆长度是数据信号速率的函数,这个 长度数据主要是受信号失真及噪声等影响所限制。下图所示的最大电缆长度与信号速率的关系曲线是使用24AWG铜芯双绞电话电缆(线 径为0.51mm),线间旁路电容为52.5PF/M,终端负载电阻为100欧 时所得出。(曲线引自GB11014-89附录A)。由图中可知,当数据信 号速率下降到90Kbit/S如下时,假定最大容许的信号损失为6dBV时, 则电缆长度被限制在1200M。实际上,图中的曲线是很保守的,在实 用时是彻底能够取得比它大的电缆长度。 当使用不一样线径的电缆。则取得的最大电缆长度是不相同的。例 如:当数据信号速率为600Kbit/S时,采用24AWG电缆,由图可知最 大电缆长度是200m,若采用19AWG电缆(线径为0。91mm)则电缆长 度将能够大于200m; 若采用28AWG 电缆(线径为0。32mm)则电缆 长度只能小于200m。
9. 串口通讯分类
9.1. 按信息的传送方向分
根据信息的传送方向,串口通讯以进一步分为单工、半双工和全双工三种。
若是在通讯过程的任意时刻,信息只能由一方A传到另外一方B,则称为单工。
若是在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方向上的传输存在,称为半双工传输。
若是在任意时刻,线路上存在A到B和B到A的双向信号传输,则称为全双工。电话线就是二线全双工信道。 因为采用了回波抵消技术,双向的传输信号不致混淆不清。双工信道有时也将收、发信道分开,采用分离的线路或频带传输相反方向的信号,如回线传输。
--------> <--------> -------->
A---------B A----------B A---------B
    <--------
单工 半双工 全双工


9.2. 按信息的交互方式分
串口通讯又分为异步通讯和同步通讯两种方式。
10. 奇偶校验
串口数据在传输过程当中,因为干扰可能引发信息的出错,例如,传输字符‘E’,其各位为:
0100,0101=45H
D7 D0
因为干扰,可能使位变为1,这种状况,咱们称为出现了“误码”。咱们把如何发现传输中的错误,叫“检错”。发现错误后,如何消除错误,叫“纠错”。
最简单的检错方法是“奇偶校验”,即在传送字符的各位以外,再传送1位奇/偶校验位。可采用奇校验或偶校验。
奇校验:全部传送的数位(含字符的各数位和校验位)中,“1”的个数为奇数,如:
1 0110,0101
0 0110,0001
偶校验:全部传送的数位(含字符的各数位和校验位)中,“1”的个数为偶数,如:
1 0100,0101
0 0100,0001
 
奇偶校验可以检测出信息传输过程当中的部分误码(1位误码能检出,2位及2位以上误码不能检出),同时,它不能纠错。在发现错误后,只能要求重发。但因为其实现简单,仍获得了普遍使用。
有些检错方法,具备自动纠错能力。如循环冗余码(CRC)检错等。


第二章 串口通讯编程简介
1. 串口的通讯编程流程
 


2. Unix平台下对串口进行开发的方法
3. Windows平台下对串口进行开发的方法
在Windows平台下,Win32 API支持同步和异步两种I/O操做。同步操做的方式的程序设计相对比较简单,可是I/O操做函数在I/O操做结束前不能返回,这将挂起调用线程,直到I/O操做结束;异步操做方式要相对复杂一些,可是可让I/O操做在后台运行,而不会挂起调用线程,这在大数据量通讯状况下对改善调用线程的响应速度是至关有效的。同时因为Win9x和WinNT下对串行通讯的处理不一样,这就致使了在Win9x下开发的同步方式串行通讯程序在NT下会发生工做线程之间的协做阻塞,即当读线程在等待WaitCommEvent的时候,写线程不能正常工做,停在那里,整个程序处于瘫痪状态。这个问题是Windows的API函数处理串行通讯的一个BUG,因此对于适应性强的程序都是选择异步方式。下面,本文对在Windows平台下对串口进行开发的方法进行介绍:
1. 汇编程序直接读写串口
汇编语言的编译效率和执行效率都很高,使用汇编语言直接对串口进行操做能够部分弥补串行通讯速度较慢的缺陷,具体作法是:用汇编语言编写读、写串口的函数,在通讯程序中直接调用,或者在幵发工具中直接内嵌汇编程序进行对端口的读写。
例如:
asm
  mov dx,0001h
mov ax,005eh
int 14h
end;
这样能够达到直接读到端口的效果。可是在WinNT和Win2000下,系统使用了保护机制,不容许用户态的程序直接读取端口,因此在WinNT和Win2000下,这种方法不能被容许执行。Ring3的用户态的程序要进入Ring0去读写端口必须先提供一个驱动(sys)程序,而后经过DLL导出函数供用户程序调用,显然,这种方法比较不容易实现。

2. 使用API函数进行串口编程
Windows系统通讯通常都以WOSA(Windows Open Service Architecture,即Windows开放式服务体系)模型为基础,在此模型中位于上层的应用程序经过调用各类通讯API(Application Programming Interfaces,即应用程序接口)与位于下层的设备驱动程序进行数据交换。
在Windows平台下,Windows将设备看做是文件进行管理,对设备的操做也能够看做是对文件的操做。Win32 API提供了CreateFile(),WriteFile(),ReadFile(),WaitForSingleObject(),WaitForMultipleObjects(),CreateEvent(),CreateMutex(),CreateSemaphore(),CreateThread()等函数,其基本步骤以下:
(1) 利用CreateFile()函数打开串口。该函数有七个参数,其中dwCreationDistribution参数取OPEN_EXISTING,代表打开的串口对应于实际的物理串口;lpFileName参数是要打开的串口名称,如“COM1”;DwFlagsAndAttributes参数决定对串口的操做是同步操做仍是异步操做;DwDesiredAccess参数是访问方式,可取GENERIC_READ或GENERIC_WRITE;DwShareMode参数是共享模式,对串口物理设备必须取0;LpSecurityAttributes参数是安全属性,取值为NULL;DwFlagsAndAttributes是文件属性和标识,通常取值为FILE_ATTRIBUTE_NORMAL。该函数返回串口操做的句柄。
(2) 对该串口句柄对应的设备进行配置,如波特率、数据位、中止位、是否奇偶校验等。这部分首先使用GetCommState()函数获得当前的串口配置信息,将这些信息存放在一个DCB结构中,而后对该DCB结构里面的内容进行从新按要求设置,最后调用SetCommState()函数使修改的设置生效。
(3) 配置串口事件。SetCommMask()函数能够设置多个串口信息事件,其串口的信息事件能够是如下任意的组合:
EV_BREAK:在输入时Windows检测到中断;
EV_CTS   :CTS信号改变状态;
EV_DSR   :DSR信号改变状态;
EV_ERR   :发生线状态错误;
EV_RING  :检测到振铃指示;
EV_RLSD  :接收线信号探测状态发生改变;
EV_RXCHAR:接收缓冲区里收到字符;EV_RXFLAG:收到事件字符,并放入接收缓冲区;
EV_TXEMPTY:输出缓冲区空。
(4) 建立串口监视线程监视串口事件。首先使用WaitForSingleObject()、WaitForCommEvent()、WaitForMultipleObjects()等等待函数对线程进行控制,当没有数据收发时,将线程阻塞,减小其CPU的资源占用;当有数据收发时,线程自动启动,完成数据的收发。最后调用CreateThread()函数启动线程。
(5) 串口使用结束,用CloseHandle()函数关闭串口,回收资源。
因而可知,利用Win32 API函数编写串口通讯程序比较复杂,须要掌握大量的系统和通讯知识,其优势是实现的功能强大,应用面普遍,适合编写较为复杂的地层次应用程序。

3. 使用串口通信的控件进行幵发,如mscomm。程序员


第三章 使用DELPHI工具进行串口通讯编程
1. Delphi串口通讯编程的方法
Delphi没有自带串口通信的控件,在它的帮助文档里也没有说起串口通信,这就给编制通信程序的开发人员带来众多麻烦,影响了开发进度,下面就这一技术进行讨论。
用Delphi 实现串口通讯,经常使用的几种方法为:
1. 使用控件如MSCOMM和SPCOMM,TurboPower.
串口控件主要優缺点以下:
mscomm:微软的东西,ActivX控件,使用简单,在VB中带的,性能通常,因为是ActivX控件,缺點打包时须要注册好多信息。
spcomm:比较好的vcl,算是比较专业的,解剖了一下,功能比较完善。
TurboPower:公认的专业通信控件。能够到其站点下载,开放源码了。

2. 使用API函数或者在Delphi 中调用其它串口通信程序。

3. 使用API编写串口通讯程序。

2. 串口控件在Delphi中的安装
ü Delphi中MsComm控件的安装使用
用过VB的程序员都知道 VB的MSComm通讯控件具备丰富的与串口通讯密切相关的属性及事件,提供了一系列标准通讯命令的接口,能够用它建立全双工的、事件驱动的、高效实用的通讯程序。在这里就介绍一下如何把MSComm这个ActiveX控件加入到Delphi中,充分发挥出两者的优越性。

    首先在VB安装目录下找到下列三个文件:

     Mscomm.reg, Mscomm32.ocx,Mscomm32.dep ,

把这三个文件拷贝到Windows的system目录下(注意WinNT下是System32)。而后用Windows下的注册工具regsvr32注册该OCX控件,例如:

  Regsvr32 … system目录/Mscomm32.ocx .

  注册成功后用记事本打开Mscomm.reg,能够看到相似下面的内容:

[HKEY_CLASSES_ROOT/Licenses/4250E830-6AC2-11cf-8ADB-00AA00C00905]

@ = "kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun",为了能正确使用该控件,须要修改注册表的信息,在注册表的在HKEY_CLASSES_ROOT/Licenses下建一主键:

4250E830-6AC2-11cf-8ADB-00AA00C00905,主键的内容为

kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun.

至此已经完成了控件的系统注册工做,剩下的工做是在Delphi中导入这个ActiveX控件,进入Delphi环境在Component菜单下选Import ActiveX Control,这时在列表中能够看到Microsoft Comm Control 6.0选项, 选中这个选项点击Install按钮,完成安装。在ActiveX控件页上能够看到一个电话为图标的控件,这就是MSComm控件。这样就能够象在VB中同样方便得使用MSComm控件了。

ü SPCOMM控件的安装

1.选择下拉菜单Component的第二项Install Component 。

图1
 
      弹出图1所示的窗口,在Unit file name 处填写控件SPCOMM控件所在路径,其它可用默认值,点击OK按纽。

2.安装成功后,system控件面板中将出现一个红色控件COMM。如今使用COMM控件能够象Delphi自带控件同样使用。
3. 串口控件的使用
ü MSComm控件使用详解
     MSComm 控件经过串行端口传输和接收数据,为应用程序提供串行通信功能。MSComm控件在串口编程时很是方便,程序员没必要去花时间去了解较为复杂的API函数,并且在VC、VB、Delphi等语言中都可使用。 Microsoft Communications Control(如下简称MSComm)是Microsoft公司提供的简化Windows下串行通讯编程的ActiveX控件,它为应用程序提供了经过串行接口收发数据的简便方法。具体的来讲,它提供了两种处理通讯问题的方法:一是事件驱动(Event-driven)方法,一是查询法。
1.MSComm控件两种处理通信的方式

MSComm控件提供下列两种处理通信的方式:事件驱动方式和查询方式。
1.1 事件驱动方式

事件驱动通信是处理串行端口交互做用的一种很是有效的方法。在许多状况下,在事件发生时须要获得通知,例如,在串口接收缓冲区中有字符,或者 Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些状况下,能够利用 MSComm 控件的 OnComm 事件捕获并处理这些通信事件。OnComm 事件还能够检查和处理通信错误。全部通信事件和通信错误的列表,参阅 CommEvent 属性。在编程过程当中,就能够在OnComm事件处理函数中加入本身的处理代码。这种方法的优势是程序响应及时,可靠性高。每一个MSComm 控件对应着一个串行端口。若是应用程序须要访问多个串行端口,必须使用多个 MSComm 控件。

1.2 查询方式

查询方式实质上仍是事件驱动,但在有些状况下,这种方式显得更为便捷。在程序的每一个关键功能以后,能够经过检查 CommEvent 属性的值来查询事件和错误。若是应用程序较小,而且是自保持的,这种方法多是更可取的。例如,若是写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,由于惟一等待接收的字符是调制解调器的“肯定”响应。

2.MSComm 控件的经常使用属性
MSComm 控件有不少重要的属性,但首先必须熟悉几个属性。
CommPort 设置并返回通信端口号。
Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、中止位。
PortOpen 设置并返回通信端口的状态。也能够打开和关闭端口。
Input 从接收缓冲区返回和删除字符。
Output 向传输缓冲区写一个字符串。

下面分别描述:

CommPort属性 设置并返回通信端口号。
语法 object.CommPort[value ] (value 一整型值,说明端口号。)
说明 在设计时,value 能够设置成从 1 到 16 的任何数(缺省值为 1)。可是若是用 PortOpen 属性打开一个并不存在的端口时,MSComm 控件会产生错误 68(设备无效)。
注意:必须在打开端口以前设置 CommPort 属性。

RThreshold 属性:在 MSComm 控件设置 CommEvent 属性为 comEvReceive 并产生 OnComm 以前,设置并返回的要接收的字符数。
语法 object.Rthreshold [ = value ](value 整型表达式,说明在产生 OnComm 事件以前要接收的字符数。 )
说明 当接收字符后,若 Rthreshold 属性设置为 0(缺省值)则不产生 OnComm 事件。例如,设置 Rthreshold 为 1,接收缓冲区收到每个字符都会使 MSComm 控件产生 OnComm 事件。

CTSHolding 属性:肯定是否可经过查询 Clear To Send (CTS) 线的状态发送数据。Clear To Send 是调制解调器发送到相联计算机的信号,指示传输能够进行。该属性在设计时无效,在运行时为只读。
语法: object.CTSHolding(Boolean)

Mscomm 控件的 CTSHolding 属性设置值:
True Clear To Send 线为高电平。
False Clear To Send 线为低电平。

说明:若是 Clear To Send 线为低电平 (CTSHolding = False) 而且超时时,MSComm 控件设置 CommEvent 属性为 comEventCTSTO (Clear To Send Timeout) 并产生 OnComm 事件。

Clear To Send 线用于 RTS/CTS (Request To Send/Clear To Send) 硬件握手。若是须要肯定 Clear To Send 线的状态,CTSHolding 属性给出一种手工查询的方法。

详细信息 有关握手协议,请参阅 Handshaking 属性。

SThreshold 属性: MSComm 控件设置 CommEvent 属性为 comEvSend 并产生 OnComm 事件以前,设置并返回传输缓冲区中容许的最小字符数。

语法 object.SThreshold [ = value ]
value 整形表达式,表明在 OnComm 事件产生以前在传输缓冲区中的最小字符数。

说明:若设置 Sthreshold 属性为 0(缺省值),数据传输事件不会产生 OnComm 事件。若设置 Sthreshold 属性为 1,当传输缓冲区彻底空时,MSComm 控件产生 OnComm 事件。若是在传输缓冲区中的字符数小于 value,CommEvent 属性设置为 comEvSend,并产生 OnComm 事件。comEvSend 事件仅当字符数与 Sthreshold 交叉时被激活一次。例如,若是 Sthreshold 等于 5,仅当在输出队列中字符数从 5 降到 4 时,comEvSend 才发生。若是在输出队列中从没有比 Sthreshold 多的字符,comEvSend 事件将毫不会发生。

Handshake 常数

常数 值 描述
comNone 0 无握手。
comXonXoff 1 XOn/Xoff 握手。
comRTS 2 Request-to-send/clear-to-send 握手。
comRTSXOnXOff 3 Request-to-send 和 clear-to-send 握手皆可。

OnComm 常数

常数 值 描述
comEvSend 1 发送事件。
comEvReceive 2 接收事件。
comEvCTS 3 clear-to-send 线变化。
comEvDSR 4 data-set ready 线变化。
comEvCD 5 carrier detect 线变化。
comEvRing 6 振铃检测。
comEvEOF 7 文件结束。

Error 常数

常数 值 描述
comEventBreak 1001 接收到中断信号
comEventCTSTO 1002 Clear-to-send 超时
comEventDSRTO 1003 Data-set ready 超时
comEventFrame 1004 帧错误
comEventOverrun 1006 端口超速
comEventCDTO 1007 Carrier detect 超时
comEventRxOver 1008 接收缓冲区溢出
comEventRxParity 1009 Parity 错误
comEventTxFull 1010 传输缓冲区满
comEventDCB 1011 检索端口 设备控制块 (DCB) 时的意外错误

InputMode 常数
常数 值 描述
comInputModeText 0 (缺省)经过 Input 属性以文本方式取回数据。
comInputModeBinary 1 经过 Input 属性以二进制方式检取回数据。

CDHolding 属性:经过查询 Carrier Detect (CD) 线的状态肯定当前是否有传输。Carrier Detect 是从调制解调器发送到相联计算机的一个信号,指示调制解调器正在联机。该属性在设计时无效,在运行时为只读。

语法 object.CDHolding
设置值:CDHolding 属性的设置值为:
设置 描述
True Carrier Detect 线为高电平
False Carrier Detect 线为低电平
说明:注意当 Carrier Detect 线为高电平 (CDHolding = True) 且超时时,MSComm 控件设置CommEvent 属性为 comEventCDTO(Carrier Detect 超时错误),并产生 OnComm 事件。
注意 在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,由于呼叫者能够随时挂起(放弃传输)。
Carrier Detect 也被称为 Receive Line Signal Detect (RLSD)。
数据类型 Boolean

DSRHolding 属性:肯定 Data Set Ready (DSR) 线的状态。Data Set Ready 信号由调制解调器发送到相连计算机,指示做好操做准备。该属性在设计时无效,在运行时为只读。
语法:object.DSRHolding
object 所在处表示对象表达式,其值是“应用于”列表中的对象。
DSRHolding 属性返回如下值:
值 描述
True Data Set Ready 线高
False Data Set Ready 线低
说明:当 Data Set Ready 线为高电平 (DSRHolding = True) 且超时时,MSComm 控件设置 CommEvent 属性为 comEventDSRTO(数据准备超时)并产生 OnComm 事件。
当为 Data Terminal Equipment (DTE) 机器写 Data Set Ready/Data Terminal Ready 握手例程时该属性是十分有用的。
数据类型:Boolean

Settings 属性: 设置并返回波特率、奇偶校验、数据位、中止位参数。

语法: object.Settings[ = value]
说明:当端口打开时,若是 value 非法,则 MSComm 控件产生错误 380(非法属性值)。
Value 由四个设置值组成,有以下的格式:
"BBBB,P,D,S"
BBBB 为波特率,P 为奇偶校验,D 为数据位数,S 为中止位数。value 的缺省值是:
"9600,N,8,1"

InputLen 属性:设置并返回 Input 属性从接收缓冲区读取的字符数。

语法 object.InputLen [ = value]
InputLen 属性语法包括下列部分:
value 整型表达式,说明 Input 属性从接收缓冲区中读取的字符数。
说明:InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中所有的内容。

若接收缓冲区中 InputLen 字符无效,Input 属性返回一个零长度字符串 ("")。在使用 Input 前,用户能够选择检查 InBufferCount 属性来肯定缓冲区中是否已有须要数目的字符。该属性在从输出格式为定长数据的机器读取数据时很是有用。

EOFEnable 属性:肯定在输入过程当中 MSComm 控件是否寻找文件结尾 (EOF) 字符。若是找到 EOF 字符,将中止输入并激活 OnComm 事件,此时 CommEvent 属性设置为 comEvEOF,
语法:object.EOFEnable [ = value ]
EOFEnable 属性语法包括下列部分:
value 布尔表达式,肯定当找到 EOF 字符时,OnComm 事件是否被激活,如“设置值”中所描述。
value 的设置值:
True 当 EOF 字符找到时 OnComm 事件被激活。
False (缺省)当 EOF 字符找到时 OnComm 事件不被激活。
说明:当 EOFEnable 属性设置为 False,OnComm 控件将不在输入流中寻找 EOF 字符。

错误消息(MS Comm 控件)

下表列出 MSComm 控件能够捕获的错误:

值 描述
380 无效属性值 comInvalidPropertyValue
383 属性为只读 comSetNotSupported
394 属性为只读 comGetNotSupported
8000 端口打开时操做不合法 comPortOpen
8001 超时值必须大于 0
8002 无效端口号 comPortInvalid
8003 属性只在运行时有效
8004 属性在运行时为只读
8005 端口已经打开 comPortAlreadyOpen
8006 设备标识符无效或不支持该标识符
8007 不支持设备的波特率
8008 指定的字节大小无效
8009 缺省参数错误
8010 硬件不可用(被其它设备锁定)
8011 函数不能分配队列
8012 设备没有打开 comNoOpen
8013 设备已经打开
8014 不能使用 comm 通知
8015 不能设置 comm 状态 comSetCommStateFailed
8016 不能设置 comm 事件屏蔽
8018 仅当端口打开时操做才有效 comPortNotOpen
8019 设备忙
8020 读 comm 设备错误 comReadError
8021 为该端口检索设备控制块时的内部错误 comDCBError


PCOMM的主要属性,方法和事件

1.属性
CommName:填写COM1,COM2…等串口的名字,在打开串口前,必须填写好此值。
BaudRate:设定波特率9600,4800等,根据实际须要来定,在串口打开后也可更改波特率,实际波特率随之更改。
ParityCheck:奇偶校验。
ByteSize:字节长度_5,_6,_7,_8等,根据实际状况设定。
Parity:奇偶校验位
pBits:中止位
SendDataEmpty:这是一个布尔属性,为true时表示发送缓存为空,或者发送队列里没有信息;为False时表示表示发送缓存不为空,或者发送队列里有信息。

2.方法
Startcomm过程用于打开串口,当打开失败时一般会报错,错误主要有7种:
⑴串口已经打开 ;
⑵打开串口错误 ;
⑶文件句柄不是通信句柄;
⑷不可以安装通信缓存;
⑸不能产生事件 ;
⑹不能产生读进程;
⑺不能产生写进程;
        StopComm过程用于关闭串口,没有返回值。
     函数WriteCommData(pDataToWrite: PChar;dwSizeofDataToWrite:Word ): boolean 用于发送一个字符串到写线程,发送成功返回true,发送失败返回false, 执行此函数将当即获得返回值,发送操做随后执行。函数有两个参数,其中 pdatatowrite是要发送的字符串,dwsizeofdatatowrite 是发送的长度。

3. 事件

OnReceiveData : procedure (Sender: TObject;Buffer: Pointer;BufferLength: Word) of object 
  当输入缓存有数据时将触发该事件,在这里能够对从串口收到的数据进行处理。Buffer中是收到的数据,bufferlength是收到的数据长度。

OnReceiveError : procedure(Sender: TObject; EventMask : DWORD)
  当接受数据时出现错误将触发该事件。

ü SPCOMM的使用

  下面,咱们结合一个串口通信的例子来讲明SPCOMM的使用。

  为了实现PC与单片机8051之间的通信,首先要调通它们之间的握手信号,假定它们之间的通信协议是,PC到8051一帧数据6个字节,8051到PC一帧数据也为6个字节,当PC发出(F0,01,FF,FF,01,F0)后能收到这样一帧(F0,01,FF,FF,01,F0),表示数据通讯握手成功,二者之间就能够按照协议相互传输数据。在PC方要发送及接受数据须要如下步骤:

1.建立一个新的工程COMM.DPR,把窗体的NAME属性改成FCOMM,把窗体的标题改成测试通信,添加控件。

  对COMM1(黑色矩形围住的控件)进行属性设计,设波特率4800,校验位无,字节长度_8,中止位_1,串口选择COM1。Memo1中将显示发送和接受的数据。选择File/Save As将新的窗体存储为Comm.pas。

2.编写源代码

变量说明
var
FCOMM: TFCOMM;
Viewstring:string;
i:integer;
rbuf,sbuf:array[1..6] of byte;

打开串口
procedure TFCOMM.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;

关闭串口
procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;

发送数据
自定义的发送过程
procedure senddata;
var
i:integer;
commflg:boolean;
begin
viewstring:="";
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf,1) then
begin
commflg:=false;
break;
end;
sleep(2); {发送时字节间的延时}
viewstring:=viewstring+inttohex(sbuf,2)+" ";
end;
viewstring:="发送"+viewstring;
fcomm.memo1.lines.add(viewstring);
fcomm.memo1.lines.add("");
if not commflg then messagedlg("发送失败!",mterror,[mbyes],0);
end;

procedure TFCOMM.Btn_sendClick(Sender: TObject);{发送按钮的点击事件}
begin
sbuf[1]:=byte($f0); {帧头}
sbuf[2]:=byte($01); {命令号}
sbuf[3]:=byte($ff);
sbuf[4]:=byte($ff);
sbuf[5]:=byte($01);
sbuf[6]:=byte($0f); {帧尾}
senddata;{调用发送函数}
end;

接收过程
procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
var
i:integer;
begin
viewstring:="";
move(buffer^,pchar(@rbuf^),bufferlength);
for i:=1 to bufferlength do
viewstring:=viewstring+inttohex(rbuf,2)+" ";
viewstring:="接受"+viewstring;
memo1.lines.add(viewstring);
memo1.lines.add("");
end;
  若是memo1上显示发送F0 01 FF FF 0F 和 接受F0 01 FF FF F0这表示串口已正确的发送出数据并正确的接受到数据,串口通信成功。



ü Spcomm串口控件的基本例程
//串口初始化
procedure TForm1.BitBtn3Click(Sender: TObject);
    begin
        comm1.startcomm;
    end;
//关闭串口
procedure TForm1.BitBtn4Click(Sender: TObject);
    begin
        comm1.StopComm;
    end;
//发送数据
procedure TForm1.BitBtn1Click(Sender: TObject);
var str:string;
      ch1:char;
begin
     comm1.WriteCommData(ch,1);
end.
//接收数据
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;BufferLength: Word);
type   ss=array[1..500]of char ;
var    str1:^ss;
          i:integer;
         s:array[0..15] of char ;
         n:integer;
 begin
                   str1:=Buffer;
                 //s[  ]=('0','1','2','3'...'E')
                   for i:=0 to 9 do
                   s[i]:=chr(48+i);
                   for i:=10 to 15 do
                   s[i]:=chr(55+i);
                   for i:=1 to bufferlength do
                   begin
                   n:=ord(str1^[i]);
                   listbox1.Items.add(
                             inttostr(listbox1.Items.Count+1)
                             +' - '+s[n div 16]+s[n mod 16]);
                   end;
                   listbox1.Refresh;
                  if listbox1.Items.count > strtoint(form2.edit1.text)
                  then listbox1.Items.Clear;
            end;


第四章 用PComm.dll进行串口编程。

第五章 串口编程的调试及其相关工具   编程