Q&A

  • 시리얼 통신에 관하여서....꼭 좀 해결....
저는 시리얼 통신을 처음하는데 핸디 터미널로 읽은 자료는2건인데 자료를 받으면

컴으로 받아보면 5건이 읽혀지거든요....

어떻게 해결해야 하는지...

참고로 저는 Component는 AsyncFree를 이용하고요 DataReceive하는 쏘스는...

-----------------------------------------------------------------------------

procedure TForm1.AfComPort1DataRecived(Sender: TObject; Count: Integer);

Var

SendBody : Array[0..1024] of Char;

Offset : Integer;



Label EndFrame;



Label TryAgain;

begin



If bStxStarted = True Then

Begin

StrPLCopy(@RecvData[StrLen(RecvData)], AfComPort1.ReadString, Count);

If (RecvData[StrLen(RecvData)-1] = _ETX) Then

Begin

Sleep(150);

goto EndFrame;

End

Else

Begin

Goto TryAgain;

End;



End

Else If bStxStarted = False Then

Begin

i := i+1;

FillChar(RecvData, SizeOf(RecvData), 0);

StrPLCopy(@RecvData[0], AfComPort1.ReadString, Count);



If RecvData[0] = _STX Then

Begin

bStxStarted := True;

goto TryAgain;

End;

End;





EndFrame:



bStxStarted := False;

offset := 0;



If(RecvData[1] = _EOT)then

Begin

FillChar(SendBody, Sizeof(SendBody), 0);

Offset := 0;

SendBody[offset] := _STX;

Inc(offset, 1);

SendBody[offset] := _ACK;

Inc(offset, 1);

SendBody[offset] := _ETX;

Inc(offset, 1);

AfComPort1.WriteString(SendBody);

Exit;

End;



If (REcvData[1] = _ENQ)then

Begin

FillChar(sendBody, sizeof(sendBody), 0);

Offset := 0;

SendBody[offset] := _STX;

Inc(offset, 1);

SendBody[offset] := _ACK;

Inc(offset, 1);

SendBody[offset] := _ETX;

Inc(offset, 1);

AfComPort1.WriteString(SendBody);

exit;

end;



FillChar(sendBody, sizeof(sendBody), 0);

offset := 0;

SendBody[offset] := _STX;

Inc(offset, 1);

SendBody[offset] := _ACK;

Inc(offset, 1);

SendBody[offset] := _ETX;

Inc(offset, 1);

AfComPort1.WriteString(SendBody);

Memo1.Lines.Add(RecvData);

FillChar(RecvData, sizeof(RecvData), 0);





TryAgain:



end;

---------------------------------------------------------------------------

이렇게 되어 있는데 어떻게 해야되는지 초보라 전혀 모르겠는데요/////



1  COMMENTS
  • Profile
    쩌비 2001.09.02 03:26
    내용을 보니



    하나의 송수신되는 Packet에는 _STX 지시자, _ETX 지시자가 있는것 같네요.



    그리고 전 AsyncFree Component를 사용하지 않기에 답이 될지 모르겠읍니다.



    일단 제가 쓰는 Component를 예로 할께요.



    전 Varian Async32 Components 를 사용합니다.



    _ETX 이 Packet의 마지막 온다면



    Setting 은 다음과 같아요. (참고로 제가 멀티 시리얼 제어하느라 동적 생성을 합니다.)



    m_comm := TvaComm.Create(application);

    m_comm.Databits := TvaDataBits(db8);

    m_comm.Parity := TvaParity(paNone);

    m_comm.StopBits := TvaStopBits(sb1);

    m_comm.ReadBufSize := 40960;

    m_comm.WriteBufSize := 10000;

    m_comm.WriteTimeout := 500;

    m_comm.ReadTimeout := 500;

    m_comm.MonitorEvents := [TVaCommEvent(ceData)];

    m_comm.Options := [];

    m_comm.Parity := paNone;

    m_comm.EventChars.EventChar := char($7E); <- m_comm.EventChars.EventChar = _ETX;

    m_comm.Priority := tpTimeCritical;

    m_comm.FlowControl := fcNone;

    m_comm.RTSControl := rtsDisable;

    m_comm.OnData := m_CommRxFlag;





    설정중 플로우컨트롤등 셋팅은 설정에 맞추어서 하시고. 보오드레이트등은



    외부에서 설정하게되어서 여기에는 없네요. 그리고



    버퍼Size와 Timeout은 잘못 설정하면 골치아파요 일단, 저와 같이 맞추고



    추후 조정하면 되겠지요.



    var rcvdata : array[0..4096] of byte;



    procedure TDMComm.m_CommRxFlag(Sender: TObject; Count : integer);

    var

    P : Integer;

    begin

    if m_comm.Active then

    begin

    P := m_comm.readbuf(rcvdata[0],Count);

    end;

    end;



    원래는 버퍼처리하지만 그 부분은 넣지 않았습니다.



    이정도면 프로그램이 저속(일반적으로는 무리없어요, 당사의 주업무가



    통신데이타 실시간 분석이기에 시스템 자원을 많이 사용하거든요)일경우



    무리없이 됩니다.



    고속일때는 버퍼처리 하시면 되고요.



    그리고 님의 내용을 보면 다른문제가 아니라 단지 컴포넌트 셋팅문제일 가능성이



    가장 높은것 같아요.



    m_comm.MonitorEvents := [TVaCommEvent(ceData)];

    m_comm.EventChars.EventChar := char($7E); <- m_comm.EventChars.EventChar = _ETX;



    이것은 EventChar가 들어오면 OnData이벤트를 발생시키라는 것인데..

    설정안할 수도 있고..

    또한, 위와같이 설정하였다 하여도, timeout과 buffersize가 적당하지 않아

    overflow처리할 가능성도 있습니다.



    이상 허접 답변이었습니다.





    이원택 wrote:

    > 저는 시리얼 통신을 처음하는데 핸디 터미널로 읽은 자료는2건인데 자료를 받으면

    > 컴으로 받아보면 5건이 읽혀지거든요....

    > 어떻게 해결해야 하는지...

    > 참고로 저는 Component는 AsyncFree를 이용하고요 DataReceive하는 쏘스는...

    > -----------------------------------------------------------------------------

    > procedure TForm1.AfComPort1DataRecived(Sender: TObject; Count: Integer);

    > Var

    > SendBody : Array[0..1024] of Char;

    > Offset : Integer;

    >

    > Label EndFrame;

    >

    > Label TryAgain;

    > begin

    >

    > If bStxStarted = True Then

    > Begin

    > StrPLCopy(@RecvData[StrLen(RecvData)], AfComPort1.ReadString, Count);

    > If (RecvData[StrLen(RecvData)-1] = _ETX) Then

    > Begin

    > Sleep(150);

    > goto EndFrame;

    > End

    > Else

    > Begin

    > Goto TryAgain;

    > End;

    >

    > End

    > Else If bStxStarted = False Then

    > Begin

    > i := i+1;

    > FillChar(RecvData, SizeOf(RecvData), 0);

    > StrPLCopy(@RecvData[0], AfComPort1.ReadString, Count);

    >

    > If RecvData[0] = _STX Then

    > Begin

    > bStxStarted := True;

    > goto TryAgain;

    > End;

    > End;

    >

    >

    > EndFrame:

    >

    > bStxStarted := False;

    > offset := 0;

    >

    > If(RecvData[1] = _EOT)then

    > Begin

    > FillChar(SendBody, Sizeof(SendBody), 0);

    > Offset := 0;

    > SendBody[offset] := _STX;

    > Inc(offset, 1);

    > SendBody[offset] := _ACK;

    > Inc(offset, 1);

    > SendBody[offset] := _ETX;

    > Inc(offset, 1);

    > AfComPort1.WriteString(SendBody);

    > Exit;

    > End;

    >

    > If (REcvData[1] = _ENQ)then

    > Begin

    > FillChar(sendBody, sizeof(sendBody), 0);

    > Offset := 0;

    > SendBody[offset] := _STX;

    > Inc(offset, 1);

    > SendBody[offset] := _ACK;

    > Inc(offset, 1);

    > SendBody[offset] := _ETX;

    > Inc(offset, 1);

    > AfComPort1.WriteString(SendBody);

    > exit;

    > end;

    >

    > FillChar(sendBody, sizeof(sendBody), 0);

    > offset := 0;

    > SendBody[offset] := _STX;

    > Inc(offset, 1);

    > SendBody[offset] := _ACK;

    > Inc(offset, 1);

    > SendBody[offset] := _ETX;

    > Inc(offset, 1);

    > AfComPort1.WriteString(SendBody);

    > Memo1.Lines.Add(RecvData);

    > FillChar(RecvData, sizeof(RecvData), 0);

    >

    >

    > TryAgain:

    >

    > end;

    > ---------------------------------------------------------------------------

    > 이렇게 되어 있는데 어떻게 해야되는지 초보라 전혀 모르겠는데요/////

    >