Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2349180
  • 博文数量: 816
  • 博客积分: 10000
  • 博客等级: 上将
  • 技术积分: 5010
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-17 17:57
文章分类

全部博文(816)

文章存档

2011年(1)

2008年(815)

分类:

2008-12-17 17:59:53

调制解调器 (Modem) 状态 (只读属性)
定义:
    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 SetTModemStatus;
    __property TModemStatus ModemStatus = { read = fGetModemStatus };

其他状态 (DTR 和 RTS 等) 请参考 Handle 属性和 EscapeCommFunction 方法。

例如:
    if(YbCommDevice1->ModemStatus.Contains(TYbCommDevice::msRlsdOn))
       Label1->Caption = "Modem 拨号成功, 正在联机通讯状态";
    else
       Label1->Caption = "Modem 在待命状态, 可以输入 AT 指令";
--------------------next---------------------
不允许写串口 (让 Write 方法无效)
定义:
    __property bool DisableWrite = { read = fGetDisableWrite, write = fSetDisableWrite};
如果 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; //允许写串口
--------------------next---------------------
如果启动了数据包协议, 这个属性表示数据包的最大字节数, 如果要启动数据包, 这个属性必须正确的设置。
定义:
    __property long PackageSize = { read = fGetPkgSz, write = fSetPkgSz };
相关属性:
    QueueSize, UsePackage, FrameSettings
例如:
#pragma pack(push,1) //开始定义数据包, 使用字节对齐方式
const MyPkgSize = 1024; //数据包最大长度
typedef struct
{
  long nBytes; //第一个参数必须是 32 位整数, int 或 long, 表示数据的字节数
  char Data[MyPkgSize]; //数据, 可以是任意的
} TMyPackage; //自定义的数据包
#pragma pack(pop) //结束定义数据包, 恢复原对齐方式

YbCommDevice1->PackageSize = MyPkgSize; //这个数据必须正确!
YbCommDevice1->UsePackage = true; //启动数据包 (可以随时启动和停止, 与 Active 属性无关)
--------------------next---------------------
写串口 (发送数据)
定义:
    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));
--------------------next---------------------
发送命令/字符串, 这个方法不受属性 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 位有效, 为已经拨号成功, 收发数据的状态, 否则为命令状态, 所有写入串口的数据都认为是命令。
--------------------next---------------------

显示串口设置对话框, 要求用户选择配置
    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();
}


--------------------next---------------------
protected 成员, 串口事件 OnCommNotify 的默认处理
定义:
    virtual void __fastcall NewCommBusy(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 事件。
--------------------next---------------------
串口事件, 串口在数据传输过程中产生的事件。
定义:
    __property void __fastcall (__closure *OnCommNotify) (TObject *Sender, int NotifyType) =
         { read = lpCommBusyProc, write = lpCommBusyProc };
参数:
    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 事件。
也可以不用事件, 通过定期查询来访问串口的数据, 毕竟要收满缓存或者把缓存数据发完需要比较长(相对而言)的时间。
这个事件在另外一个线程里, 没在主线程里。在这个事件里要尽可能的缩短处理时间, 不要在此事件中停留太久。
--------------------next---------------------

阅读(1620) | 评论(0) | 转发(0) |
0

上一篇:C++爱好者

下一篇:C++爱好者

给主人留下些什么吧!~~