unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, inifiles, StdCtrls;
const   
  //     MAXCOMNUM   =   2   ;     //设置最大支持串口数目   
      WM_RECEIVEDATA   =   WM_USER   +   1;
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;    thrRead= class(TThread)
      protected
          procedure   Execute   ;   Override;
      public
          constructor   Create;
      end;
   function opencom(comname:Integer):THandle;   //串口初始化
   function readcom(comname:THandle):String;    //读取串口数据
   function writecom(comname:THandle;pwrite:PChar):Boolean;    //写入串口数据
   function closecom(comname:THandle):Boolean;  //关闭串口
var
  Form1: TForm1;
  hComAll: THandle;
  hEvent: THandle;
implementationuses Math;{$R *.dfm}procedure thrRead.Execute;
 var
  TEventMask :DWORD;
  TWait :Boolean;
begin
  TEventMask:=0;
   while not Terminated do
     begin
       TWait:=WaitCommEvent(hComAll,TEventMask,nil);
        if TWait then
          begin
            WaitForSingleObject(hEvent,INFINITE);  //   等待同步事件定位
            ResetEvent(hEvent);            // 同步事件复位
            PostMessage(Form1.Handle,WM_RECEIVEDATA,0,0);//向主进程发送消息
          end;
     end;
end;constructor thrRead.Create;
 begin
   FreeOnTerminate :=True;
    inherited Create(False);
 end;function opencom(comname:Integer):THandle;
var
  Tcomname:PChar;
  Dcb:TDCB;
  Hcom:THandle;
  Htimeout:TCommTimeouts;
  ini:TIniFile;
begin
  Result:=INVALID_HANDLE_VALUE;
  ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'com.ini');
  Tcomname := pchar('com'+IntToStr(comname));
  Hcom := CreateFile(Tcomname,GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
   if Hcom=invalid_handle_value then
     begin
       MessageBox(0,pchar('Notice : com '+inttostr(comname)+'is a invoild com!'),'notice',MB_OK);
     end
   else
     begin
      //通过GetCommState函数填充设备控制块DCB
      GetCommState(Hcom,Dcb);
      //通过调用SetCommState函数配置串行口的波特率、数据位、停止位和校验位
      Dcb.BaudRate:=StrToInt(ini.ReadString('com','BaudRate',''));      //每秒位数
      Dcb.ByteSize:=StrToInt(ini.ReadString('com','ByteSize',''));      //数据位
      Dcb.StopBits:=StrToInt(ini.ReadString('com','StopBits',''));      //停止位
      Dcb.Parity:=StrToInt(ini.ReadString('com','Parity',''));          //奇偶校验
      SetCommState(Hcom,Dcb);
      //设置读写缓冲
      SetupComm(Hcom,4096,4096);
      //   设置超时
       Htimeout.ReadIntervalTimeout:=100;
       Htimeout.ReadTotalTimeoutMultiplier:=1;
       Htimeout.ReadTotalTimeoutConstant:=100;
       Htimeout.WriteTotalTimeoutMultiplier:=1;
       Htimeout.WriteTotalTimeoutConstant:=100;
       SetCommTimeouts(Hcom,Htimeout);
     end;
  //指定串行口事件为接收到字符;
  SetCommMask(Hcom,EV_RXCHAR);
  //返回创建串口设备的句柄
  Result:=Hcom;
end;function readcom(comname:THandle):String;
var
 ByteToRead:DWORD;
 ByteRead:DWORD;
 S:String;
begin
  ByteToRead:=4096;
  ByteRead:=0;
  SetLength(s,ByteToRead);
  ReadFile(comname,s[1],ByteToRead,ByteRead,nil);
   if ByteRead>0 then
    begin
     SetLength(Result,ByteRead);
     Move(s[1],Result[1],ByteRead);
    end;
end;function writecom(comname:THandle;pwrite:PChar):Boolean;
var
  ByteToWrite:DWORD;              //   共需写入数
  ByteStartWrite:DWORD;           //   从何处开始写入
  ByteWrite:DWORD;                //    已写入数
  Tresult:Boolean;
begin
   ByteStartWrite:=0;
   ByteWrite:=0;
   ByteToWrite:=StrLen(pwrite);
     repeat
      Tresult:=WriteFile(comname,pwrite[ByteStartWrite],ByteToWrite,ByteWrite,nil);
      Dec(ByteToWrite,ByteWrite);
      Inc(ByteStartWrite,ByteWrite);
     until  (ByteToWrite<=0);
 Result:=Tresult;
end;function closecom(comname:THandle):Boolean;
begin
  Result:=CloseHandle(comname);
end;procedure TForm1.Button1Click(Sender: TObject);
var
ini:TIniFile;
PATCommand:PChar;
comstat:PComStat;
TErrorFlag:DWORD;
ReadResult:String;
begin
   Memo1.Lines.Clear;
   ini:=TIniFile.Create(ExtractFilePath(Application.ExeName)+'com.ini');
   //**********端口初始化********
   hComAll:=opencom(StrToInt(ini.ReadString('com','com','')));
    if hComAll=INVALID_HANDLE_VALUE then
      begin
       Memo1.Lines.Add('Open COM'+ini.ReadString('COM','COM','')+' error!');
       Exit;
      end
    else
      begin
       Memo1.Lines.Add('Open COM'+ini.ReadString('com','com','')+' Success!');
      end;
    //打开端口监听
   hEvent:=CreateEvent(nil,True,False,nil);
   thrRead.Create;
   Memo1.Lines.Add('COM Listen ThrRead Create Success!');
    //向端口写入命令
    try
      PATCommand:=pchar('at+STX'+chr(13));
      writecom(hComAll,PATCommand);
        try
          PATCommand:=pchar('at+B'+Chr(13));
          writecom(hComAll,PATCommand);
           try
             PATCommand:=pchar('at+ETX'+chr(13));
             writecom(hComAll,PATCommand);
           except
             Memo1.Lines.Add('Write Command error!');
           end;
        except
          Memo1.Lines.Add('Write Command error!');
        end;
    except
       Memo1.Lines.Add('Write Command error!');
    end;
    {try
     PATCommand:=pchar('STX');
      if writecom(hComAll,PATCommand) then
        begin
         PATCommand:=pchar('B');
          if writecom(hComAll,PATCommand) then
           begin
             PATCommand:=pchar('ETX');
              If writecom(hComAll,PATCommand) then
               begin
                Memo1.Lines.Add('Write Command Success!');
               end
              else
               begin
                Memo1.Lines.Add('Write Command error!');
               end;
           end
          else
           begin
            Memo1.Lines.Add('Write Command error!');
           end;
        end
       else
         begin
           Memo1.Lines.Add('Write Command error!');
         end;
     except
      Memo1.Lines.Add('Write Command error!');
     end;   }
   //******* 获得返回值
    ReadResult:='';
    GetMem(comstat,SIZEOF(Tcomstat));
    ClearCommError(hComAll,TErrorFlag,comstat);
    if TErrorFlag>0 then
     begin
       PurgeComm(hComAll,PURGE_RXABORT and PURGE_RXCLEAR);
     end;
    if comstat.cbInQue >0 then
      ReadResult:=readcom(hComAll);
    Memo1.Lines.Add('Listen Result : '+ReadResult);
    SetEvent(hEvent);
   //******关闭端口
   closecom(hComAll);
end;end.
运行后死机,不知道什么问题?

解决方案 »

  1.   

    既然是串口通信
    建议用SPComm吧
    这个控件挺成熟 我以前用它做过与Modem的通信
    在网上可以免费下载
      

  2.   

    用spcomm组件,spcomm是多线程的,用起来比较简单
      

  3.   

    告诉email给你发一个spcomm组件
      

  4.   

    我邮箱[email protected] 给我发份spcomm教程吧
      

  5.   

    首先打开串口:procedure TForm1.Button2Click(Sender: TObject);
    begin
      comm1.BaudRate:=4800;//可以在属性窗口设置
      comm1.CommName:='com1';//可以在属性窗口设置
      try
        comm1.StartComm;
      except
        showmessage('串口打开错误');
      end;
    end;然后发送数据procedure TForm1.send(sbuf: byte);
    begin
      if not  comm1.WriteCommData(@sbuf,1) then
      begin
        showmessage('发送错误!');
      end;
    end;
    处理接收事件
    [code=Delphi(Pascal)]
    procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    var
      rbuf:array of byte;
      i:integer;
      t:ttime;
    begin
      setLength(rbuf, BufferLength);
      move(Buffer^, PChar(rbuf)^, BufferLength);
      memo1.Lines.Add('长度'+inttostr(BufferLength));
      for i:=0 to  BufferLength-1 do
      begin
         memo1.Lines.Add(inttostr(rbuf[i]));
      end;
    end;最后关闭串口
    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      comm1.StopComm;
    end;
      

  6.   

    需要注意的是,如果不用软件流和硬件流的方式,需要在组件的属性栏进行设定:
    这是我使用时的设定:
    object Comm1: TComm
        CommName = 'COM1'
        BaudRate = 4800
        ParityCheck = False
        Outx_CtsFlow = False
        Outx_DsrFlow = False
        DtrControl = DtrDisable
        DsrSensitivity = False
        TxContinueOnXoff = False
        Outx_XonXoffFlow = False
        Inx_XonXoffFlow = False
        ReplaceWhenParityError = False
        IgnoreNullChar = False
        RtsControl = RtsDisable
        XonLimit = 500
        XoffLimit = 500
        ByteSize = _8
        Parity = None
        StopBits = _1
        XonChar = #17
        XoffChar = #19
        ReplacedChar = #0
        ReadIntervalTimeout = 10
        ReadTotalTimeoutMultiplier = 0
        ReadTotalTimeoutConstant = 0
        WriteTotalTimeoutMultiplier = 0
        WriteTotalTimeoutConstant = 0
        OnReceiveData = Comm1ReceiveData
        OnModemStateChange = Comm1ModemStateChange
        Left = 400
        Top = 88
      end
      

  7.   

    你的代码太乱了,用SPCOMm吧。