说明:
TYbCommDevice: 串口控件
头文件:
Vcl.YbCommDevice.h
Fmx.YbCommDevice.h
相关控件:
TVictorComm, TCommQueue, EVictorCommError
继承关系:
TObject
└TPersistent
└TComponent
└TYbCustomCommDevice
└TYbCommDevice
相关链接和演示程序
文本收发演示程序、二进制数据收发演示程序、数据包和数据包演示程序
属性:
属性 |
类型 |
描述 |
Active |
bool |
打开/关闭串口、判断串口是否已经打开
在打开串口时用 try ... catch 可得到串口错误信息, 关于错误信息的详细描述:EVictorCommError。
try
{
YbCommDevice1->Active = true; //打开串口
}
catch(Exception &e)
{
ShowMessage(e.Message); //错误处理
} |
PortNo |
int |
串口号, 整数, 1 对应 COM1, 2 对应 COM2, 3 对应 COM3 ... n 对应 COMn
可通过这个属性改变操作的串口, 也可通过这个属性判断正在操作哪个串口。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
例如:
YbCommDevice1->PortNo = 2; // 使用
COM2 |
PortName |
String |
串口名称,字符串,例如 COM1, COM2 ……
可通过这个属性改变操作的串口, 也可通过这个属性判断正在操作哪个串口。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
例如:
YbCommDevice1->PortName = _T("COM10"); // 使用
COM10 |
PortParams |
String |
串口的参数,字符串类型,格式为:"名称,波特率,奇偶校验,数据位数,停止位"
可以通过这个属性改变串口的参数,也可以通过这个属性获得正在操作的串口的参数
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
例如:
YbCommDevice1->PortParams = _T("COM5,56000,N,8,1");
奇偶校验可用的参数为:
N 无校验 (No Parity)
E 偶校验 (Even Parity)
O 奇校验 (Odd Parity)
M 校验位=1 (Mark Parity)
S 校验位=0 (Space Parity)
PortParams 属性设为空字符串,会自动变成默认值 "COM2,9600,N,8,1"
PortParams 属性设为不完整的内容,缺省部分会使用默认值填充,例如:
"COM8" 相当于 "COM8,9600,N,8,1"
"COM8,38400" 相当于 "COM8,38400,N,8,1" |
Baud |
TBaudRate |
波特率, TBaudRate 类型, 可通过这个属性修改或得到当前读写的波特率。
enum TBaudRate {
br110,br300,br600,br1200,br2400,br4800,br9600,br14400,br19200,
br38400,br56000,br57600,br115200,br128000,br256000,brCustom };
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
如果通过 BaudRate 属性设定了非标准波特率,Baud 属性值会自动变成 brCustom
例如:
YbCommDevice1->Baud = TYbCommDevice::br57600;
//设置波特率为 57600bps |
BaudRate |
DWORD |
波特率,无符号整数类型,可以通过这个属性修改或者得到当前读写串口的波特率,
支持设定非标准波特率值,如果硬件支持。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
例如:
YbCommDevice1->BaudRate = 57600; |
Parity |
TParity |
奇偶校验, TParity 类型,可以通过此属性设置或得到当前串口数据的奇偶校验。
enum TParity
{
ptNoParity , // 无奇偶校验
(No parity)
ptOddParity
, // 奇校验 (Odd)
ptEvenParity , // 偶校验
(Even)
ptMarkParity , // Mark
校验,校验码始终等于 1
ptSpaceParity, // Space 校验,校验码始终等于 0
};
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
在一般的通讯中, 这个属性的值都设置成 ptNoParity (无奇偶校验), 这个属性的默认值为 ptNoParity.
例如:
YbCommDevice1->Parity = TYbCommDevice::ptNoParity; |
ByteSize |
int |
数据位数,整数类型,可通过此属性设置或得到当前串口的数据位数。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
支持的值: 4 到 8 之间的整数。
在一般的通讯中, 这个属性的值都设置成 8, 即 8 位的数据。这个属性的默认值为 8.
例如:
YbCommDevice1->ByteSize =
8; // 采用8位数据 |
StopBits |
TStopBits |
停止位,TStopBits 类型,可通过此属性设置或得到当前串口的停止位数。
enum TStopBits
{
sbOneStopBit
, // 1 个停止位
sbOne_5_StopBits, // 1.5 个停止位
sbTwoStopBit
, // 2 个停止位
};
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
在一般的通讯中, 这个属性值都设置成 sbOneStopBit, 即 1 个停止位。这个属性的默认值为 sbOneStopBit.
例如:
YbCommDevice1->StopBits =
TYbCommDevice::sbOneStopBit; //设置成 1 个停止位 |
FlowControl |
TFlowControl |
数据流控制,TFlowControl 类型 (Modem 与电脑之间的通讯握手协议)
enum TFlowControl
{
fcNone , // 不启动 Modem 通讯协议
fcRtsCts , // 采用硬件 RTS/CTS
协议
fcXonXoff , // 采用软件 XON/XOFF
协议
fcTranXonXoff, // 采用透明的
XON/XOFF 协议
fcRtsCtsXonXoff, // 同时采用
RTS/CTS 和 XON/XOFF 协议
};
如果没有 Modem, 一般设置为 fcNone (不启动 Modem 通讯协议)
如果使用 Modem, 必需设置一个通讯协议, 一般采用 RTS/CTS 协议, 也可以用 XON/XOFF 协议。
改变这个值, 需要调用 InitModem 方法之后才可生效, 请参考方法 InitModem 的说明。
例如:
YbCommDevice1->FlowControl = TYbCommDevice::fcNone;
//不启动通讯协议 |
AutoAnswer |
int |
Modem 自动应答,整数类型,可设置或得到当前自动应答的状态。
定义:
__property int AutoAnswer =
{ read = fGetAutAns, write = fSetAutAns };
这个属性的值取值范围: 0 到 255 之间的整数。
0 表示不自动应答;
1 到 255 之间的数表示电话响铃几次之后应答; 1 是响铃立即应答,
2 是响铃 2 次之后应答……
改变这个值, 需要调用 InitModem 方法之后才可生效, 请参考方法 InitModem 的说明。
例如:
YbCommDevice1->AutoAnswer
= 3; //电话响铃 3 声之后自动应答。 |
ModemStatus |
TModemStatus |
调制解调器 (Modem) 状态 (只读属性),TModemStatus 类型
enum TModemStatusItem
{
msCtsOn , // 清除发送 CTS (Clear
To Send) 位有效;
msDsrOn
, // 数据设备就绪 DSR (Data Set Ready) 位有效;
msRingOn,
// 振铃指示 (Ring Indicator) 位有效;
msRlsdOn,
// 数据载波检测 DCD (Data Carrier Detect) 或 RLSD (Receive Line Signal
Detect) 位有效;
};
typedef
Set<TModemStatusItem,msCtsOn,msRlsdOn>TModemStatus;
例如:
if(YbCommDevice1->ModemStatus.Contains(TYbCommDevice::msRlsdOn))
Label1->Caption
= "Modem 拨号成功, 正在联机通讯状态";
else
Label1->Caption
= "Modem 在待命状态, 可以输入 AT 指令"; |
DTR |
bool |
串口 DTR 引脚状态,可读写 |
RTS |
bool |
串口 RTS 引脚状态,可读写 |
CTS |
bool |
串口 CTS 引脚状态,只读 |
DSR |
bool |
串口 DSR 引脚状态,只读 |
RING |
bool |
串口 RING 引脚状态,只读 |
RLSD |
bool |
串口 RLSD/DCD 引脚状态,只读,和 DCD 属性相同 |
DCD |
bool |
串口 RLSD/DCD 引脚状态,只读,和 RLSD 属性相同 |
DisableWrite |
bool |
不允许写串口 (让 Write 方法无效),bool 类型
如果 DisableWrite 属性为 true, 可禁止写串口, 但是 Command 方法仍然有效.
典型应用: 如果 Modem 正在数据通讯状态, 要想发送 "+++" 命令时, 必须在命令前、后各延时1秒钟,
此期间不允许写入串口任何其他数据。
例如:
YbCommDevice1->DisableWrite
= true; //不允许写串口数据
YbCommDevice1->PurgeWrite();
//清空发送缓存, 扔掉缓存中所有正在写入的数据
Sleep(1000);
//延时一秒钟
YbCommDevice1->Command("+++");
//写入命令"+++", 这是AT指令当中惟一不需要回车的命令, 也不允许有回车
Sleep(1000);
//延时一秒钟
YbCommDevice1->Command("ATH0\r");
//写入挂机命令"ATH0", AT 命令需要用回车结束
YbCommDevice1->DisableWrite
= false; //允许写串口 |
SyncEvents |
bool |
事件 OnCommNotify 和 OnPackage 是否同步在主线程里面执行,默认值是 true
如果这个属性设为 true,事件是同步在主线程里面执行的;
如果这个属性设为 false,事件是在串口收发数据线程里面执行的。 |
DataOnly |
bool |
是否只处理串口的 TxD 和 RxD 信号,忽略其他引脚的数据,默认值是 false
如果这个属性设为 true,只处理串口的 TxD 和 RxD 信号,即只收发数据,处理其他信号;
如果这个属性设为 false,会处理串口所有的引脚的数据。 |
InBufSize |
long |
串口读数据缓存的容量, 单位: 字节, 可以读出或修改这个值。
这个属性的默认值为 8192, 即 8kb 缓存。 |
OutBufSize |
long |
串口写数据缓存的容量, 单位: 字节, 可以读出或修改这个值。
这个属性的默认值为 8192, 即 8kb 缓存。 |
HwInSize |
long |
在 Windows 串口驱动里面的读数据缓存容量, 单位: 字节, 可以读出或修改这个值。
这个属性的默认值为 1200 (字节)。 |
HwOutSize |
long |
在 Windows 串口驱动里面的写数据缓存容量, 单位: 字节, 可以读出或修改这个值。
这个属性的默认值为 1200 (字节)。 |
QueueSize |
long |
如果启动了数据包协议, 这个属性表示缓存中可容纳的数据包个数, 默认值为 16
相关属性:
UsePackage, PackageType, PackageSize, FrameSettings |
PackageType |
TCommPackageType |
数据包的类型,UsePackage 属性为 true 的时候使用。
cptFrameTimeout 时间间隔的数据包,是数据包类型的默认值
cptFrameHeadTail 首、尾、控制符的数据包
相关属性
UsePackage, QueueSize, PackageSize, FrameSettings |
PackageSize |
long |
如果启动了数据包协议, 这个属性表示数据包的最大字节数, 默认为 4096 个字节。
相关属性:
QueueSize, UsePackage, FrameSettings
YbCommDevice1->PackageSize = 8192; // 最大的数据包允许 8192 个字节
YbCommDevice1->UsePackage = true; // 启动数据包 (可以随时启动和停止, 与 Active
属性无关) |
UsePackage |
bool |
使用数据包协议。如果启动数据包协议:
可以用 ReadPackage 和 WritePackage 方法发送和接收数据包;
收到数据包产生 OnPackage 事件,可以在这个事件里面接收数据包。
相关属性:
QueueSize, PackageSize, FrameSettings |
FrameSettings |
TYbCommFrameSettings |
规定数据包首、尾、和控制符。只有当 PackageType 为 cptFrameHeadTail 时使用这些属性。
例如:
YbCommDevice1->FrameSettings->FrameHead
= 0xdb; //数据包头
YbCommDevice1->FrameSettings->FrameTail
= 0xde; //数据包尾
YbCommDevice1->FrameSettings->FrameCtrl
= 0xdc; //数据控制符 |
InQueue |
TCommQueue |
串口读缓存, 指向一个 FIFO 队列缓存, 由控件内部使用, 不要访问除 Count 之外的其他属性。
可以通过 YbCommDevice1->InQueue->Count 来判断串口缓存收到数据的字节数, 这个属性是随着接收数据动态变化的。 |
OutQueue |
TCommQueue |
串口写缓存, 指向一个 FIFO 队列缓存, 由控件内部使用, 不要访问除 Count 之外的其他属性。
可以通过 YbCommDevice1->OutQueue->Count 来判断缓存中还剩多少字节未发送, 这个属性是随着发送数据动态变化的。 |
Handle |
HANDLE |
串口句柄。通过串口句柄, 可用 API 函数直接对串口操作。 |
CommPort |
TVictorComm |
串口控件内部使用的属性, 用于处理串口数据。 |
CommPackage |
TCommPackage |
串口控件内部使用的属性, 用于处理数据包。 |
方法:
方法 |
描述 |
Read |
读串口 (接收数据)
原型:
virtual long __fastcall Read(void
far *s, long n);
参数:
s: 读出数据存放的地址;
n:
读出数据字节数。
返回值:
实际读出的字节数。返回值有可能:
①
0: 没有读出数据;
② 实际读出的字节数, 这个数小于或等于参数
n 的值, 并且也小于或等于属性 InBufSize 的值。
例如:
char Buffer[8192]; //定义一个 8kb 缓存
int n = YbCommDevice1->Read(Buffer,8192); //收到 n 个字节, 接收的数据保存到
Buffer 里 |
Write |
写串口 (发送数据)
原型:
virtual long __fastcall Write(const
void far *s, long n);
参数:
s: 发送数据的地址
n:
发送的字节数
返回值:
实际发送的字节数。返回值有可能小于参数 n 的值, 原因是串口忙,
或者发送缓存不足以保存所有数据。
//--- 例(1), 发送简单数据类型: ---
char a[10];
AnsiString s;
short n;
YbCommDevice1->Write(a,10); //发送字符数组
YbCommDevice1->Write(s.c_str(),s.Length()); //发送字符串
YbCommDevice1->Write(&n,2); //发送一个 16 位的短整数, 先发送低位字节,
后发送高位字节
//--- 例(2), 发送结构: ---
#pragma pack(push,1) //用字节型对齐方式,下面的 TMyStruct 结构是 7 个字节, 否则
TMyStruct 结构是8个字节
typedef struct
{
char a; //字节型变量, 1 个字节
short
b; //短整数变量, 2 个字节
long c; //长整数变量, 4 个字节
} TMyStruct;
#pragma pack(pop) //恢复原来的对齐方式
TMyStruct MyStruct; //定义结构变量
YbCommDevice1->Write(&MyStruct,sizeof(TMyStruct)); |
Command |
发送命令/字符串, 这个方法不受属性 DisableWrite 的控制。
原型 :
virtual long __fastcall Command(const
char far *s);
参数:
s: 以 '\0' 结束的字符串
返回值:
实际发送的字节数。返回值有可能小于参数 n 的值, 原因是串口忙,
或者发送缓存不足以保存所有数据。
例如:
YbCommDevice1->Command("ATDT12345678\r");
//通过 Modem 进行拨号, 采用双音频方式, 电话号码为 12345678
注意: 如果使用 AT 指令, 除了"+++"之外的指令都要用回车结束。
Command 方法只是简单的通过串口发送字符串, 并不是特殊的功能, 本例子程序用下面的方法同样可以实现:
YbCommDevice1->Write("ATDT12345678\r",13);
//发送 13 个字节的数据, 因为数据的内容为 AT 指令, 如果 Modem 为命令状态, 就会进行拨号, 号码为
12345678
通过属性 ModemStatus 可判断 Modem 的状态, 如果 MS_RLSD_ON 位有效, 为已经拨号成功,
收发数据的状态, 否则为命令状态, 所有写入串口的数据都认为是命令。 |
ReadPackage |
读数据包 (接收数据包)
原型 :
virtual bool __fastcall ReadPackage(void
*lpPkg);
相关属性:
PackageType, PackageSize, QueueSize, UsePackage,
FrameSettings |
WritePackage |
写数据包 (发送数据包)
原型 :
virtual bool __fastcall WritePackage(void
*lpPkg);
相关属性:
PackageType, PackageSize, QueueSize, UsePackage,
FrameSettings |
PurgeRead |
清空读数据缓存 (扔掉读出的数据)
原型 :
virtual void __fastcall PurgeRead(bool
bAbort=false);
参数:
bAbort: 强制终止正在执行的接收动作, 默认值为
false |
PurgeWrite |
清空写数据缓存 (扔掉正在写的数据, 终止当前的写动作)
定义:
virtual void __fastcall PurgeWrite(bool
bAbort=false);
参数:
bAbort: 强制终止正在执行的发送动作, 默认值为 false |
SettingsDialog |
显示串口设置对话框, 要求用户选择配置
virtual bool __fastcall SettingsDialog(TComponent*
AOwner, bool FActive=false);
参数:
AOwner: 显示对话框的拥有者窗体, 一般用 this 即可;
FActive: 是否确认选择的配置必须有效
如果为 true, 选择的配置必须有效, 并且按确定按钮时,
会打开串口;
如果为 false, 选择的配置不加验证,
按确定按钮时不打开串口;
返回值:
true: 设置成功, 并且接受了设置;
false: 设置失败, 或者取消了设置.
例: 打开串口, 如果打开失败, 就让用户选择配置, 如果选择配置成功, 打开串口, 否则退出程序。
try
{
YbCommDevice1->Active = true;
}
catch(Exception &e)
{
ShowMessage("YbCommDevice1: "+e.Message);
if(!YbCommDevice1->SettingsDialog(this,true))
Application->Terminate();
} |
ResetModem |
复位 Modem, Modem 恢复上电状态
原型 :
virtual void __fastcall ResetModem(void);
通过 Command("ATZ\r") 实现的。 |
InitModem |
初始化 Modem, 使用 Modem 之前必须进行初始化
原型 :
virtual void __fastcall InitModem(void);
通过 AT 指令实现的, 初始化成功会从串口收到包含 "OK" 和回车换行的字符串。
通过 InitModem 设置电脑与 Modem 之间的通讯协议, 通常在打开串口时执行, 或者在 AfterOpen
事件里执行。
建议拨号方在拨号之前先执行 InitModem 来判断 Modem 是否联机, 应答方在打开串口时必须进行 InitModem。 |
EscapeCommFunction |
控制串口状态
原型 :
virtual BOOL __fastcall EscapeCommFunction(DWORD
dwFunc);
相关属性:
ModemStatus
参数:
dwFunc: 下列内容之一: CLRDTR,CLRRTS,SETDTR,SETRTS,SETXOFF,SETXON,SETBREAK,CLRBREAK
具体内容请参考 API 函数 EscapeCommFunction 的解释 |
TYbCommDevice |
构造函数, 由系统自动调用, 或者通过 new 来调用。
原型 :
__fastcall TYbCommDevice(TComponent*
Owner);
参数:
Owner: 拥有者, 通常用 this. |
~TYbCommDevice |
析构函数, 由系统调用, 或者通过 delete 来调用。
原型 :
virtual __fastcall ~TYbCommDevice();
|
EvCommNotify |
protected 成员, 串口事件 OnCommNotify 的默认处理
原型 :
virtual void __fastcall EvCommNotify(TObject
*Sender, int NotifyType);
参数:
Sender: 产生事件的控件
NotifyType:
是以下位或位的组合, 表示产生了相应的事件:
EV_RXCHAR
收到数据
EV_TXEMPTY 数据已经发送完毕
EV_CTS 清除发送信号有变化 (CTS引脚电平有变化)
EV_DSR 数据设备就绪状态有变化 (DSR引脚电平有变化)
EV_RLSD 数据载波检测状态有变化 (DCD引脚电平有变化)
EV_RING 有振铃信号
EV_RXFLAG
收到可产生事件的字符, 可参考 API 函数 SetCommState
EV_RX80FULL
接收缓存已经达到 80% 的容量, 如果是通过 Modem 等设备进行通讯, 要及时通知对方暂停发送
EV_ERR
线路状态有错误, 包括 CE_FRAME, CE_OVERRUN 和 CE_RXPARITY.
以上事件均由默认的处理过程进行处理, 用户通常只需要处理 EV_RXCHAR 和 EV_TXEMPTY 事件。 |
EvPackageNotify |
protected 成员, 串口事件 OnPackage 的默认处理
原型 :
virtual void __fastcall EvPackageNotify(TObject
*Sender, int NotifyType);
参数:
Sender: 产生事件的控件
NotifyType:
是以下位或位的组合, 表示产生了相应的事件:
EV_RXCHAR
收到数据包
EV_TXEMPTY 数据包已经发送完毕 |
EvAfterOpen |
protected 成员, 当打开串口之后产生的事件的默认处理过程。
原型 :
virtual void __fastcall EvAfterOpen(TObject
*Sender);
参数:
Sender: 产生事件的控件。 |
EvBeforeClose |
protected 成员, 关闭串口之前产生的事件的默认处理过程。
原型 :
virtual void __fastcall EvBeforeClose(TObject
*Sender);
参数:
Sender: 产生事件的控件。 |
事件:
事件 |
描述 |
OnCommNotify |
串口事件, 串口在数据传输过程中产生的事件。
定义:
__property void __fastcall (__closure *OnCommNotify) (TObject *Sender, int NotifyType);
参数:
Sender: 产生事件的控件
NotifyType:
是以下位或位的组合, 表示产生了相应的事件:
EV_RXCHAR
收到数据
EV_TXEMPTY 数据已经发送完毕
EV_CTS 清除发送信号有变化 (CTS引脚电平有变化)
EV_DSR 数据设备就绪状态有变化 (DSR引脚电平有变化)
EV_RLSD 数据载波检测状态有变化 (DCD引脚电平有变化)
EV_RING 有振铃信号
EV_RXFLAG
收到可产生事件的字符, 可参考 API 函数 SetCommState
EV_RX80FULL
接收缓存已经达到 80% 的容量, 如果是通过 Modem 等设备进行通讯, 要及时通知对方暂停发送
EV_ERR
线路状态有错误, 包括 CE_FRAME, CE_OVERRUN 和 CE_RXPARITY.
以上事件均由默认的处理过程进行处理, 用户通常只需要处理 EV_RXCHAR 和 EV_TXEMPTY 事件。
默认情况,这个事件同步在主线程运行,如果当 SyncEvents 属性为 false 的时候,这个事件会在串口收发线程里面执行。 |
OnPackage |
串口事件, 当启动数据包之后,即 UsePackage 属性为 true, 收到数据包或者数据包发送完毕产生的事件
定义:
__property void __fastcall (__closure *OnPackage) (TObject *Sender, int NotifyType)
参数:
Sender: 产生事件的控件
NotifyType:
是以下位或位的组合, 表示产生了相应的事件:
EV_RXCHAR
收到数据
EV_TXEMPTY 数据已经发送完毕
默认情况,这个事件同步在主线程运行,如果当 SyncEvents 属性为 false 的时候,这个事件会在串口收发线程里面执行。 |
AfterOpen |
在串口打开之后产生的事件, 在这个事件中可以作一些特殊处理, 比如初始化 Modem 等。
__property
void __fastcall (__closure *AfterOpen) (TObject *Sender);
参数:
Sender: 产生事件的控件 |
BeforeClose |
在关闭串口之前产生的事件, 在这个事件中可以作一些在串口关闭之前必须执行的特殊的处理。
__property
void __fastcall (__closure *BeforeClose) (TObject *Sender);
参数:
Sender: 产生事件的控件 |
|