Delphi下的具体实现方法
    Delphi的强大功能和支持多线程的面向对象编程技术,使得实现串行通信非常简单方
便。它通过调用外部的API函数来实现,主要步骤如下。
    1. 利用CreateFile函数打开串行口,以确定本应用程序对此串行口的占有权,并封锁
其它应用程序对此串口的操作;
    2. 通过GetCommState函数填充设备控制块DCB,再通过调用SetCommState函数配置串
行口的波特率、数据位、校验位和停止位;
    3. 创建串行口监视线程监视串行口事件,在此基础上就可以在相应的串口上操作数
据的传输;
    4. 用CloseHandle函数关闭串行口(具体的程序如下)。本程序用Delphi3.0编写,在
Windows 95环境下调试通过,已投入实际应用中,供广大读者参考。
    程序:
    unit comdemou;
    interface
    uses
     Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialo
gs;
    const
     Wm_commNotify=Wm_User+12;
    type
     TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
     private
    Procedure comminitialize;
    Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify;
    { Private declarations }
     public
    { Public declarations }
     end;
     //线程声明
     TComm=Class(TThread)
     protected
     procedure Execute;override;
     end;
    var
     Form1: TForm1;
     hcom,Post_Event:Thandle;
     lpol:Poverlapped;
    implementation
    {$R *.DFM}
    Procedure TComm.Execute;
    //线程执行过程
    var
    dwEvtMask:Dword;
    Wait:Boolean;
    Begin
    fillchar(lpol,sizeof(toverlapped),0);
    While True do Begin
     dwEvtMask:=0;
     Wait:=WaitCommEvent(hcom,dwevtmask,lpol);
     //等待串行口事件;
     if Wait Then Begin
     waitforsingleobject(post_event,infinite);  //等待同步事件置位;
     resetevent(post_event);
     //同步事件复位;
     PostMessage(Form1.Handle,WM_COMMNOTIFY,0,0);//发送消息;
     end;
     end;
    end;
    procedure Tform1.comminitialize;
     //串行口初始化
    var
    lpdcb:Tdcb;
    Begin
    hcom:=createfile(‘com2’,generic_read or generic_write,0,nil,open_exist
ing,
     file_attribute_normal or file_flag_overlapped,0);//打开串行口
    if hcom=invalid_handle_value then
    else
    setupcomm(hcom,4096,4096);
     //设置输入、输出缓冲区皆为4096字节
    getcommstate(hcom,lpdcb);
    //获取串行口当前默认设置
    lpdcb.baudrate:=2400;
    lpdcb.StopBits:=1;
    lpdcb.ByteSize:=8;
    lpdcb.Parity:=EvenParity;
     //偶校验
    Setcommstate(hcom,lpdcb);
    setcommMask(hcom,ev_rxchar);
     //指定串行口事件为接收到字符;
    end;
    Procedure TForm1.MsgcommProcess(Var Message:Tmessage);
    var
    Clear:Boolean;
    Coms:Tcomstat;
    cbNum,ReadNumber,lpErrors:Integer;
    Read_Buffer:array[1..100]of char;
    Begin
    Clear:=Clearcommerror(hcom,lpErrors,@Coms);
    if Clear Then Begin
      cbNum:=Coms.cbInQue;
      ReadFile(hCom,Read_Buffer,cbNum,ReadNumber,lpol);
      //处理接收数据
      SetEvent(Post_Event);
     //同步事件置位
      end;
    end;
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    comminitialize;
    post_event:=CreateEvent(nil,true,true,nil); //创建同步事件;
    Tcomm.Create(False);
    //创建串行口监视线程;
    end;
    end.

解决方案 »

  1.   

    Delphi串口通讯的监听  
    unit frmComm;
    interface
    uses
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, ComCtrls,GeoUtils,GeoGPS;
    const MAXBLOCK = 160;
    type
    TComm = record
    idComDev : THandle;
    fConnected : Boolean;
    end;
    TCommForm = class(TForm)
    ComboBox1: TComboBox;
    Button1: TButton;
    StatusBar1: TStatusBar;
    Button2: TButton;
    ComboBox2: TComboBox;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    private
    { Private declarations }
    public
    { Public declarations }
    end;
    TCommThread = Class(TThread)
    protected
    procedure Execute;override;
    public
    constructor Create;
    end;
    var
    CommForm: TCommForm;
    CommHandle : THandle;
    Connected : Boolean;
    CommThread : TCommThread;
    implementation
    {$R *.DFM}
    uses
    frmMain,frmMdiMapView;
    procedure TCommThread.Execute;
    var
    dwErrorFlags,dwLength : DWORD;
    ComStat : PComStat;
    fReadStat : Boolean;
    InChar : Char;
    AbIn : String;
    XX,YY : double; file://经度、纬度
    VID : string; file://车号
    begin
    while Connected do begin
    GetMem(ComStat,SizeOf(TComStat));
    ClearCommError(CommHandle, dwErrorFlags, ComStat);
    if (dwErrorFlags > 0) then begin
    PurgeComm(CommHandle,(PURGE_RXABORT and PURGE_RXCLEAR));
    // return 0;
    end;
    dwLength := ComStat.cbInQue;
    if (dwLength>0) then begin
    fReadStat := ReadFile(CommHandle, InChar, 1,dwLength, nil);
    if (fReadStat) then begin
    if (InChar <> Chr(13)) and (Length(abIn) < MAXBLOCK+5 ) then AbIn := AbIn + InChar
    else begin
    ...
    {接收完毕,}
    end;//if (fReadStat>0){
    end; file://if (dwLength>0){
    FreeMem(ComStat);
    end;{while}
    end;
    constructor TCommThread.Create;
    begin
    FreeOnTerminate := TRUE;
    inherited Create(FALSE); file://Createsuspended = false
    end;
    //
    procedure TCommForm.Button1Click(Sender: TObject);
    var
    CommTimeOut : TCOMMTIMEOUTS;
    DCB : TDCB;
    fRetVal : Boolean;
    begin
    StatusBar1.SimpleText := ’连接中...’;
    CommHandle := CreateFile(PChar(ComboBox1.Text),GENERIC_READ,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL
    , 0);
    if CommHandle = INVALID_HANDLE_VALUE then begin
    StatusBar1.SimpleText := ’连接失败’;
    Exit;
    end;
    StatusBar1.SimpleText := ’已同端口 ’+ ComboBox1.Text + ’ 连接!’;
    CommTimeOut.ReadIntervalTimeout := MAXDWORD;
    CommTimeOut.ReadTotalTimeoutMultiplier := 0;
    CommTimeOut.ReadTotalTimeoutConstant := 0;
    SetCommTimeouts(CommHandle, CommTimeOut);
    GetCommState(CommHandle,DCB);
    DCB.BaudRate := 9600;
    DCB.ByteSize := 8;
    DCB.Parity := NOPARITY;
    DCB.StopBits := ONESTOPBIT;
    fRetVal := SetCommState(CommHandle, DCB);
    if (fRetVal) then begin
    Connected := TRUE;
    try
    CommThread := TCommThread.Create;
    except
    Connected := FALSE;
    CloseHandle(CommHandle);
    fRetVal := FALSE;
    StatusBar1.SimpleText := ’线程建立失败’;
    Exit;
    end;
    end
    else begin
    Connected := FALSE;
    CloseHandle(CommHandle);
    end;
    end;
    procedure TCommForm.Button2Click(Sender: TObject);
    begin
    Connected := FALSE;
    CloseHandle(CommHandle);
    {终止线程}
    CommThread.Terminate;
    StatusBar1.SimpleText := ’关闭端口’+ComboBox1.Text;
    end;
    procedure TCommForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    Connected := FALSE;
    CloseHandle(CommHandle);
    StatusBar1.SimpleText := ’关闭端口’+ComboBox1.Text;
    end;
    end. 
      

  2.   

    Delphi中串行通信的实现  
        随 着 现 代 信 息 技 术 的 发 展 以 及 计 算 机 网 络 的 广 泛 使 用, 计 算 机 通 信 技 术已 经 日 臻 成 熟, 但 串 行 通 信 作 为 一 种 灵 活 方 便 可 靠 的 通 信 方 式, 仍 不 失 为有 效 的 通 信 手 段, 被 广 泛 应 用 于 工 业 控 制 中。 在 工 业 生 产 实 践 中, 用PC 机 对工 程 实 现 实 时 监 控, 通 常 要 求PC 机 能 在 用 户 界 面 上 具 有 数 据 采 集、 数 据 处理 以 及 控 制 信 号 的 产 生 与 传 输 等 功 能。 在 这 种 特 定 的 环 境 下,PC 机 要 与 过程 控 制 的 实 时 信 号 相 联 系, 就 要 求 能 实 现 对PC 机 的 串 行 端 口 直 接 操作。Borland 公 司 推 出 的Delphi 是 一 种 功 能 强 大 的 高 级 编 程 语 言, 其 具 有 的 可 视 化 面 向 对象 的 特 性, 特 别 适 于 在Windows 环 境 下 图 形 界 面 和 用 户 程 序 的 编 制。 本 文 就 是介 绍 基 于Windows95/NT 操 作 系 统 用Delphi 来 实 现PC 机 与 下 层PLC 控 制 器 之 间 的 串 口通 信 方 法。 基 于WIN95/NT 的 串 行 通 信 机 制 Windows 操 作 系 统 的 机 制 禁 止 应 用 程 序 直 接 访 问 计 算 机 硬 件, 但 它 为 程 序员 提 供 了 一 系 列 的 标 准API 函 数, 使 得 应 用 程 序 的 编 制 更 加 方 便 并 且 免 除 了对 有 关 硬 件 的 调 试 麻 烦。 在Windows95/NT 中, 原 来Windows3.X 的WM_COMMNOTIFY 消 息已 被 取 消, 操 作 系 统 为 每 个 通 信 设 备 开 辟 了 用 户 可 定 义 大 小 的 读/ 写 缓 冲区, 数 据 进 出 通 信 口 均 由 操 作 系 统 后 台 完 成, 应 用 程 序 只 需 对 读/ 写 缓 冲 区操 作 即 可。WIN95/NT 中 几 个 常 用 的 串 行 通 信 操 作 函 数 如 下: CreatFile
     打 开 串 行 口
    CloseHandle
     关 闭 串 行 口
    SetupComm
     设 置 通 信 缓 冲 区 的 大 小
    ReadFile
     读 串 口 操 作
    WriteFile
     写 串 口 操 作
    SetCommState
     设 置 通 信 参 数
    GetCommState
     获 取 默 认 通 信 参 数
    ClearCommError
     清 除 串 口 错 误 并 获 取 当 前 状 态
    除 上 述 几 个 函 数 外, 还 要 经 常 用 到 一 个 重 要 的 记 录DCB( 设 备 控 制块)。DCB 中 记 录 有 可 定 义 的 串 行 口 参 数, 设 置 串 行 口 参 数 时 必 须 先 用 GetCommState 函 数 将 系 统 默 认 值 填 入DCB 控 制 块, 然 后 才 可 把 用 户 想 改 变 的 自 定义 值 设 定。 在WIN95/NT 中 进 行 串 行 通 信 除 了 解 基 本 的 通 信 操 作 函 数 外, 还 要 掌 握 多 线程 编 程。 线 程 是 进 程 内 部 执 行 的 路 径, 是 操 作 系 统 分 配CPU 时 间 的 基 本 实体。 每 个 进 程 都 由 单 线 程 开 始 完 成 应 用 程 序 的 执 行。 串 行 通 信 需 要 利 用 多线 程 技 术 实 现, 其 主 要 的 处 理 逻 辑 可 以 表 述 如 下: 进 程 一 开 始 先 由 主 线 程做 一 些 必 要 的 初 始 化 工 作, 然 后 主 线 程 根 据 需 要 在 适 当 时 候 建 立 通 信 监 视线 程 监 视 通 信 口, 当 指 定 的 串 行 口 事 件 发 生 时, 向 主 线 程 发 送 WM_COMMNOTIFY 消 息( 由 于WIN95 取 消 了WM_COMMNOTIFY 消 息, 因 此 必 须 自 己 创建), 主 线 程 对 其 进 行 处 理。 若 不 需 要WM_COMMNOTIFY 消 息, 则 主 线 程 终 止 通信 监 视 线 程。 多 线 程 同 时 执 行, 将 会 引 起 对 共 享 资 源 的 冲 突。 为 避 免 冲 突, 就 要 用 同步 多 线 程 对 共 享 资 源 进 行 访 问。WIN95 提 供 了 许 多 保 持 线 程 同 步 的 方 法, 笔者 采 用 创 建 事 件 对 象 来 保 持 线 程 同 步。 通 过CraeteEvent() 创 建 事 件 对 象, 使用SetEvent() 或PulseEvent() 函 数 将 事 件 对 象 设 置 成 信 号 同 步。 在 应 用 程 序 中,利 用WaitSingleObject() 函 数 等 待 同 步 的 触 发, 等 到 指 定 的 事 件 被 其 它 线 程 设 置为 有 信 号 时, 才 继 续 向 下 执 行 程 序。
      

  3.   

    关注,好像有专门讲此类的一本书,chint-pub出版的
      

  4.   

    《Delphi串口通信编程》http://wulumuqi.bayakala.com/list/AdBook.asp?ADIDclick=921&PluId=711509564&LicenseId=7-115http://roaringwind.best.163.com/scomm/sc2dephispcomm02.htmhttp://www.swm.com.cn/yingyong/yy-00-07/yy11.htmhttp://www.comprg.com.cn/wz052.htmhttp://xuhao23.myetang.com/jq/network/http://www.china-pub.com/computers/emook/0918/info.htm
      

  5.   

    可用windows 自有的api 或是ocx实现