Delphi SPComm设置的问题

Mr Dang 2014-08-26 05:10:28


上图是使用AccessPort监控得到2个串口软件的参数。

使用QComm发送字符串可以正常通讯(QCOM网上下的一个软件)。
使用串口助手发送字符串无法通讯。
Delphi 使用SPCOMM发送字符也无法通讯。

//程序的设置

function TComm232.InitComm(Str_CommName,Str_BaudRate,Str_DataSize,Str_StopBits,Str_Parity:string):Integer;
var
i_BaudRate,i_ByteSizeIndex,i_StopBitsIndex,i_ParityIndex:Integer;
begin
Result:=0;
i_BaudRate:=StrToIntDef(Str_BaudRate,230400);
if Str_DataSize='5' then i_ByteSizeIndex:=0
else if Str_DataSize='6' then i_ByteSizeIndex:=1
else if Str_DataSize='7' then i_ByteSizeIndex:=2
else if Str_DataSize='8' then i_ByteSizeIndex:=3
else i_ByteSizeIndex:=3;
if Str_StopBits='2' then i_StopBitsIndex:=2
else if Str_StopBits='1.5' then i_StopBitsIndex:=1
else if Str_StopBits='1' then i_StopBitsIndex:=0;
if Str_Parity='Even' then i_ParityIndex:=0
else if Str_Parity='Mark' then i_ParityIndex:=1
else if Str_Parity='None' then i_ParityIndex:=2
else if Str_Parity='Odd' then i_ParityIndex:=3
else if Str_Parity='Space' then i_ParityIndex:=4
else i_ParityIndex:=2;
Comm.CommName:='//./'+Str_CommName;
Comm.BaudRate:=i_Baudrate;
Comm.ByteSize:=TEumn_ByteSize[i_ByteSizeIndex];
Comm.StopBits:=TEumn_StopBits[i_StopBitsIndex];
Comm.Parity:=TEumn_Parity[i_ParityIndex];

Comm.Outx_CtsFlow:= False;
Comm.Outx_DsrFlow:=False;
Comm.DtrControl:=DtrDisable;
Comm.TxContinueOnXoff:=False;
Comm.RtsControl:=RtsDisable;

Comm.XonLimit:=4096;
Comm.XoffLimit:=1024;


Comm.ReadIntervalTimeout:=1;
//Start
Comm.Inx_XonXoffFlow:=False;
Comm.Outx_XonXoffFlow:=False;
Comm.StopComm;
try
Comm.StartComm;
Sleep(180);
except
Result:=-1;
Comm.StopComm;
Exit;
end;
end;


我程序SPCOMM里应该怎么设置才能和QCOM一样?
...全文
420 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
fang 2014-08-27
  • 打赏
  • 举报
回复
恭喜啊,还是要自己调试才知道。
Mr Dang 2014-08-27
  • 打赏
  • 举报
回复
Mr Dang 2014-08-27
  • 打赏
  • 举报
回复
我自己弄好了。
 
    Comm.Outx_CtsFlow:= False;
    Comm.Outx_DsrFlow:=False;
    Comm.DtrControl:=DtrDisable;
    Comm.TxContinueOnXoff:=False;
    Comm.RtsControl:=RtsDisable;
这个不要,也不要去修改那些掩码,不要修改SPCOMM,原来是我发送字符的时候要这样的格式: Send_Str+#13+#10,增加了#13#10,我是通过虚拟串口助手,使用QCom发送到串口助手上,自己的软件也发送到串口助手上,对比发现发送字符串要回车换行~
Bzdr_2 2014-08-26
  • 打赏
  • 举报
回复
修改SPCOMM源码,也无法触发接收事件~~~ ,大神,救命呀~~~

procedure TComm.StartComm;
var
   hNewCommFile:   THandle;
begin
     // Are we already doing comm?
     if (hCommFile <> 0) then
        raise ECommsError.Create( 'This serial port already opened' );

     hNewCommFile := CreateFile( PChar(FCommName),
                                 GENERIC_READ or GENERIC_WRITE,
                                 0, {not shared}
                                 nil, {no security ??}
                                 OPEN_EXISTING,
                                 FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
                                 0 {template} );

     if hNewCommFile = INVALID_HANDLE_VALUE then
        raise ECommsError.Create( 'Error opening serial port' );

     // Is this a valid comm handle?
     if GetFileType( hNewCommFile ) <> FILE_TYPE_CHAR then
     begin
          CloseHandle( hNewCommFile );
          raise ECommsError.Create( 'File handle is not a comm handle ' )
     end;

     if not SetupComm( hNewCommFile, 4096, 4096 ) then
     begin
          CloseHandle( hCommFile );
          raise ECommsError.Create( 'Cannot setup comm buffer' )
     end;

     // It is ok to continue.

     hCommFile := hNewCommFile;

     // purge any information in the buffer

     PurgeComm( hCommFile, PURGE_TXABORT or PURGE_RXABORT or
                           PURGE_TXCLEAR or PURGE_RXCLEAR ) ;

     SetCommMask(hCommFile,EV_RXCHAR or EV_TXEMPTY or EV_CTS or       //Add 20140826
                           EV_DSR or EV_RLSD or EV_BREAK or
                           EV_ERR or EV_RING);

     PurgeComm( hCommFile, PURGE_TXABORT or PURGE_RXABORT or          //Add 20140826
                           PURGE_TXCLEAR or PURGE_RXCLEAR ) ;

     FSendDataEmpty := True;

     // Setting the time-out value
     _SetCommTimeout;

     // Querying then setting the comm port configurations.
     _SetCommState;

     // Create the event that will signal the threads to close.
     hCloseEvent := CreateEvent( nil, True, False, nil );

     if hCloseEvent = 0 then
     begin
          CloseHandle( hCommFile );
          hCommFile := 0;
          raise ECommsError.Create( 'Unable to create event' )
     end;

     // Create the Read thread.
     try
        ReadThread := TReadThread.Create( True {suspended} );
     except
           ReadThread := nil;
           CloseHandle( hCloseEvent );
           CloseHandle( hCommFile );
           hCommFile := 0;
           raise ECommsError.Create( 'Unable to create read thread' )
     end;
     ReadThread.hCommFile := hCommFile;
     ReadThread.hCloseEvent := hCloseEvent;
     ReadThread.hComm32Window := FHWnd;

     // Comm threads should have a higher base priority than the UI thread.
     // If they don't, then any temporary priority boost the UI thread gains
     // could cause the COMM threads to loose data.
     ReadThread.Priority := tpHighest;

     // Create the Write thread.
     try
        WriteThread := TWriteThread.Create( True {suspended} );
     except
           CloseReadThread;
           WriteThread := nil;
           CloseHandle( hCloseEvent );
           CloseHandle( hCommFile );
           hCommFile := 0;
           raise ECommsError.Create( 'Unable to create write thread' )
     end;
     WriteThread.hCommFile := hCommFile;
     WriteThread.hCloseEvent := hCloseEvent;
     WriteThread.hComm32Window := FHWnd;
     WriteThread.pFSendDataEmpty := @FSendDataEmpty;

     WriteThread.Priority := tpHigher;

     ReadThread.Resume;
     WriteThread.Resume

     // Everything was created ok.  Ready to go!
end; {TComm.StartComm}

procedure TReadThread.Execute;
var
   szInputBuffer: array[0..INPUTBUFFERSIZE-1] of Char;
   nNumberOfBytesRead:    DWORD;

   HandlesToWaitFor:      array[0..2] of THandle;
   dwHandleSignaled:      DWORD;

   fdwEvtMask:                    DWORD;

   // Needed for overlapped I/O (ReadFile)
   overlappedRead:                TOverlapped;

   // Needed for overlapped Comm Event handling.
   overlappedCommEvent:   TOverlapped;
label
     EndReadThread;
begin
     FillChar( overlappedRead, Sizeof(overlappedRead), 0 );
     FillChar( overlappedCommEvent, Sizeof(overlappedCommEvent), 0 );

     // Lets put an event in the Read overlapped structure.
     overlappedRead.hEvent := CreateEvent( nil, True, True, nil);
     if overlappedRead.hEvent = 0 then
     begin
          PostHangupCall;
          goto EndReadThread
     end;

     // And an event for the CommEvent overlapped structure.
     overlappedCommEvent.hEvent := CreateEvent( nil, True, True, nil);
     if overlappedCommEvent.hEvent = 0 then
     begin
          PostHangupCall();
          goto EndReadThread
     end;

     // We will be waiting on these objects.
     HandlesToWaitFor[0] := hCloseEvent;
     HandlesToWaitFor[1] := overlappedCommEvent.hEvent;
     HandlesToWaitFor[2] := overlappedRead.hEvent;

     // Setup CommEvent handling.

     // Set the comm mask so we receive error signals.
//     if not SetCommMask(hCommFile, EV_ERR or EV_RLSD or EV_RING ) then
//     begin
//          PostHangupCall;
//          goto EndReadThread
//     end;

     if not SetCommMask(hCommFile,EV_RXCHAR or EV_TXEMPTY or EV_CTS or     //Modification 20140826
                                  EV_DSR or EV_RLSD or EV_BREAK or
                                  EV_ERR or EV_RING) then
     begin
          PostHangupCall;
          goto EndReadThread
     end;

     // Start waiting for CommEvents (Errors)
     if not SetupCommEvent( @overlappedCommEvent,  fdwEvtMask ) then
        goto EndReadThread;

     // Start waiting for Read events.
     if not SetupReadEvent( @overlappedRead,
                            szInputBuffer, INPUTBUFFERSIZE,
                            nNumberOfBytesRead ) then
        goto EndReadThread;

     // Keep looping until we break out.
     while True do
     begin
          // Wait until some event occurs (data to read; error; stopping).
          dwHandleSignaled := WaitForMultipleObjects(3, @HandlesToWaitFor,
                              False, INFINITE);

          // Which event occured?
          case dwHandleSignaled of
               WAIT_OBJECT_0:     // Signal to end the thread.
               begin
                    // Time to exit.
                    goto EndReadThread
               end;

               WAIT_OBJECT_0 + 1: // CommEvent signaled.
               begin
                    // Handle the CommEvent.
                    if not HandleCommEvent( @overlappedCommEvent, fdwEvtMask, TRUE ) then
                       goto EndReadThread;

                    // Start waiting for the next CommEvent.
                    if not SetupCommEvent( @overlappedCommEvent, fdwEvtMask ) then
                       goto EndReadThread
                    {break;??}
               end;

               WAIT_OBJECT_0 + 2: // Read Event signaled.
               begin
                    // Get the new data!
                    if not HandleReadEvent( @overlappedRead,
                                            szInputBuffer,
                                            INPUTBUFFERSIZE,
                                            nNumberOfBytesRead ) then
                       goto EndReadThread;

                    // Wait for more new data.
                    if not SetupReadEvent( @overlappedRead,
                                           szInputBuffer, INPUTBUFFERSIZE,
                                           nNumberOfBytesRead ) then
                       goto EndReadThread
                    {break;}
               end;

               WAIT_FAILED:       // Wait failed.  Shouldn't happen.
               begin
                    PostHangupCall;
                    goto EndReadThread
               end
               else    // This case should never occur.
               begin
                    PostHangupCall;
                    goto EndReadThread
               end
          end {case dwHandleSignaled}
     end; {while True}

        // Time to clean up Read Thread.
 EndReadThread:

     PurgeComm( hCommFile, PURGE_RXABORT + PURGE_RXCLEAR );
     CloseHandle( overlappedRead.hEvent );
     CloseHandle( overlappedCommEvent.hEvent )
end; {TReadThread.Execute}
Bzdr_2 2014-08-26
  • 打赏
  • 举报
回复
SetCommMask:设置事件的掩码,用以触发事件 应该是这个函数引起的,导致不能触发接收事件,我设置了这个函数,然后监控到他自动又回去了,难道要改SPCOMM源代码?还有没有其他解决方案 ~~
Bzdr_2 2014-08-26
  • 打赏
  • 举报
回复
@fang098 问题就是不触发SPCOMM接收事件~ 串口事件掩码没有收的处理。 这里怎么处理???
Mr Dang 2014-08-26
  • 打赏
  • 举报
回复
@fang098


//Start
Comm.Inx_XonXoffFlow:=False;
Comm.Outx_XonXoffFlow:=False;
Comm.StopComm;
try
Comm.StartComm;

m_CommMask:=EV_RXCHAR or EV_TXEMPTY or EV_CTS or EV_DSR or EV_RLSD or EV_BREAK or EV_ERR or EV_RING;
SetCommMask(Comm.Handle,m_CommMask);

Sleep(180);
except
Result:=-1;
Comm.StopComm;
Exit;
end;


还是不行 ~~ 设置的掩码又自动回去了 ~~~

Mr Dang 2014-08-26
  • 打赏
  • 举报
回复
@fang098 我试下你的方法
Mr Dang 2014-08-26
  • 打赏
  • 举报
回复
constructor TComm232.Create();
begin
    Inherited Create();
    Comm:=TComm.Create(nil);
    Comm.OnReceiveData:=CommReceiveData;
    Gl_b_ReceivedEnd:=False;
end;

destructor TComm232.Destroy();
begin
    try
        Comm.OnReceiveData:=nil;
        Comm.StopComm;
        FreeAndNil(Comm);
    except
        
    end;
    Application.ProcessMessages;
    Inherited Destroy;
end;
fang 2014-08-26
  • 打赏
  • 举报
回复
spcomm记得是能拿到串口名句柄的,控件没提供设置掩码的话自己用API设置的。 m_CommMask = EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING | EV_ERR; SetCommMask(m_Handle,m_CommMask)) m_Handle是SPCOMM打开的串口句柄
fang 2014-08-26
  • 打赏
  • 举报
回复
你的下面是不是你收的串口参数?串口事件掩码没有收的处理。数据到达触发不了数据接收。

16,746

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧