BASIC4MCU | 질문게시판 | mfc 코드 질문
페이지 정보
작성자 stevie8 작성일2023-08-09 11:02 조회293회 댓글4건본문
안녕하세요 제가 매트릭스 키패드를 버튼 누른거마다 mfc 앱 edit box에 출력하려고 하는데요
#include "stdafx.h"
#include "Mycomm.h"
CMycomm::CMycomm()
{
}
CMycomm::~CMycomm()
{
if (m_bIsOpenned)
Close();
delete m_pEvent;
}
CMycomm::CMycomm(CString port, CString baudrate, CString parity, CString databit, CString stopbit)
{
m_sComPort = port;
m_sBaudRate = baudrate;
m_sParity = parity;
m_sDataBit = databit;
m_sStopBit = stopbit;
m_bFlowChk = 1;
m_bIsOpenned = FALSE;
m_nLength = 0;
memset(m_sInBuf, 0, MAXBUF * 2);
m_pEvent = new CEvent(FALSE, TRUE);
}
// CMycomm message handlers
void CMycomm::ResetSerial()
{
DCB dcb;
DWORD DErr;
COMMTIMEOUTS CommTimeOuts;
if (!m_bIsOpenned)
return;
ClearCommError(m_hComDev, &DErr, NULL);
SetupComm(m_hComDev, InBufSize, OutBufSize);
PurgeComm(m_hComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
// set up for overlapped I/O
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
// CBR_9600 is approximately 1byte/ms. For our purposes, allow
// double the expected time per character for a fudge factor.
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 1000;
SetCommTimeouts(m_hComDev, &CommTimeOuts);
memset(&dcb, 0, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
GetCommState(m_hComDev, &dcb);
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
if (m_sBaudRate == "300")
dcb.BaudRate = CBR_300;
else if (m_sBaudRate == "600")
dcb.BaudRate = CBR_600;
else if (m_sBaudRate == "1200")
dcb.BaudRate = CBR_1200;
else if (m_sBaudRate == "2400")
dcb.BaudRate = CBR_2400;
else if (m_sBaudRate == "4800")
dcb.BaudRate = CBR_4800;
else if (m_sBaudRate == "9600")
dcb.BaudRate = CBR_9600;
else if (m_sBaudRate == "14400")
dcb.BaudRate = CBR_14400;
else if (m_sBaudRate == "19200")
dcb.BaudRate = CBR_19200;
else if (m_sBaudRate == "28800")
dcb.BaudRate = CBR_38400;
else if (m_sBaudRate == "33600")
dcb.BaudRate = CBR_38400;
else if (m_sBaudRate == "38400")
dcb.BaudRate = CBR_38400;
else if (m_sBaudRate == "56000")
dcb.BaudRate = CBR_56000;
else if (m_sBaudRate == "57600")
dcb.BaudRate = CBR_57600;
else if (m_sBaudRate == "115200")
dcb.BaudRate = CBR_115200;
else if (m_sBaudRate == "128000")
dcb.BaudRate = CBR_128000;
else if (m_sBaudRate == "256000")
dcb.BaudRate = CBR_256000;
else if (m_sBaudRate == "PCI_9600")
dcb.BaudRate = 1075;
else if (m_sBaudRate == "PCI_19200")
dcb.BaudRate = 2212;
else if (m_sBaudRate == "PCI_38400")
dcb.BaudRate = 4300;
else if (m_sBaudRate == "PCI_57600")
dcb.BaudRate = 6450;
else if (m_sBaudRate == "PCI_500K")
dcb.BaudRate = 56000;
if (m_sParity == "None")
dcb.Parity = NOPARITY;
else if (m_sParity == "Even")
dcb.Parity = EVENPARITY;
else if (m_sParity == "Odd")
dcb.Parity = ODDPARITY;
if (m_sDataBit == "7 Bit")
dcb.ByteSize = 7;
else if (m_sDataBit == "8 Bit")
dcb.ByteSize = 8;
if (m_sStopBit == "1 Bit")
dcb.StopBits = ONESTOPBIT;
else if (m_sStopBit == "1.5 Bit")
dcb.StopBits = ONE5STOPBITS;
else if (m_sStopBit == "2 Bit")
dcb.StopBits = TWOSTOPBITS;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fOutxDsrFlow = FALSE;
if (m_bFlowChk) {
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.XonLim = 2048;
dcb.XoffLim = 1024;
}
else {
dcb.fOutxCtsFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
}
SetCommState(m_hComDev, &dcb);
SetCommMask(m_hComDev, EV_RXCHAR);
}
void CMycomm::Close()
{
if (!m_bIsOpenned)
return;
m_bIsOpenned = FALSE;
SetCommMask(m_hComDev, 0);
EscapeCommFunction(m_hComDev, CLRDTR);
PurgeComm(m_hComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
Sleep(500);
}
UINT CommThread(LPVOID lpData)
{
extern short g_nRemoteStatus;
DWORD ErrorFlags;
COMSTAT ComStat;
DWORD EvtMask;
char buf[MAXBUF];
DWORD Length;
int size;
int insize = 0;
// 통신클래스의 객체포인터를 얻음
CMycomm* Comm = (CMycomm*)lpData;
// 통신포트가 열려 있다면
while (Comm->m_bIsOpenned)
{
EvtMask = 0;
Length = 0;
insize = 0;
memset(buf, '\0', MAXBUF);
// 이벤트를 기다림
WaitCommEvent(Comm->m_hComDev, &EvtMask, NULL);
ClearCommError(Comm->m_hComDev, &ErrorFlags, &ComStat);
// EV_RXCHAR에서 이벤트가 발생하면
if ((EvtMask & EV_RXCHAR) && ComStat.cbInQue)
{
if (ComStat.cbInQue > MAXBUF)
size = MAXBUF;
else
size = ComStat.cbInQue;
do
{
ClearCommError(Comm->m_hComDev, &ErrorFlags, &ComStat);
// overlapped I/O를 통해 데이터를 읽음
if (!ReadFile(Comm->m_hComDev, buf + insize, size, &Length, &(Comm->m_OLR)))
{
// 에러
TRACE("Error in ReadFile\n");
if (GetLastError() == ERROR_IO_PENDING)
{
if (WaitForSingleObject(Comm->m_OLR.hEvent, 1000) != WAIT_OBJECT_0)
Length = 0;
else
GetOverlappedResult(Comm->m_hComDev, &(Comm->m_OLR), &Length, FALSE);
}
else
Length = 0;
}
insize += Length;
} while ((Length != 0) && (insize < size));
ClearCommError(Comm->m_hComDev, &ErrorFlags, &ComStat);
if (Comm->m_nLength + insize > MAXBUF * 2)
insize = (Comm->m_nLength + insize) - MAXBUF * 2;
// 이벤트 발생을 잠시 중단하고 input buffer에 데이터를 복사
Comm->m_pEvent->ResetEvent();
memcpy(Comm->m_sInBuf + Comm->m_nLength, buf, insize);
Comm->m_nLength += insize;
// 복사가 끝나면 다시 이벤트를 활성화 시키고
Comm->m_pEvent->SetEvent();
LPARAM temp = (LPARAM)Comm;
// 데이터가 들어왔다는 메시지를 발생
SendMessage(Comm->m_hWnd, WM_MYRECEIVE, Comm->m_nLength, temp);
}
}
PurgeComm(Comm->m_hComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
LPARAM temp = (LPARAM)Comm;
SendMessage(Comm->m_hWnd, WM_MYCLOSE, 0, temp);
return 0;
}
void CMycomm::HandleClose()
{
CloseHandle(m_hComDev);
CloseHandle(m_OLR.hEvent);
CloseHandle(m_OLW.hEvent);
}
BOOL CMycomm::Create(HWND hWnd)
{
m_hWnd = hWnd;
m_hComDev = CreateFile(m_sComPort, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (m_hComDev != INVALID_HANDLE_VALUE)
m_bIsOpenned = TRUE;
else
return FALSE;
ResetSerial();
m_OLW.Offset = 0;
m_OLW.OffsetHigh = 0;
m_OLR.Offset = 0;
m_OLR.OffsetHigh = 0;
m_OLR.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_OLR.hEvent == NULL) {
CloseHandle(m_OLR.hEvent);
return FALSE;
}
m_OLW.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (m_OLW.hEvent == NULL) {
CloseHandle(m_OLW.hEvent);
return FALSE;
}
AfxBeginThread(CommThread, (LPVOID)this);
EscapeCommFunction(m_hComDev, SETDTR);
return TRUE;
}
BOOL CMycomm::Send(LPCTSTR outbuf, int len)
{
BOOL bRet = TRUE;
DWORD ErrorFlags;
COMSTAT ComStat;
DWORD BytesWritten;
DWORD BytesSent = 0;
ClearCommError(m_hComDev, &ErrorFlags, &ComStat);
if (!WriteFile(m_hComDev, outbuf, len, &BytesWritten, &m_OLW))
{
if (GetLastError() == ERROR_IO_PENDING)
{
if (WaitForSingleObject(m_OLW.hEvent, 1000) != WAIT_OBJECT_0)
bRet = FALSE;
else
GetOverlappedResult(m_hComDev, &m_OLW, &BytesWritten, FALSE);
}
else /* I/O error */
bRet = FALSE; /* ignore error */
}
ClearCommError(m_hComDev, &ErrorFlags, &ComStat);
return bRet;
}
int CMycomm::Receive(LPSTR inbuf, int len)
{
CSingleLock lockObj((CSyncObject*)m_pEvent, FALSE);
// argument value is not valid
if (len == 0)
return -1;
else if (len > MAXBUF)
return -1;
if (m_nLength == 0)
{
inbuf[0] = '\0';
return 0;
}
// 정상적이라면 본루틴으로 들어와 실제 들어온 데이터의 길이 만큼 Input Buffer에서 데이터를 읽음
else if (m_nLength <= len)
{
lockObj.Lock();
memcpy(inbuf, m_sInBuf, m_nLength);
memset(m_sInBuf, 0, MAXBUF * 2);
int tmp = m_nLength;
m_nLength = 0;
lockObj.Unlock();
return tmp;
}
else
{
lockObj.Lock();
memcpy(inbuf, m_sInBuf, len);
memmove(m_sInBuf, m_sInBuf + len, MAXBUF * 2 - len);
m_nLength -= len;
lockObj.Unlock();
return len;
}
}
void CMycomm::Clear()
{
PurgeComm(m_hComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
memset(m_sInBuf, 0, MAXBUF * 2);
m_nLength = 0;
}
uart 통신 예제코드를 따와서 만들었는데..
SendMessage(Comm->m_hWnd, WM_MYRECEIVE, Comm->m_nLength, temp);
이부분에서 윈도우창으로 메세지를 띄운다는 말인것 같은데 buf에 제 키패드 값은 잘 담기는데 왜 윈도우창이 안 뜰까요
아니면 제가 edit box에 buf에 담긴 키패드 값을 출력하고 싶은데 (Comm-> m_hWnd) 이부분을 (Comm-> 제가 설정한 에딧박스 변수)로 바꾸면 될까요?
댓글 4
조회수 293master님의 댓글
master 작성일
edit box는 주로 입력 받을 때 사용하는 컴포넌트고
label을 사용하지 않나요?
stevie8님의 댓글
stevie8
아하 제가 완전 초보라서 잘 몰랐네요 그런데 그 부분은 코드와 상관 없지 않나요? 바꿔줘야 하나요?
master님의 댓글
master
void CCAMCFS20Dlg::SetDlgItemDouble(int nID, double value)
{
CString sTemp;
sTemp.Format("%.3f", value);
GetDlgItem(nID)->SetWindowText(sTemp);
}
http://dblab.co.kr/entry/CMFC-ETC-%EB%AA%A8%EC%9D%8C
기본 예제들을 충분히 공부한 후에 원하는대로 만들어보세요
stevie8님의 댓글
stevie8
감사합니다!! 어떻게 해결 했네요 트래픽 초과로 접속은 불가하지만 나중에 접속 해볼게요 감사합니다