none
MFC 시리얼 통신에 대해 질문... RRS feed

  • 질문

  • 안녕하세요 MFC 입문자입니다. 
    시리얼 통신 프로그램을 한번 짜 보는게 도움이 많이 된다하여 해보는 중인데 어렵네요...
    데이터를 보내는것 까진 되는거같은데 
    받는 동작이 되지도 않고 확인하는 방법도 잘 모르겠습니다.
    통신 클래스
    // 시리얼 포트 오픈 함수

    bool CSerialComm::OpenPort(HWND hWnd)
    {
    // 윈도우 핸들 사용, 클래스 객체를 사용하는 클래스에 메시지를 전달하기 위하여 클래스의 핸들을 인자로 받음
    m_hWnd = hWnd;

      //////////////////////////////////////////////////////////////////////////////////////////
      //   CreateFile() 함수
      //
      //  HANDLE CreateFile(
      //     LPCTSTR lpFileName,                         : 생성 또는 오픈할 파일의 경로와 파일이름
      // DWORD dwDesiredAccess,                      : 파일접근모드
      // DWORD dwShareMode,                          : 파일을 공유할지의 여부를 결정하는 플래그, 0이면 공유안함
      // LPSECURITY_ATTRIBUTE lpSecurityAttributes,  : 보안속성을 지정하는 인수, 주로 NULL
      // DWORD dwCreationDispostion,                 : 파일 존재에 따른 행동설정
      // DWORD dwFlagsAndAttributes,                 : 파일의 속성 설정
      // HANDLE hTemplateFile );                     : 생성된 파일에 대한 속성을 제공하는 템플릿, 주로 NULL
      ////////////////////////////////////////////////////////////////////////////////////////


    m_hComm = CreateFile(m_sComPort, GENERIC_READ | GENERIC_WRITE, 0,
                        NULL, OPEN_EXISTING, 0, NULL);


    if(m_hComm != INVALID_HANDLE_VALUE) 
            //INVALID_HANDLE_VALUE : 초기화를 위한 목적과 유효값 판단, 보통 -1로 정의되며 CreatFile()의 반환값으로 사용됨.
    m_sPortOpenned =TRUE;
    else
    return false;

    SetSerial();

    return true;
    }


    // 데이터 송신 함수
    bool CSerialComm::Send(LPCTSTR WrittenBufData, int len)
    {
    DWORD BytesWritten;
      //////////////////////////////////////////////////////////////////////////////////////////
      //   WriteFile() 함수
      //
      //  HANDLE WriteFile(
      // HANDLE hFile,                    : 파일이나 I/O 디바이스의 핸들
      //     LPCVOID lpBuffer,                : 파일이나 디바이스에 쓸 데이터를 포함하는 버퍼의 포인터
      //     DWORD nNumberOfBytesToWrite,     : 파일이나 디바이스에 쓸 바이트의 수
      //     LPDWORD lpNumberOfBytesWritten,  : hFile 파라미터가 사용한 바이트의 수를 받을 변수의 포인터
      //        LPOVERLAPPED lpOverlapped        : 비동기입출력 사용시 OVERLAPPED 구조체의 포인터, 사용하지않을시 NULL
      ////////////////////////////////////////////////////////////////////////////////////////
    if (WriteFile(m_hComm, WrittenBufData, len, &BytesWritten, NULL) !=0)
    return true;
    else
    return false;
    }
    // 데이터 수신 함수
    bool CSerialComm::Receive(LPSTR ReadBufData, int len)
    {
    DWORD BytesRead;
    LPVOID lpData;
    CSerialComm* Comm = (CSerialComm*)lpData;
    LPARAM temp = (LPARAM)Comm;
      //////////////////////////////////////////////////////////////////////////////////////////
      //   ReadFile() 함수
      //
      //  HANDLE WriteFile(
      // HANDLE hFile,                    : 파일이나 I/O 디바이스의 핸들
      //     LPCVOID lpBuffer,                : 파일이나 디바이스로부터 읽은 데이터를 받을 버퍼의 포인터
      //     DWORD nNumberOfBytesToRead,      : 읽을 데이터의 최대 바이트의 수
      //     LPDWORD lpNumberOfBytesRead,     : hFile 파라미터가 읽은 바이트의 수를 받을 변수의 포인터
      //        LPOVERLAPPED lpOverlapped        : 비동기입출력 사용시 OVERLAPPED 구조체의 포인터, 사용하지않을시 NULL
      ////////////////////////////////////////////////////////////////////////////////////////
    if (m_sPortOpenned==true) 
    {
    SendMessage(m_hWnd,WM_MYRECEIVE,BytesRead,temp);
    if (ReadFile(m_hComm, &ReadBufData, len, &BytesRead, NULL) != 0)
    return true;
    else
    return false;
    }
    else
    return false;
    }
    대화상자
    BEGIN_MESSAGE_MAP(CSerialDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    //}}AFX_MSG_MAP
    ON_CBN_SELCHANGE(IDC_SETCOMPORT, &CSerialDlg::OnCbnSelchangeSetcomport)
    ON_EN_CHANGE(IDC_EDITVIEWDATA, &CSerialDlg::OnEnChangeEditviewdata)
    ON_BN_CLICKED(IDC_OPENPORT, &CSerialDlg::OnBnClickedOpenport)
    ON_BN_CLICKED(IDC_CLEAR, &CSerialDlg::OnBnClickedClear)
    ON_BN_CLICKED(IDC_SENDDATA, &CSerialDlg::OnBnClickedSenddata)
    ON_CBN_SELCHANGE(IDC_SETBAUDRATE, &CSerialDlg::OnCbnSelchangeSetbaudrate)
    ON_EN_CHANGE(IDC_EDIT_SENDDATA, &CSerialDlg::OnEnChangeEditSenddata)
    ON_MESSAGE(WM_MYRECEIVE, &CSerialDlg::OnReceive)
    END_MESSAGE_MAP()
    // 포트 오픈
    void CSerialDlg::OnBnClickedOpenport()
    {
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    if(Comport1_State)
    {
    if(m_Comm)
    {
    m_Comm ->Close();
    m_Comm = NULL;
    AfxMessageBox(_T("COM 포트 닫힘"));
    Comport1_State = false;
    GetDlgItem(IDC_OPENPORT)->SetWindowText(_T("OPEN"));
    //GetDlgItem(IDC_OPENPORT)->EnableWindow(true);
    GetDlgItem(IDC_SENDDATA)->EnableWindow(false);
    }
    }
    else
    {
    m_Comm = new CSerialComm(_T("\\\\.\\")+m_strSetComPort, m_strSetBaudRate, _T("NONE"), _T("8 Bit"), _T("1 Bit"));
    if (m_Comm->OpenPort(GetSafeHwnd()) !=0)
    {
    AfxMessageBox(_T("COM 포트 열림"));
    Comport1_State=true;
    GetDlgItem(IDC_OPENPORT)->SetWindowText(_T("CLOSE"));
    //GetDlgItem(IDC_OPENPORT)->EnableWindow(false);
    GetDlgItem(IDC_SENDDATA)->EnableWindow(true);
    }
    else
    {
    AfxMessageBox(_T("ERROR"));
    }
    }
    }
    //송신
    void CSerialDlg::OnBnClickedSenddata()
    {
    // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
    CString str;
    if(Comport1_State == true)
    {
    GetDlgItem(IDC_EDIT_SENDDATA) -> GetWindowText(str);
    str += "\r\n";
    m_Comm->Send(str,str.GetLength());
    AfxMessageBox(_T("성공"));
    }
    else
    {
    AfxMessageBox(_T("ERROR"));
    }
    }
    // 수신
    LRESULT CSerialDlg::OnReceive(WPARAM length, LPARAM lpara)
    {
    CString str;
    char data[20000];
    if(m_Comm)
    {
    m_Comm->Receive(data,length);
    data[length]=_T('\0');
    str+=_T("\r\n");
    AfxMessageBox(_T("123"));
    for(int i=0; i<(int)length; i++)
    {
    str+=data[i];
    }
    m_EditViewData.ReplaceSel(str);
    str="";
    }
    return 0;
    }
    수신 함수쪽에 브레이크를 걸어놓고 디버깅 해보면 걸리지가 않네요...
    어떤게 문제일까요...
    2018년 5월 10일 목요일 오전 5:47

모든 응답