티스토리 뷰
Visual Studio 2012 사용
시리얼 통신을 해보자.
시리얼 관련 클래스를 만들고 통신 연결까지만 다뤄보도록 하자.
WINAPI 계열의 함수들을 사용할 예정이다.
Serial 통신을 하기 위해서 CreateFile() 함수를 사용한다. Serial을 하는데 파일이란 개념이 생소하긴 하지만, 리눅스나 윈도우에서는 Serial도 하나의 파일로 간주하여 관리하기 때문에 위의 함수를 사용할 수 있다. 커스텀 함수를 제외하고 사용할 함수는 CreateFile(), SetCommTimeouts(), SetCommState(), GetCommState()이다.
사용할 함수에 대해 알아보자.
1. 함수원형
(1) CreateFile() - Serial Device 핸들을 얻는다.
HANDLE CreateFileA( LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
파라미터:
lpFileName
생성할 디바이스의 이름을 입력한다. 여기서는 \\.\COM포트번호를 입력한다
* 그냥 COM을 적어도되는 경우는 COM1~9번까지만 가능하다. COM10이상 부터는 위의 형식대로 적어야 제대로 인식 된다. (참고: 마소홈피)
dwDesiredAccess
허가 요청 관련 내용이다. GENERIC_READ | GENERIC_WRITE 사용한다.
dwShareMode
공유 모드이다. 여기서는 0을 사용한다.
lpSecurityAttributes
SECURITY_ATTRIBUTES 구조체 포인터. NULL을 사용한다.
dwCreationDisposition
파일이나 디바이스가 존재 하거나 존재 하지 않을 경우에 사용하는 액션이다. 우리는 디바이스를 사용하기 때문에 OPEN_EXISTING을 사용한다.
dwFlagsAndAttributes
파일이나 디바이스의 상태나 플래그 관련 파라미터다. FILE_ATTRIBUTE_NORMAL을 사용한다.
hTemplateFile
NULL을 사용한다.
(2) SetCommTimeouts() - 디바이스의 time-out에 관련된 내용을 설정한다.
BOOL SetCommTimeouts( HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts );
파라미터:
hFile
Serial Device Handle이다.
lpCommTimeouts
COMMTIMEOUTS 구조체 포인터이다. (참고: COMMTIMEOUTS)
(3) SetCommState(), GetCommState() - DCB 구조체로 통신 상태를 설정하거나 가져온다. Baudrate 등의 통신 포트 관련 설정을 담당한다.
BOOL SetCommState( HANDLE hFile, LPDCB lpDCB );
BOOL GetCommState( HANDLE hFile, LPDCB lpDCB );
파라미터:
hFile
Serial Device Handle이다.
lpDCB
DCB 구조체 포인터이다. (참고: DCB)
2. 통신 클래스 추가(CSerialCom)
따로 상속 없이 통신 관련 클래스를 만들었다.
SerialCom.h
class CSerialCom { public: CSerialCom(void); ~CSerialCom(void); HANDLE m_hComm; //Handle of COM Port bool OpenConnection(BYTE nPort, DWORD nBaudrate, BYTE nSize, BYTE nParity, BYTE nStop); void CloseConnection(void); bool SetDCB(DWORD nBaudrate, BYTE nSize, BYTE nParity, BYTE nStop); bool SetTimeouts(void); };
SerialCom.cpp
#include "SerialCom.h" //1. 생성자 CSerialCom::CSerialCom(void) { m_hComm = NULL; } //2. 소멸자 CSerialCom::~CSerialCom(void) { CloseConnection(); } //3. 통신 연결 bool CSerialCom::OpenConnection(BYTE nPort, DWORD nBaudrate, BYTE nSize, BYTE nParity, BYTE nStop) { //이미 통신이 연결되어 있다면 통신 연결 해제 후 진행 if(m_hComm != NULL) CloseConnection(); //드라이버 핸들 생성 char szPort[15]; wsprintf(szPort, "\\\\.\\COM%d", nPort); if((m_hComm = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL)) == (HANDLE) - 1) return (false); //TIME-OUT if(!SetTimeouts()) { //Failed to set Comm Timeouts CloseHandle(m_hComm); return false; } //DCB Structure if (!SetDCB(nBaudrate, nSize, nParity, nStop)) { //Failed to set DCB Structure CloseHandle(m_hComm); return false; } return true; } //4. 통신 연결 해제 void CSerialCom::CloseConnection(void) { if(m_hComm==NULL) return; CloseHandle(m_hComm); m_hComm=NULL; } //5. DCB Structure 설정 bool CSerialCom::SetDCB(DWORD nBaudrate, BYTE nSize, BYTE nParity, BYTE nStop) { DCB dcb; dcb.DCBlength = sizeof(DCB); if(GetCommState(m_hComm, &dcb)==0) { //GetCommState Error CloseHandle(m_hComm); return false; } dcb.BaudRate = nBaudrate; dcb.ByteSize = nSize; dcb.Parity = nParity; dcb.StopBits = nStop; return (SetCommState(m_hComm, &dcb) != 0); //C4800 해결 } //6. Timeout 설정 bool CSerialCom::SetTimeouts(void) { COMMTIMEOUTS CommTimeOuts; CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier = 0; CommTimeOuts.ReadTotalTimeoutConstant = 1000; CommTimeOuts.WriteTotalTimeoutMultiplier = 0; CommTimeOuts.WriteTotalTimeoutConstant = 1000; return (SetCommTimeouts(m_hComm, &CommTimeOuts) != 0); //C4800 해결 }
(1) 생성자: 통신 드라이버 핸들을 초기화한다.
(2) 소멸자: 통신 연결 해제 함수를 사용하여 만약 연결 해제가 안되어있다면 해제 후 종료한다.
(3) 통신연결: 통신 연결을 위해 드라이버 핸들 생성, Timeout 설정, DCB Structrue 설정한다.
(4) 통신해제: 통신 드라이버 핸들을 확인하여 연결 상태 검토 후 핸들을 초기화한다.
(5) DCB, Timeout설정: 통신 연결을 위해 사용한다. 모듈화시킴.
3. 실행 클래스
MFC 대화상자 기반 프로젝트를 생성했다. (이름은 CommTest)
(1) 선언
CommTestDlg.h
#pragma once #include "SerialCom.h" // CCommTestDlg 대화 상자 class CCommTestDlg : public CDialogEx { //... public: afx_msg void OnBnClickedBtnConnect(); afx_msg void OnBnClickedBtnDisconnect(); CSerialCom *m_comm; bool m_bSerialConnected; };
연결과 연결해제 버튼을 2개 만들고, CSerialCom 클래스 포인터 변수와 연결 상태 변수를 추가하였다.
(2) 정의
CommTestDlg.cpp
// CCommTestDlg 메시지 처리기 BOOL CCommTestDlg::OnInitDialog() { //... m_bSerialConnected=false; if(m_comm==NULL) m_comm = new CSerialCom(); return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다. } void CCommTestDlg::OnBnClickedBtnConnect() { if(m_comm->OpenConnection(7,CBR_115200,8,NOPARITY,ONESTOPBIT) == true) { //Connection Success m_bSerialConnected=true; } else { //Connection Error } } void CCommTestDlg::OnBnClickedBtnDisconnect() { m_comm->CloseConnection(); m_bSerialConnected=false; }
OnInitDialog() - 각 변수들을 초기화시킨다.
OnBnClickedBtnConnect() - 통신 연결 함수, OpenConnection()함수로 통신을 연결한다.
예제에서는 COM7포트, 115200 Baudrate, 8 Bytesize, No Parity, 1 Stopbit를 사용했다.
OnBnClickedBtnDisconnect() - 통신 연결 해제 함수
소스: CommTest .zip
끝
'Programming > MFC(C++)' 카테고리의 다른 글
[MFC] 다이얼로그(대화상자) 배경화면 바꾸기 (0) | 2019.10.14 |
---|---|
[MFC] 로또 번호 뽑아보자(rand()활용) (0) | 2019.01.23 |
[MFC] 이벤트를 사용해보자 CreateEvent, SetEvent, ResetEvent (0) | 2019.01.03 |
[MFC] Performance Counter를 사용하여 코드 속도 측정하기 (0) | 2018.12.31 |
[MFC] ON_CONTROL_RANGE 사용하기(하나의 함수로 여러 컨트롤 제어) (0) | 2018.12.19 |
- Total
- Today
- Yesterday
- 모달리스
- 스쿠트항공 환불받기
- CMFCBUTTON
- Modeless
- 전자신고변환
- 청년내일채움공제
- c++
- ADODB
- 부가가치세
- 전자신고파일설명서
- sqlite3
- MFC
- 소켓
- Sticky Notes Loading
- 법정동코드
- MXCOMPONENT
- MSSQL
- 모달리스 다이얼로그
- 항공알파벳
- 해외송금확인
- 스티커메모로드중
- 청년내일채움공제 만기신청
- 부가가치세전산매체
- MFC Modeless
- MFC ADO
- #자동업데이트
- SendMessage
- ADO
- 프로세스이름변경
- 세금계산서합계표양식
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |