主页C++ Builder 资料C++ Builder 串口控件Victor 串口控件使用说明TVictorComm
C++ Builder 串口控件
Victor 串口控件使用说明
 • TYbCommDevice
 • TVictorComm
 • TCommQueue
 • EVictorCommError
 • TComm32
 • EComm32Error
 • TVictorSerialPortInfo
 • TVictorSerialPortList
 • TCommSerialPortInfo
 • TVictorFSM
 • TVictorFsmStateT
Victor 串口控件示例程序
C++ Builder 编程技巧
C++ Builder 操作指南
C++ Builder 参考手册
网友留言/技术支持
TVictorComm - Victor 串口控件使用说明

说明:

TVictorComm 是多线程的串口数据收发类,TYbCommDevice 控件内部封装的就是这个类。

头文件:

Vcl.VictorComm.h
Fmx.VictorComm.h

相关控件:

TYbCommDevice, TCommQueue, EVictorCommError

继承关系:

TObject
 └TVictorComm

属性:

属性 类型 描述
Active bool 打开/关闭串口、判断串口是否已经打开
在打开串口时用 try ... catch 可得到串口错误信息, 关于错误信息的详细描述:EVictorCommError
PortNo int 串口号, 整数, 1 对应 COM1, 2 对应 COM2, 3 对应 COM3 ... n 对应 COMn
可通过这个属性改变操作的串口, 也可通过这个属性判断正在操作哪个串口。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
如果串口的名称不符合 COMn 格式,PortNo 属性为 0
PortName String 串口名称,字符串,例如 COM1, COM2 ……,
支持不符合 COMn 格式名称的串口,PortNo 属性会自动变为 0
可通过这个属性改变操作的串口, 也可通过这个属性判断正在操作哪个串口。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
Baud DWORD 波特率,无符号整数类型,可以通过这个属性修改或者得到当前读写串口的波特率,
支持设定非标准波特率值,如果硬件支持。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
Parity BYTE 奇偶校验, BYTE 类型,可以通过此属性设置或得到当前串口数据的奇偶校验。
 • NOPARITY    : 无校验
 • ODDPARITY   : 奇校验
 • EVENPARITY  : 偶校验
 • MARKPARITY  : 校验码始终等于 1
 • SPACEPARITY : 校验码始终等于 0
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
这个属性的默认值为 NOPARITY 无校验
ByteSize BYTE 数据位数,BYTE 类型,可通过此属性设置或得到当前串口的数据位数。
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
支持的值: 4 到 8 之间的整数。
这个属性的默认值为 8.
StopBits BYTE 停止位,BYTE 类型,可通过此属性设置或得到当前串口的停止位数。
 • ONESTOPBIT   : 1 个停止位
 • ONE5STOPBITS : 1.5 个停止位
 • TWOSTOPBITS  : 2 个停止位
改变这个属性的值, Active 属性会自动变为 false, 需要重新打开串口。
这个属性的默认值为 ONESTOPBIT (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 DWORD 调制解调器 (Modem) 状态 (只读属性),DWORD 类型,包含以下位的组合:
MS_CTS_ON | MS_DSR_ON | MS_RING_ON | MS_RLSD_ON
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; //允许写串口
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 (字节)。
InQueue TCommQueue 串口读缓存, 指向一个 FIFO 队列缓存, 由控件内部使用, 不要访问除 Count 之外的其他属性。
可以通过 YbCommDevice1->InQueue->Count 来判断串口缓存收到数据的字节数, 这个属性是随着接收数据动态变化的。
OutQueue TCommQueue 串口写缓存, 指向一个 FIFO 队列缓存, 由控件内部使用, 不要访问除 Count 之外的其他属性。
可以通过 YbCommDevice1->OutQueue->Count 来判断缓存中还剩多少字节未发送, 这个属性是随着发送数据动态变化的。
Handle HANDLE 串口句柄。通过串口句柄, 可用 API 函数直接对串口操作。

方法:

方法 描述
Read 读串口 (接收数据)
定义:
    virtual long __fastcall Read(void far *s, long n);
参数:
    s: 读出数据存放的地址;
    n: 读出数据字节数。
返回值:
    实际读出的字节数。返回值有可能:
    ① 0: 没有读出数据;
    ② 实际读出的字节数, 这个数小于或等于参数 n 的值, 并且也小于或等于属性 InBufSize 的值。

例如:
char Buffer[8192]; //定义一个 8kb 缓存
int n = Comm->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;

Comm->Write(a,10); //发送字符数组
Comm->Write(s.c_str(),s.Length()); //发送字符串
Comm->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;  //定义结构变量
Comm->Write(&MyStruct,sizeof(TMyStruct));
Command 发送命令/字符串, 这个方法不受属性 DisableWrite 的控制。
定义:
    virtual long __fastcall Command(const char far *s);
参数:
    s: 以 '\0' 结束的字符串
返回值:
    实际发送的字节数。返回值有可能小于参数 n 的值, 原因是串口忙, 或者发送缓存不足以保存所有数据。

例如:
    Comm->Command("ATDT12345678\r"); //通过 Modem 进行拨号, 采用双音频方式, 电话号码为 12345678

注意: 如果使用 AT 指令, 除了"+++"之外的指令都要用回车结束。
Command 方法只是简单的通过串口发送字符串, 并不是特殊的功能, 本例子程序用下面的方法同样可以实现:

    Comm->Write("ATDT12345678\r",13); //发送 13 个字节的数据, 因为数据的内容为 AT 指令, 如果 Modem 为命令状态, 就会进行拨号, 号码为 12345678

(通过属性 ModemStatus 可判断 Modem 的状态, 如果 MS_RLSD_ON 位有效, 为已经拨号成功, 收发数据的状态, 否则为命令状态, 所有写入串口的数据都认为是命令。)

很多软件 MODEM 没有硬件接线状态, 需要用判断收到的数据包含 "CONNECT" 字符串判断连接成功,是最通用的方法。
PurgeRead 清空读数据缓存 (扔掉读出的数据)
定义:
    virtual void __fastcall PurgeRead(bool bAbort=false);
参数:
    bAbort: 强制终止正在执行的接收动作, 默认值为 false
PurgeWrite

清空写数据缓存 (扔掉正在写的数据, 终止当前的写动作)
定义:
    virtual void __fastcall PurgeWrite(bool bAbort=false);
参数:
    bAbort: 强制终止正在执行的发送动作, 默认值为 false

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 的解释
TVictorComm 构造函数
    __fastcall TVictorComm();
~TYbCommDevice 析构函数
    virtual __fastcall ~TVictorComm();
CommNotify protected 成员, 串口事件 OnCommNotify 的默认处理
定义:
    virtual void __fastcall CommNotify(int NotifyType);
参数:
    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 事件。
这个函数在串口收发线程里面执行。
CommAfterOpen

protected 成员, 当打开串口之后产生的事件的默认处理过程。
定义:
    virtual void __fastcall CommAfterOpen(void);

CommBeforeClose protected 成员, 关闭串口之前产生的事件的默认处理过程。
定义:
    virtual void __fastcall CommBeforeClose(void);

事件:

事件 描述
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 事件。

TVictorComm 类的这个事件始终在串口收发线程里面执行,
如果要同步在主线程运行,需要使用 TYbCommDevice 控件或者自己写同步的代码。
AfterOpen 在串口打开之后产生的事件, 在这个事件中可以作一些特殊处理, 比如初始化 Modem 等。
    __property void __fastcall (__closure *AfterOpen) (TObject *Sender);
参数:
    Sender: 产生事件的类或控件
BeforeClose 在关闭串口之前产生的事件, 在这个事件中可以作一些在串口关闭之前必须执行的特殊的处理。
    void __fastcall (__closure *BeforeClose) (TObject *Sender)
参数:
    Sender: 产生事件的类或控件
◤上一页:TYbCommDevice下一页:TCommQueue

C++ 爱好者 -- Victor Chen 的个人网站 www.cppfans.com 辽ICP备11016859号