본문 바로가기

Windows/MFC

data transfer by serial

음.. 소스에서 보시면..



void CMy2Dlg::OnSendPacket()

요 함수 안에서...



     WriteDisplayEditBox();    

요걸 사용하시는걸 볼 수 있습니다..



현재 디스플레이된 에디트 박스의 내용을 써~라... -0-''' 라는 정도로 해석되는군요..^^;;



그래서...

void CMy2Dlg::WriteDisplayEditBox()

함수 안으로 살펴 들어가면...

(거기에..

GetDlgItemText(

GetDlgItemText(IDC_SEND_EDIT, m_SendString);



요 부분은 에러인거 아시죠?? )



if(m_bIsHexa)

{

     if(nToSend%2)

     {

         m_missInput.LoadString(IDS_NUM_HEXA);

         MessageBox(m_missInput,NULL,MB_OK);

         return ;

     }

     if(MakeHaxa( pBuff , nToSend))

         m_Port.WriteComm( pBuff , nToSend/2 );

}

else

     m_Port.WriteComm( (BYTE*)(LPCTSTR)m_SendString , nToSend );





요 부분이 보입니다...



거기에서.. m_Port.WriteComm 부분이.. 포트로 쓰는 함수이고..



다시.. WriteComm 함수 부분을 추적해 가보면..



DWORD CSerialPort::WriteComm(BYTE *pBuff, DWORD nToWrite)



요기까쥐..갈 수 있습니다.



이 함수 내부의



...



n = WriteFile(m_hComm, pBuff, nToWrite, &dwWritten,&m_ovrWrite);

이 부분에서.. 실제 출력을 내 보내게 됩니다.



WriteFile 에서 말이죠...........



그런데, 이 순간.. 바로.. 나가는 것은 아닙니다.



이러한 함수 출력을 응용 프로그램에서 하면...

OS는 Serial 포트의 인터럽트 처리 루틴에.. 처리해 달라는 요청을 하게 됩니다.

UART 전용 칩이 M'B에 내장되어 있으니.. 이 칩이 하드웨어 처리를 담당하겠군요..



Serial Port 출력 요청이 있으면.. 인터럽트 서비스 루틴은 그 출력 결과를 내보내게 됩니다.



예전(Win95까지)에는..처리 루틴을 직접적으로 핸들링 할 수 있었는데..

그 이후부터는 OS를 통한 서비스 요청...처리로 그 작업이 진행되어 가는걸로 알고 있습니다.



실제로, 응용 프로그램에서는 처리해달라..라는 요청이 전부인셈이죠...



그것도, 처리 담당 부서가 아니라..

관리자인.. OS를 통해서..말이죠...



때때로.. 시스템 부하(?)가 있을때면..

보낸 출력 타이밍과 실제 출력 시간은 차이가 생기기도 합니다...



그래서, 응용프로그램의 출력에서.. WriteFile 에서.. 출력 했다고 응답이 와도...

이 응답은.. OS 가 자신이 말을 들었다고 하는 정도 입니다.



RF 통신에서 보면..

송/수신 전환 신호로.. RTS 신호선을 사용하기도 합니다.



그런데, RTS 신호선을 ON 시키고... 데이터를 보내고..

데이터 출력이 끝나면.. RTS 신호선을 OFF 시키는 수순을 밟아야 하는데...



데이터 출력이 끝났다고.. WriteFile 에서.. 값을 받아서.. RTS 신호선을 Off 시키면... 데이터가 제대로 전달되지 못하는 경우가 발생되게 됩니다.



따라서, 실제적인 포트의 출력 타이밍을 알아야 할 필요가 있는데..



이럴 경우에 사용되는 것이..



EV_TXEMPTY 라는 이벤트 입니다.

EV_TXEMPTY 라는 이벤트는 송신 버퍼가 비었을 때 발생되는 이벤트 입니다.. 실제 출력이 끝나서.. 버퍼 비었음.. 이라고 해 주는 것이죠..



물론, 시리얼 이벤트 마스크 시켜줄 때.. 이것또한 마스크 처리 해줘야 하는 것이죠..



//--> 이벤트 마스크..

if( !SetCommMask( pComm->m_hComm, (EV_RXCHAR | EV_TXEMPTY) ) )



이런식으로.. EV_RXCHAR : 데이터 수신 이벤트

                 EV_TXEMPTY : 송신버퍼 비었음... 두개의 이벤트를 마스크 시켜준후..에..





포트를 감시하는 쓰레드 에서...



// 포트를 감시하는 루프.

while( pComm->m_bConnected )

{

        dwEvent = 0;



        // 포트에 읽을 거리가 올때까지 기다린다.

        WaitCommEvent( pComm->m_hComm, &dwEvent, NULL);



        //---> 송신 끝나면.. RTS CLEAR

        if( (dwEvent & EV_TXEMPTY) == EV_TXEMPTY )

        {

            //---> RTS 를 항상 켜 놓을것이 아니면..

            if( !pComm->m__bRTSOffNo )

            {



                EscapeCommFunction( pComm->m_hComm, CLRRTS );

            

                Sleep( pComm->m__nRtsOffDelay );



            }



        }

        



        //--> 데이터가 수신되었다는 메세지가 발생하면..

        if ((dwEvent & EV_RXCHAR) == EV_RXCHAR)

        {



이런식으로 처리를 하는 것입니다.



보통 유선에서는 별로 사용되지 않고.. RF 에서 송/수신 제어를 직접적으로 하고자 할 때 사용하는 방식입니다.



...........................................................................

질문의 의도가 정확히 판단되지 않아서... 주저리~ 길게 썼습니다.



참고 하시길...!--



굴~~개...굴~~개...



'Windows > MFC' 카테고리의 다른 글

xmodem  (0) 2013.10.02
zmodem  (0) 2013.10.02
Windbg  (0) 2013.10.02
Ultimate Toolbox Open source  (0) 2013.10.02
mysql connect  (0) 2013.10.02