Delphi 串口通信编程

95
Delphi Delphi 串串串串串串 串串串串串串

description

Delphi 串口通信编程. 第一章 基本概念. 通信 串行通信 硬件基础知识 模式及流量 接线和错误预防 错误排除. 1 、通信. 通信:不同的独立系统通过线路互相交换数据 数据通信:终端与计算机之间的通信或计算机与计算机之间的通信 网络:构成整个通信的线路 数据传送 通信的类型 字符传输. 数据传送. 完整的通信系统包括发送端、接收端、转换数据 的接口以及传送数据的实际信道或媒体 DTE ( Data Terminal Equipment ):发送与接收的节点 - PowerPoint PPT Presentation

Transcript of Delphi 串口通信编程

Page 1: Delphi 串口通信编程

DelphiDelphi 串口通信编程串口通信编程

Page 2: Delphi 串口通信编程

第一章 基本概念第一章 基本概念1. 通信2. 串行通信3. 硬件基础知识4. 模式及流量5. 接线和错误预防6. 错误排除

Page 3: Delphi 串口通信编程

11 、通信、通信通信:不同的独立系统通过线路互相交换数据数据通信:终端与计算机之间的通信或计算机与计算机之间的通信网络:构成整个通信的线路数据传送通信的类型字符传输

Page 4: Delphi 串口通信编程

数据传送数据传送完整的通信系统包括发送端、接收端、转换数据的接口以及传送数据的实际信道或媒体DTE ( Data Terminal Equipment ):发送与接收的节点DSE ( Data Switching Equipment ):中间节点,负责数据转送工作DCE ( Data Communication Equipment ):负责数据与电气信号转换的设备DTE 与 DCE 间的数据传输线路通常使用 RS-232DTE 与 DSE 间的媒体则包括了双绞线、同轴电缆、光纤或无线电等

Page 5: Delphi 串口通信编程

传送的方式传送的方式 并行传送( Parallel ):一次的传输量为 8 个位( 1 字节) 通过并行端口,如打印机 串行传送( Serial ):一次只传输 1 个位 通过串行端口,如 RS-232

Page 6: Delphi 串口通信编程

通信的种类通信的种类将数据转换成串行通信有两种方式 同步方式:接收设备能自动与发送计算机同步,接收字符有规则的分割开来,以块为单位,没有起始位和停止位,效率高。 异步方式:以字符为传送单位,传送的字符之间有无规律的间隔,这样可能使接收设备不能正常接收数据,因为每接收完一个字符都不能确切地知道下一个接收的字符从何时开始。(通过加开始位和停止位实现)传输效率低,成本也低。

Page 7: Delphi 串口通信编程

字符传输字符传输位和字节文本编码非文本编码帧

Page 8: Delphi 串口通信编程

位和字节位和字节二进制中的每一位 0 和 1 ,被叫做一个位每 8 个位构成一个字节一个字节中最右面的位被称为第 0 位,最左面的位被称为第 7 位。

Page 9: Delphi 串口通信编程

文本编码文本编码文本(字符字母、标点符号等)在计算机中存储时,每个不同的字符都用不同的数值来表示。这些数值的范围通常在 0-1

27 或 0-255 范围。7 位: ASCII 码,每个字节留一个备用位8 位:前 128 个遵循 ASCII 码规则,其余的 128 个用来做扩展字符、数字符号、图形字符等编码。

Page 10: Delphi 串口通信编程

非文本编码非文本编码某些可执行指令文件和图形图像文件就是以二进制形式而不是 ASCII 码形式存储的。一个数据可用二进制形式存储,可以占多个字节。在通信领域,常常把这种类型的资料叫做二进制数据。

Page 11: Delphi 串口通信编程

帧帧帧:在串行异步通信情况下,构成一个字节的那些数据单元被称为数据位,在数据位的前、后要加上起始位、停止位和奇偶校验位。一个字符所使用的位数根据协议而不同。称这些位数为字符位数据长或字长。通常不是 8 位就是 7 位。

Page 12: Delphi 串口通信编程

22 、串行通信、串行通信RS-232 串行通信RS-485 串行通信USB 接口IEEE-1394

Page 13: Delphi 串口通信编程

RS-232RS-232 串行通信串行通信RS-232 的通信端口是每台计算机上的必要配置,通常含有 COM !和 COM2 两个端口。计算机上的 RS-232 均是公头一般有两种: 9 引脚和 25 引脚

Page 14: Delphi 串口通信编程

RS-485RS-485 串行通信串行通信RS-485 的通信方式可有效地防止噪声信号的干扰。RS-485 的信号将被发送出去时会先分成正负的两条线路,当到达接收端后,再将信号相减还原来原来的信号;如果将原始的信号记为( DT ),而被分成后的信号分别记为( D+ )及( D- ),则原始的信号与离散的信号在由发送端发送出去时: ( DT ) = ( D+ ) - ( D- )如果此线路受干扰,则两条传输线上的信号会分别成为( D

+ ) +Noise 及( D- ) +Noise

( DT ) = [ ( D+ ) +Noise]- [ ( D- ) +Noise]

= ( D+ ) - ( D- )

Page 15: Delphi 串口通信编程

USBUSB (( Universal Serial BusUniversal Serial Bus )接口)接口集成一般计算机所使用的外围设备的连接方式,而且其所采用的信号传输方式也是串行通信。USB特性:低价位,热连接,单一的连接头方式,连接数多,线上供电,不占系统资源,错误检测与复原,节省能源,支持四种传输(巨量、实时、中断及控制 4 种传输模式),速度较快( 12M bps/RS-232 最快 115bps )

Page 16: Delphi 串口通信编程

IEEE-1394IEEE-1394

IEEE-1394( 也称 FireWire ,火线 ) 与 USB一样拥有即插即用的功能,也是用于解决计算机与外围设备复杂的连接问题,并且也是使用串行通信的传输方式。IEEE-1394 的传输速度是 400Mbps ,而且速度还向 1000Mbps迈进

Page 17: Delphi 串口通信编程

USBUSB 与与 IEEE-1394IEEE-1394 的比较的比较比较项目 USB IEEE-1394 应用 低速设备 高速设备带宽( Mbps ) 1.5,12 100,200,400

电缆长度 5米 4.5米电缆 4 线 6 线即插即用 支持 支持

Page 18: Delphi 串口通信编程

33 、硬件基础知识、硬件基础知识PC 机的 RS-232 接口名称尚未统一,有多个名称: RS-232 口、串口、通信口、 C

OM 口、异步口等。1 2 3 4 5

6 7 8 9

Page 19: Delphi 串口通信编程

常用的常用的 99 条条 RS-232RS-232 信号线信号线引脚 信号名称 信号方向 简称 信号功能1 载波检测 DCE-DTE DCD ( Data Carrier Detec

t ) 数据链路已连接2 接收数据 DCE-DTE RxD ( Receive ) DTE 接收串行数据3 发送数据 DTE-DCE TxD ( Transmit ) DTE 发送串行数据4 数据终端就绪 DTE-DCE DTR ( Data Terminal Read

y ) DTE准备准备就绪5 信号地 - SG ( Signal Groun

d ) 公共信号地6 数据设备就绪 DCE-DTE DSR ( Data Set Re

ady ) DCE准备就绪,可以接收7 请求发送 DTE-DCE RTS ( Request to S

end ) DTE 通知 DCE请求发送8 清除发送 DCE-DTE CTS ( Clear to Sen

d ) DCE已切换到接收模式9 振铃指示 DCE-DTE RI ( Ring Indicato

r ) 通知 DTE 有远程呼叫

Page 20: Delphi 串口通信编程

一次应答呼叫过程一次应答呼叫过程Modem 从接收到振铃信号开始,到数据传输结束Modem 和 DTE恢复到原来的空闲状态为止的过程。

Page 21: Delphi 串口通信编程

数据终端 DTE 的控制软件持续监视振铃指示 RI ,等待该 信号有效响铃后, RI 信号在 ON 和 OFF状态之间交替变化。DTE 的通信控制软件在检测到振铃指示后,开始通过计 算机振铃指示的 ON 和 OFF状态的变化次数来进行计数。 当达到程序设计的次数时,控制软件发出终端就绪信号( DTR )有效,使 Modem 进行摘机状态,开始应答电话 Modem 在等待一小段时间后,自动地发送它的应答载波 信号。同时 Modem 发出数据设备就绪信号( DSR ),通 知 DTE已经完成所有准备工作,正在等待对方的载波信 号

Page 22: Delphi 串口通信编程

在 DTE 发出数据终端就绪信号( DTR )期间, DTE 的控制软件监视数据设备就绪信号( DSR )是否有效,当 DSR为 ON状态后, DTE便知道 Modem已准备建立数据链路,于是 DTE 开始检测载波信号( DCD ),以检查数据链路是否已经建立当主叫 Modem 的载波信号出现在电话线上时,被叫 Mode

m 发出载波信号( DCD ),以检查数据链路是否已经建立 在数据链路连接期间,发送数据( TxD )和接收数据( R

xD )线上即开始了全又工通信。同时, DTE仍监视载波信号( DCD ),以确定数据链路是否连接 数据传输结束后, DTE 使数据终端就绪信号( DTR )无效, Modem撤消载波检测( DCD ),并且使设备数据就绪信号( DSR )信号无效。数据候链路释放后, Modem和 DTE返回到初始状态。

Page 23: Delphi 串口通信编程

通信参数通信参数数据的传送速度数据的传送单位

Page 24: Delphi 串口通信编程

数据的传送速度数据的传送速度 波特率:每秒所能产生的最大电压状态改变率(一秒钟可以振荡的次数) bps 通信双方必须要取得一样的通信速度。原始信号经过不一样的波特率取样后,所得的结果完全不一样,如取样速度只有原来一半时,信号被跳着取样,数据因此错误。

Page 25: Delphi 串口通信编程

数据的传送单位数据的传送单位一般串行通信端口所传送的数据是字符类型,若用来传输文件,则会使用二进制的数据类型。

Page 26: Delphi 串口通信编程

起始位及停止位起始位及停止位异步串行传输时需要当发送端要开始传送数据时,便将传输线上的电压由低电位提升至高电位,而当传送结束后,再将电压降至低电压。接收端会因起始位的触发(因电压由低电位升至高电位)而开始接收数据;并因停止位的通知(因电压维持在低电位)而确节知道数据的字符已经结束。

Page 27: Delphi 串口通信编程

校验位的检查校验位的检查用来检查所传送数据正确性的一种核对码,其中又分成奇校验( Odd )及偶校验( Even )串行通信上的字符数据格式 起始位 + 传送字符 + 校验位 + 停止位

Page 28: Delphi 串口通信编程

44 、模式及流量、模式及流量工作模式硬件握手软件握手

Page 29: Delphi 串口通信编程

工作模式工作模式当计算机在进行数据的传送与接收时,传输线上的数据流动情况可分为 3 种: 单工:传输线上的数据流动只有一个方向 半双工:数据流动是双向,但同一时间只能一个方向行进 全双工:传输线同时具有两个方向的传输能力RS-485属于半双工, RS-232属于全双工(引脚在设计时就是接收与传送是分属两个不同的引脚与线路。)

Page 30: Delphi 串口通信编程

串行数据的流动方式串行数据的流动方式当数据要由 A 设备传送至 B 设备前,数据会先被送到 A 设备的数据输出缓冲区,接着再由此缓冲区将数据由 RS-232 线路传送到B 设备;同样地,当数据通过硬件线路传送到 B 设备时,数据首先会送到接收缓冲区,而设备 B 的 CPU再到接收缓冲区将数据读取并进行处理。

Page 31: Delphi 串口通信编程

握手握手握手信号:提供一种控制数据流的方法,即接收设备可以控制发送设备的数据发送。如果接收设备速度比发送速度快,握手信号可以略去。在异步串行通信中,这称之为握手( handshaking )或流量控制( flow control )。流量控制:保证传输双方都能正确地传送和接收数据而不会漏失。握手控制可以具休分为硬件握手和软件握手。

Page 32: Delphi 串口通信编程

硬件握手硬件握手使用专门的握手电路去控制数据的传输。当接收设备准备好之后,就通过专用的握手电路传送一个正电压给发送设备,指示发送设备发送数据。如果接收设备传送一个负电压给发送设备,则指示发送设备停止发送数据。硬件握手用到 DSR 、 CTS 、 DTR 、 RTS4 条硬件线路,其中 DTR 、 RTS 指的是计算机上的 RS-232 端;而 D

SR 、 CTS 则是指被控制的设备端。

Page 33: Delphi 串口通信编程

计算机计算机 ->-> 设备设备1. 设备必须将相对于计算机上的 DSR 引脚降为低电压2. 计算机检测到 DSR 引脚为低电位后,暂停数据的传输;同时设备继续处理位于缓冲区的数据3. 等设备的接收缓冲区数据量下降到一定程度后,设备将 DSR 引脚的标准电压升高4. 计算机一检测到 DSR 引脚为高电压后,随即继续传送数据给设备

Page 34: Delphi 串口通信编程

设备设备 ->-> 计算机计算机1. 计算机将 DTR 引脚降为低电压2. 设备检测到 DTR 引脚为低电压后,暂停数据的传输;同时计算机也会继续处理位于缓冲区的数据3. 待计算机的接收缓冲区中数据量下降到一定程度后,计算机将 DTR 引脚的标准电压升高4. 设备一检测到 DTR 引脚为高电压后,随即继续传送数据给计算机

Page 35: Delphi 串口通信编程

软件握手软件握手以数据线上的数据信号来代替实际的硬件线路最常见的是 XON/XOFF 协议:若接收端欲使发送端暂停数据的传送时,它便向发送端送出 ASCII 第 19 号字符(十六进制是 13 );而欲恢复传送时,便向发送端送出 ASCII 第 17 号字符(十六进制是 1

1 ),两个字符的交互使用,便可控制发送端的传送操作了。其操作流程与硬件握手类似。

Page 36: Delphi 串口通信编程

55 、接线和错误预防、接线和错误预防接线方法错误预防

Page 37: Delphi 串口通信编程

接线方法接线方法RS-232 口特点:

– 9 引脚或 25 引脚– 公头(区别于打印机接头)1 2 3 4 5

6 7 8 95 4 3 2 1

9 8 7 6

计算机上为公头 连线上为公头

Page 38: Delphi 串口通信编程

当使用 RS-232 与 Modem 进行连接时,直接连接即可当使用 RS-232 和其他的设备进行连接时,有时就必须做必要的跳线

Page 39: Delphi 串口通信编程

跳线跳线跳线的实际意义就是一个传送的信号必须到达对方的接收引脚,如此才能形成一个完整的通路。跳线:欲将数据从一个地方传送至另一个地方,其实只要使用第 2 引脚、第 3 引脚与第 5 引脚就可以形成一个最简单的通信线路。实际制作:将 RS-232 线的一端接头拆掉,将里面的第 2 引脚和第 3 引脚对调即可。跳线的意义:甲方传送的数据必定到乙方的接收信道;而乙方的传送数据则会到达甲方的接收信道,双方的传送与接收形成一个完整的回路。

Page 40: Delphi 串口通信编程

错误预防错误预防检测数据在传送过程中发生的错误 CheckSum: 将所有要传送字符的 ASCII 码做加法运算,计算其总和后将此数目与一数字(通常是 255 )做除法运算,再取其余数,将此余数组合成传送字符串的一部分而传送出去;同样,接收方也以相同的方式对所传送过来的字符串进行运算操作,以判断数据的正确性,如果不对,则要求发送方重发。 CRC (C yclic Redundancy Check Code 循环冗余校验码) 将欲传输的数据块视为一堆连续位所构成的一个整数值,并将此数值除一个特定的除数。

Page 41: Delphi 串口通信编程

错误预防原理:将所传送的数值做相加的操作后与一个固定的除数进行除法运算,所得的余数即为校验码。传送与接收的双方只要针对其固定的检查方法分别进行运算,比较后只要双方均一致,即正确;若不一致,数据重传。

Page 42: Delphi 串口通信编程

66 、错误排除、错误排除波特率失配检验错误字长不匹配停止位错帧错

Page 43: Delphi 串口通信编程

波特率失配波特率失配如果两个设备的波特率设置不同,当接收设备试图接受数据时,程序将报告校验错和帧错。

Page 44: Delphi 串口通信编程

校验错误校验错误指数据在传输中被破坏,至少可以说明设备在奇偶校验位类型设置不同或者字长不同。

Page 45: Delphi 串口通信编程

字长不匹配字长不匹配发送的是 8 位字长,接收采用 7 位字长发送的是 7 位字长,接收采用 8 位字长

Page 46: Delphi 串口通信编程

停止位错停止位错接收端要求一个停止位,而发送端发送了两个停止位接收端要求两个停止位,而发送端发送了一个停止位

Page 47: Delphi 串口通信编程

帧错帧错一般指位数不匹配。这个类型的错误,通常是在没有接收到要求的停止位时出现。

Page 48: Delphi 串口通信编程

第2章 串行通信程序及组件建立第2章 串行通信程序及组件建立1 、串行通信的 WindowsAPI简述2 、通信测试3 、自动与事件

Page 49: Delphi 串口通信编程

11 、串行通信的、串行通信的 WindowsWindowsAPIAPI简述简述串行通信相关函数串口通信流程Delphi 的 Windows.pas 单元文件中已经将 Win32 API 均声明进去,因此在 Delphi里面使用 API 时只要在 uses 区段中加入Windows ,使其引用该单元文件即可

Page 50: Delphi 串口通信编程

串行通信相关函数串行通信相关函数 CreateFile:建立文件,在此用打开通信端口 CloseHandle:关闭由 CreateFile建立的文件,在此用于关闭通信端口 GetCommState:取得计算机串口的设置参数 SetCommState: 设置计算机串口的参数 WriteFile: 将数据写入文件,在此用来将数据由串口送出 ReadFile:由文件中读取数据,在此用来取得送到串口的数据 ClearCommError:清除串行端口的错误,并取得信息

Page 51: Delphi 串口通信编程

串行通信相关函数串行通信相关函数 PurgeComm :清除串口上的缓冲区 EscapeCommFunction :控制串口的硬件状态 SetCommMask :设置事件的掩码,用以触发事件 WaitCommEvent :等待设置事件的发生 GetCommModemStatus :取得串口上的硬件线路状态

Page 52: Delphi 串口通信编程

HANDLE CreateFile(LPCTSTR lpFileName, // 文件名指针DWORD dwDesiredAccess, // 存取(读 /写)模式DWORD dwShareMode,//共享模式

LPSECURITY_ATTRIBUTES lpSecurityAttribute, //security attribute结构指针DWORD dwCreationDistribution, // 打开文件的方式DWORD dwAttrsAndFlags, // 文件属性HANDLE hTemplateFile//带属性复制的文件句柄

);

Page 53: Delphi 串口通信编程

有关参数说明有关参数说明 lpFileName :欲打开的文件名称。以串口通信来说,就是 COM

1 、 COM2 等 dwDesiredAccess :读写模式设备。由于将会对串口进行读写操作,因此在此给定 GENERIC_READ 和 GENERIC_WRITE 常数 dwShareMode :是否共享串行端口。一般不共享,设为 0 lpSecurityAttribute :传入一个 Security Attribute结构,指明其返回的 Handle 是否可以被子程序所继承。在此设置为 nil ,表示不可继承 dwCreationDistribution :指定如何打开文件。在打开设备时,此参数设定为 OPEN_EXISTING dwAttrsAndFlags :文件属性及相关标志。此项设置为 0 hTemplateFile :此项设置为 0

Page 54: Delphi 串口通信编程

BOOL CloseHandle(HANDLE hObject);hObject :要关闭对象的句柄当函数返回 True 时,表示关闭动作完成。

Page 55: Delphi 串口通信编程

Var Fhandle:THandle; ComName:array[0..4] of char; // ComName:string;Begin ComName:=‘COM1’;// PCHAR(ComName) FHandle := CreateFile(ComName, GENERIC_READ or GENERIC_WR

ITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);if FHandle<>INVALID_HANDLE_VALUE then showmessage(‘ 串口打开成功!’ )Else showmessage(‘ 串口打开失败!’ );CloseHandle(FHandle);End;

Page 56: Delphi 串口通信编程

GetCommStateGetCommState

BOOL GetCommState( HANDLE hFile, // 通信设备的句柄 LPDCB lpDCB // 设备控制块结构的地址 );

Page 57: Delphi 串口通信编程

_DCB = packed record DCBlength: DWORD; //DCB结构的长度 BaudRate: DWORD; //当前波特率 Flags: Longint; // wReserved: Word; //保留,未使用 XonLim: Word; // 传送 XON阈值 XoffLim: Word; // 传送 XOFF阈值 ByteSize: Byte; // 每字节位数( 4-8 ) Parity: Byte; //0-4 : no,odd,even,mark,space StopBits: Byte; //0,1,2:1,1.5,2 XonChar: CHAR; // 设置 Tx 和 Rx 的 XON 字符 XoffChar: CHAR; // 设置 Tx 和 Rx 的 XOFF 字符 ErrorChar: CHAR; // 有错误时的替换字符 EofChar: CHAR; // 表示输入结束的字符 EvtChar: CHAR; // 接收事件字符 wReserved1: Word; //保留,未使用 end; TDCB = _DCB; DCB = _DCB;PDCB = ^TDCB;

Page 58: Delphi 串口通信编程

SetCommStateSetCommState

BOOL SetCommState( HANDLE hFile, // 通信设备的句柄 LPDCB lpDCB // 设备控制块结构的地址 );

Page 59: Delphi 串口通信编程

VarFDCB: TDCB;

GetCommState(FHandle, FDCB); FDCB.BaudRate := 9600; FDCB.Parity := EVENPARITY; FDCB.Stopbits := ONESTOPBIT; FDCB.Bytesize := 8; SetCommState(FCOMHandle, FDCB);

Page 60: Delphi 串口通信编程

WriteFileWriteFileBOOL WriteFile( HANDLE hFile, // 要写入文件的句柄 LPCVOID lpBuffer,// 写入文件中的数据的指针 DWORD nNumberOfBytesToWrite,// 写入的字节数 LPDWORD lpNumberOfBytesWritten, // 写入总字节数的指针 LPOVERLAPPED lpOverlapped // overlapped I/O结构的指针 );// lpOverlapped 通常用来作后台工作时同步检查之用,在串行通信中若不同时使用串行端口,则可不使用,设为

nil

Page 61: Delphi 串口通信编程

var i:byte; strlen:DWord; xx:byte; dat : array[0..99]of char;begin dat[0] := chr($fe); dat[1] := chr($1B); dat[2] := chr($44); dat[3] := chr($03); dat[4] := chr($02); xx:=0; for i:=1 to 4 do xx := xx xor ord(dat[i]); dat[5] := chr(xx); // 异或校验 strlen:=6; WriteFile(FHandle,dat,strlen,strlen,nil);end;

Page 62: Delphi 串口通信编程

ReadFileReadFile

BOOL ReadFile( HANDLE hFile, // 要读取文件的句柄 LPVOID lpBuffer, // 接收数据的缓冲区地址 DWORD NumberOfBytesToRead, //读取的字节数 LPDWORD lpNumberOfBytesRead,//读取总字节数的地址 LPOVERLAPPED lpOverlapped//OverLapped I/O结构的地址);

Page 63: Delphi 串口通信编程

Var dat : array[0..99]of char; flag:dword;stepno:integer;begin stepno:=0; repeat Readfile(FHandle,dat,1,flag,nil); if flag>0 then if dat1[0]=chr($fe) then stepno:=1; until (stepno=1)or(flag<=0); Readfile(FHandle,dat,1,flag,nil); length:=ord(dat1[0]); //取长度 readfile(FHandle,dat1,length,flag,nil);end;

Page 64: Delphi 串口通信编程

PurgeCommPurgeComm

BOOL PurgeComm( HANDLE hFile, // 通信资源的句柄 DWORD dwFlags // 执行动作 );

Page 65: Delphi 串口通信编程

dwFlags:dwFlags: 指定执行的工作指定执行的工作 PURGE_TXABORT: 终止目前所有的传输工作,立即返回,不管是否完完成传输的操作 PURGE_RXABORT: 终止目前所有的读取工作,立即返回,不管是否完成读取操作 PURGE_TXCLEAR:清除传送缓冲区中的所有数据 PURGE_RXCLEAR:清除接收缓冲区中的所有数据

Page 66: Delphi 串口通信编程

EscapeCommFunctionEscapeCommFunction

BOOL EscapeCommFunction( HANDLE hFile, // 通信设备的句柄 DWORD dwFunc // 指定执行的功能 );

Page 67: Delphi 串口通信编程

dwFuncdwFunc :指定串口必须完成的工作:指定串口必须完成的工作 CLRDTR: 将 DTR 线路降成低电压 CLRRTS: 将 RTS 线路降成低电压 SETDTR: 将 DTR 线路升成高电压 SETRTS: 将 RTS 线路升成高电压 SETXOFF:当接收到 Xoff 字符时激活传输操作 SETXON:当接收到 Xon 字符时激活传输操作 SETBREAK: 设置通信状态为中断(送出 BREAK 信号) CLRBREAK:清除 BREAK 信号,使传输动作继续

Page 68: Delphi 串口通信编程

GetCommModemStatusGetCommModemStatus

取得串口数字输入线路电压状态可用该函数BOOL GetCommModemStatus( HANDLE hFile, // 通讯设备的句柄 LPDWORD lpModemStat // 控制寄存器中数值的地址 );

Page 69: Delphi 串口通信编程

lpModemStat :指向检测到的状态的参数地址, 32 位长度MS_CTS_ON : CTS (clear-to-send) 引脚升至高电压MS_DSR_ON : DSR (data-set-ready) 引脚升至高电压MS_RING_ON : RI 引脚升至高电压MS_RLSD_ON : DCD 引脚升至高电压

Page 70: Delphi 串口通信编程

串口通信流程串口通信流程打开通信端口

打开成功?通信参数设置其他函数操作

显示错误信息

关闭串口

结束

开始

继续操作? 否是

Page 71: Delphi 串口通信编程

22 、通信测试、通信测试通信步骤回路测试

Page 72: Delphi 串口通信编程

通信步骤通信步骤1. 设置通信端口号码2. 使用 CreateFile函数打开通信端口3. 设置通信协议4. 设置传输速度等参数5. 设置其它参数6. 送出字符串或读入字符串,使用 ReadFile 及 WriteFil

e函数7. 使用完毕后以 CloseHandle函数将通信端口关闭

Page 73: Delphi 串口通信编程

回路测试回路测试硬件设置软件实现

Page 74: Delphi 串口通信编程

硬件设置硬件设置两台计算机,各使用其上的一个串口,一条 RS-232 两边都是母头的线一台计算机,但拥有两个串行通信口,一条 RS-232 两边都是母头的线一台计算机,一个串行通信口,一条 RS-

232 线,至少其中一边是母头

Page 75: Delphi 串口通信编程

33 、自动与事件、自动与事件自动化的实现轮询方式:不断地发出询问的信号给设备,要求设备返回计算机所要的信息

– 使用定时器( Timer组件),设定时间间隔,当时间间隔一到,便会执行原先放在定时器中的程序代码– 使用 While…Do 不断地执行程序代码

线程方式:将串行通信的功能封装在一个线程中,利用线程的不断执行而达到自动化的目的

Page 76: Delphi 串口通信编程

建立多线程建立多线程工作原理:操作系统将 CPU处理数据的时间切成很多的时间片( Time Slice ),操作系统再将应用程序的代码加载到 CPU 中执行,一旦这一小块的时间执行完毕后,操作系统会将正在执行的程序放一边,然后再取另外一个应用程序进 CPU 中执行,一样只执行这一小块时间片,如此周而复始,所以见到了整个系统中多任务的情况。

Page 77: Delphi 串口通信编程

线程的实现线程的实现应用程序执行后即产生主线程,而主线程可以衍生出其他线程。一个应用程序可以依需要而造出多个线程对象,每一个线程开始执行后即被排入CPU 的执行周期中,这些线程可能被建立后开始执行,直到应用程序结束;也有可能执行完工作后在应用程序结束前就结束掉,实际的情况看具体需求而定。

Page 78: Delphi 串口通信编程

TthreadTthread 类中常用的方法类中常用的方法 Create :建立线程。使用此方法可建立线程,有 1 个参数,若设成 True ,表示建立后不立即执行;若设成

False ,则表示一建立后马上执行。 constructor Create(CreateSuspended: Boolean); Free :释放线程,线程程序代码将从内存中被删除 procedure Free; Resume :执行程序代码。若线程暂停时,使用此指令再次激活 procedure Resume; Suspend :暂停线程。将执行中的线程暂停 procedure Suspend;

Page 79: Delphi 串口通信编程

var SecondProcess: TMyThread; { TMyThread is a custom desc

endant of TThread }begin SecondProcess := TMyThread.Create(True); { create suspen

ded -secondprocess does not run yet } SecondProcess.Priority := tpLower; { set the priority to lowe

r than normal } SecondProcess.Resume; { now run the thread }end;

Page 80: Delphi 串口通信编程

第第 44 章 串行通信中的字符与字节章 串行通信中的字符与字节1 、字符与字节2 、字节数据的传送与接收

Page 81: Delphi 串口通信编程

11 、字符与字节、字符与字节字符和字节的差别Delphi 中的字符串种类及处理函数中英文字符串长度计算

Page 82: Delphi 串口通信编程

字符和字节的差别字符和字节的差别Windows支持的字符集有单字符集、双字节字符集及 UniCode 字符集,在西方国家使用 Windows 系统基本使用单字符集,每一个字符都使用一个字节来表示;而亚洲国家由于字符无法单用一个字节表示,因此使用双字节字符集,其中每个字符使用双字节字符集。

Page 83: Delphi 串口通信编程

UniCodeUniCode

UniCode涵盖了世界上所有国家的字符码,每个字符用一个唯一的内码来表示,其特点是所有的字符以两个字节表示,不仅中文使用两个字节,英文也使用两个字节

Page 84: Delphi 串口通信编程

串口通信过程中,如果传送的是一个英文字节组成,只要一个字节就可以将信息传送出去;如果传送的是双字节的字符(如中文),完整的字符传送就必须是两个字节。

Page 85: Delphi 串口通信编程

DelphiDelphi 中的字符串种类及处理函中的字符串种类及处理函数数Chr(x):返回 X参数的字符Ord(x):返回 x参数所列的序数,一般用来解读字符在 ASCII 码中的序数Pos(substr,str):返回 str 中, substr 出现的位置,若找不到则返回 0StrPos(str1,str2):返回 str2 在 str1 出现的第一位置的指针,无则返回 nilCopy(str,index,count):返回 str参数中,索引 index 开始的 count 数目的字串Delete(str,index,count):删除 str 字串中,由 index 所指定的开始位置的 cou

nt 数目的字串Length(str):返回字串 str 的长度SetLength(str,newlen): 设置 str 的长度Value(str,value,code): 将 str 转成数值 value , code 表示发生错误的位置Str(value,str):Trim(str),TrimRight(str),TrimLeft(str): 去空格StringReplace(str,oldpattern,newpattern):替换Insert(s1,s2,index):s1插入 s2 的第 index 位置

Page 86: Delphi 串口通信编程

中英文字符串长度计算中英文字符串长度计算Type Maximum

lengthMemory required

Used for

ShortString 255 characters 2 to 256 bytes backward compatibility

AnsiString ~2^31 characters 4 bytes to 2GB 8-bit (ANSI) characters

WideString ~2^30 characters 4 bytes to 2GB Unicode characters; multiuser servers and multi-language applications

Page 87: Delphi 串口通信编程

Var InstrW:WideString; InstrA:ANSIString; Instr:string;Begin Instr:=edit1.text; InstrW:=edit1.text; InstrA:=edit1.text; edit2.text:=inttostr(length(Instr)); edit3.text:=inttostr(length(InstrW)); edit4.text:=inttostr(length(InstrA));End;

Page 88: Delphi 串口通信编程

现象现象纯英文字符串使用三种字符串的计算结果相同,显示出一样的字符串长度纯中文字符串时, String 和 ANSIString 所呈现的结果一样,但WideString 的字符串长度只有它们的一半 中英文混合时, String 及 ANSIString 所呈现的结果还是一样,中文占两个字符和英文占一个字符;但WideString 类型中英文和中文都只占一个字符,

Page 89: Delphi 串口通信编程

结论结论 Length函数在不同的类型下所作的计算是不一样的 Delphi 的确是以 String 作为默认的长字符串类型 字符串的长度计算可以用 WideString 类型来进行,在这种情况下,一个中英文字符均被计算为一个字符 实际所占的字节大小需要使用 String 的类型来计算

Page 90: Delphi 串口通信编程

字符编码字符编码一般的英文字符,可以使用 Ord取得其在

ASCII 表中的代表号码;反过来说,如果想以一个号码而得知其所代表的 ASCII 字符是什么,则可以使用 chr函数来实现。

Page 91: Delphi 串口通信编程

Var instr:string;instrW:Widestring; i,len:integer; temp:string;Begin instr:=edit1.text; instrW:=edit1.text; len:=length(instr); temp:=‘’; for i:=1 to len do temp:=temp+inttostr(ord(instr[i])); memo1.text:=temp; len:=length(instrW); temp:=‘’; for I:=1 to len do temp:=temp+inttostr(ord(instrW[i])); memo2.text:=temp;End;

Page 92: Delphi 串口通信编程

22 、字节数据的传送与接收、字节数据的传送与接收字节类型、声明与传送 / 接收动态数组

Page 93: Delphi 串口通信编程

数组名: Array[startIndex..EndIndex] of 类型 ByteSend:Array[0..9] of Byte;

ByteSend[0]:=123;ByteSend[1]:=46;

Page 94: Delphi 串口通信编程

动态数组动态数组动态数组:声明时不指定数组的大小,而在需要使用数组之前再指定该数组的大小Delphi 中对于动态数组的声明方式如下:ByteReceive:array of Byte;….// 其他代码SetLength(ByteReceive,count)

Page 95: Delphi 串口通信编程

var ByteSend:array of byte; ByteReceive:array of byte; count,i:dword; FHandle: THandle;begin FHandle := CreateFile(pchar('COM1'),GENERIC_READ or GENERIC_WRITE,

0, nil, PEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0); SetLength(ByteSend,mSend.Lines.Count); for i:=0 to mSend.Lines.Count -1 do ByteSend[i]:=StrtoInt(mSend.Lines[i]); count:=0; WriteFile(FHandle,bytesend,mSend.Lines.Count,count,nil); showmessage(inttostr(count)); closehandle(FHandle);end;