www.gusucode.com > VC++多线程的串口通讯实例源码程序 > VC++多线程的串口通讯实例源码程序/code/mscomabc/CMscom.cpp
// CMscom.cpp: implementation of the CCMscom class. // Download by http://www.NewXing.com ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "mscomabc.h" #include "CMscom.h" //#include "Fabc.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CCMscom::CCMscom() { } CCMscom::~CCMscom() { //程序结束时删除线程、关闭串口的操作 if(m_bConnected) CloseConnection(); // 删除事件句柄 if(m_hPostMsgEvent) CloseHandle(m_hPostMsgEvent); if(m_osRead.hEvent) CloseHandle(m_osRead.hEvent); if(m_osWrite.hEvent) CloseHandle(m_osWrite.hEvent); } BOOL CCMscom::OpenConnection(int port)//打开串口 { COMMTIMEOUTS timeout; BOOL b_r; if(!m_bConnected) { if(port!=0 && port!=1) { return FALSE; } m_sPort=port; timeout.ReadIntervalTimeout=500;//1 timeout.ReadTotalTimeoutConstant=0;//500 timeout.ReadTotalTimeoutMultiplier=0;//2 timeout.WriteTotalTimeoutConstant=0;//0 timeout.WriteTotalTimeoutMultiplier=500;//0 if(port==0) m_hCom=CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); // 重叠方式 else m_hCom=CreateFile("COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); // 重叠方式 if(m_hCom) { DCB dcb; b_r=GetCommState(m_hCom,&dcb); if(b_r==FALSE) { CloseHandle(m_hCom); return FALSE; } //9600 b_r=BuildCommDCB("baud=115200 parity=N data=8 stop=1",&dcb); if(b_r==FALSE) { CloseHandle(m_hCom); return FALSE; } b_r=SetCommState(m_hCom,&dcb); if(b_r==FALSE) { CloseHandle(m_hCom); return FALSE; } b_r=SetCommTimeouts(m_hCom,&timeout); if(b_r==FALSE) { CloseHandle(m_hCom); return FALSE; } m_bConnected = TRUE; } else { // CGError::DispMsg(ER_OPEN_PORT); return FALSE; } } else { if(port!=m_sPort) { // CGError::DispMsg(ER_IO_PORT); return FALSE; } } //-------------------------------------------------- // pNewObject = new CMyObject; // AfxBeginThread(CommProc, pNewObject); m_pThread=AfxBeginThread(CommProc, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL); // 创建并挂起线程 //m_pThread=AfxBeginThread(CommProc,this,0,0,NULL);//???????? if(m_pThread==NULL) { CloseHandle(m_hCom); return FALSE; } else { m_bConnected=TRUE; m_pThread->ResumeThread(); // 恢复线程运行 } return TRUE; } //--------------------------------------------------------- void CCMscom::CloseConnection() { if(!m_bConnected) return; m_bConnected=FALSE; //结束CommProc线程中WaitSingleObject函数的等待 SetEvent(m_hPostMsgEvent); //结束CommProc线程中WaitCommEvent的等待 SetCommMask(m_hCom, 0); //等待辅助线程终止 WaitForSingleObject(m_pThread->m_hThread, INFINITE); m_pThread=NULL; CloseHandle(m_hCom); } /* BOOL CCMscom::ConfigConnection()//-----连接设置无用 { DCB dcb; if(!GetCommState(m_hCom, &dcb)) return FALSE; dcb.BaudRate=9600; dcb.ByteSize=8; dcb.StopBits=1; dcb.Parity=0; dcb.fBinary=true; SetCommState(m_hCom,&dcb); //-------------------------------- 硬件流控制设置 dcb.fOutxCtsFlow = TRUE; dcb.fRtsControl = TRUE; // XON/XOFF流控制设置 dcb.fInX=dcb.fOutX = TRUE; dcb.XonChar = XON; dcb.XoffChar = XOFF; dcb.XonLim = 50; dcb.XoffLim = 50; return SetCommState(m_hCom, &dcb); } */ DWORD CCMscom::ReadComm(char *buf,DWORD dwLength) { DWORD length=0; COMSTAT ComStat; DWORD dwErrorFlags; ClearCommError(m_hCom,&dwErrorFlags,&ComStat); length=min(dwLength, ComStat.cbInQue); ReadFile(m_hCom,buf,length,&length,&m_osRead); // AfxMessageBox("收到"); dwLength=length; return dwLength; } DWORD CCMscom::WriteComm(char *buf,DWORD dwLength) { BOOL fState; DWORD length; COMSTAT ComStat; DWORD dwErrorFlags; length=dwLength; ClearCommError(m_hCom,&dwErrorFlags,&ComStat); fState=WriteFile(m_hCom,buf,length,&length,&m_osWrite); if(!fState) { if(GetLastError()==ERROR_IO_PENDING) { GetOverlappedResult(m_hCom,&m_osWrite,&length,TRUE);// 等待 } else length=0; } return length; } BOOL CCMscom::OnNewDocument()//???? { if (!CCMscom::OnNewDocument()) return FALSE; // 为WM_COMMNOTIFY消息创建事件对象,手工重置,初始化为有信号的 if((m_hPostMsgEvent=CreateEvent(NULL, TRUE, TRUE, NULL))==NULL) return FALSE; memset(&m_osRead, 0, sizeof(OVERLAPPED)); memset(&m_osWrite, 0, sizeof(OVERLAPPED)); // 为重叠 读 创建事件对象,手工重置,初始化为无信号的 if((m_osRead.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL) return FALSE; // 为重叠 写 创建事件对象,手工重置,初始化为无信号的 if((m_osWrite.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL))==NULL) return FALSE; return TRUE; } // -----------工作者线程,负责监视串行口--------------- UINT CommProc(LPVOID pParam)//222 { OVERLAPPED os; DWORD dwMask, dwTrans; COMSTAT ComStat; DWORD dwErrorFlags; CCMscom *pDoc=(CCMscom*)pParam; memset(&os, 0, sizeof(OVERLAPPED)); os.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL); if(os.hEvent==NULL) { AfxMessageBox("Can't create event object!"); return (UINT)-1; } while(pDoc->m_bConnected) { ClearCommError(pDoc->m_hCom,&dwErrorFlags,&ComStat); if(ComStat.cbInQue) { // 无限等待WM_COMMNOTIFY消息被处理完 WaitForSingleObject(pDoc->m_hPostMsgEvent, INFINITE); ResetEvent(pDoc->m_hPostMsgEvent); // 通知视图 // PostMessage(pDoc->m_hTermWnd, WM_COMMNOTIFY, EV_RXCHAR, 0); continue; } dwMask=0; if(!WaitCommEvent(pDoc->m_hCom, &dwMask, &os)) // 重叠操作 { if(GetLastError()==ERROR_IO_PENDING) { // ---------------------------------无限等待重叠操作结果 GetOverlappedResult(pDoc->m_hCom, &os, &dwTrans, TRUE); } else { CloseHandle(os.hEvent); return (UINT)-1; } } AfxMessageBox("122"); } CloseHandle(os.hEvent); return 0; }