实例介绍
【实例简介】
【实例截图】
【实例截图】
【核心代码】
#include "StdAfx.h" #include "SerialComm.h" CSerialComm::CSerialComm(void) { m_recvData = ""; m_bConnected = FALSE; m_pThread = NULL; } CSerialComm::~CSerialComm(void) { 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 CSerialComm::openConnection(CString commno, UINT8 baud, UINT8 datalen, UINT8 stopbit, UINT8 parity) { if((baud > COMM_BAUD_115200) || (datalen > COMM_DATA_LEN_8) || (stopbit > COMM_STOP_BIT_2) || (parity > COMM_SPACE_PARITY)) { m_bConnected = FALSE; AfxMessageBox(_T("串口参数设置错误")); return FALSE; } m_hPostMsgEvent = CreateEvent(NULL, TRUE, TRUE, NULL); if(m_hPostMsgEvent == NULL) return FALSE; memset(&m_osRead, 0, sizeof(OVERLAPPED)); memset(&m_osWrite, 0, sizeof(OVERLAPPED)); m_osRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //为重叠读创建事件对象,手工重置,初始化为无信号 if(m_osRead.hEvent == NULL) return FALSE; m_osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //为重叠写创建事件对象,手工重置,初始化为无信号 if(m_osWrite.hEvent == NULL) return FALSE; m_hComm = CreateFile(commno, //打开串口 GENERIC_READ | GENERIC_WRITE, //允许对设备进行读写访问 0, //独占方式 NULL, // OPEN_EXISTING, //打开而不是创建 FILE_FLAG_OVERLAPPED, //使用异步通信 NULL); if(m_hComm == (HANDLE)-1) { m_bConnected = FALSE; AfxMessageBox(_T("打开串口失败")); return FALSE; } else { SetupComm(m_hComm, MAXBLOCK, MAXBLOCK); //输入缓冲区和输出缓冲区的大小都是1024 SetCommMask(m_hComm, EV_RXCHAR | EV_TXEMPTY ); //设置事件驱动的类型 COMMTIMEOUTS TimeOuts; TimeOuts.ReadIntervalTimeout = MAXDWORD; //时间间隔设为最大,设为0会导致ReadFile立即返回并完成操作 TimeOuts.ReadTotalTimeoutMultiplier = 0; TimeOuts.ReadTotalTimeoutConstant = 0; TimeOuts.WriteTotalTimeoutMultiplier = 50; //设置写超时用于GetOverlapperResult函数的等待时间 TimeOuts.WriteTotalTimeoutConstant = 2000; SetCommTimeouts(m_hComm, &TimeOuts); //设置超时 //PurgeComm(m_hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); //清干净输入、输出缓冲区 if(!configureConnection(commno, baud, datalen, stopbit, parity)) { CloseHandle(m_hComm); return FALSE; } return TRUE; } } BOOL CSerialComm::configureConnection(CString commno, UINT8 baud, UINT8 datalen, UINT8 stopbit, UINT8 parity) { DCB dcb; if(!GetCommState(m_hComm, &dcb)) //读串口原来的参数设置 return false; switch(baud) //波特率 { case COMM_BAUD_2400: dcb.BaudRate = 2400; break; case COMM_BAUD_4800: dcb.BaudRate = 4800; break; case COMM_BAUD_9600: dcb.BaudRate = 9600; break; case COMM_BAUD_19200: dcb.BaudRate = 19200; break; case COMM_BAUD_38400: dcb.BaudRate = 38400; break; case COMM_BAUD_115200: dcb.BaudRate = 115200; break; default: break; } switch(datalen) //字节数 { case COMM_DATA_LEN_5: dcb.ByteSize = 5; break; case COMM_DATA_LEN_6: dcb.ByteSize = 6; break; case COMM_DATA_LEN_7: dcb.ByteSize = 7; break; case COMM_DATA_LEN_8: dcb.ByteSize = 8; break; default: break; } switch(stopbit) //停止位 { case COMM_STOP_BIT_1: dcb.StopBits = ONESTOPBIT; break; case COMM_STOP_BIT_1_5: dcb.StopBits = ONE5STOPBITS; break; case COMM_STOP_BIT_2: dcb.StopBits = TWOSTOPBITS; break; default: break; } switch(parity) //校验 { case COMM_NONE_PARITY: dcb.Parity = NOPARITY; break; case COMM_ODD_PARITY: dcb.Parity = ODDPARITY; break; case COMM_EVEN_PARITY: dcb.Parity = EVENPARITY; break; case COMM_MARK_PARITY: dcb.Parity = MARKPARITY; break; case COMM_SPACE_PARITY: dcb.Parity = SPACEPARITY; break; default: break; } return SetCommState(m_hComm, &dcb); } void CSerialComm::closeConnection() { if(!m_bConnected) return ; m_bConnected = FALSE; SetEvent(m_hPostMsgEvent); //结束commProc线程中WaitSingleObject函数的等待 SetCommMask(m_hComm, 0); //结束commProc线程中WaitCommEvent的等待 WaitForSingleObject(m_pThread->m_hThread, INFINITE); //等待辅助线程终止 m_pThread = NULL; CloseHandle(m_hComm); } DWORD CSerialComm::writeComm(char *buf, DWORD len) { BOOL ret; DWORD length = len; DWORD errorflags; COMSTAT comstat; ClearCommError(m_hComm, &errorflags, &comstat); ret = WriteFile(m_hComm, buf, length, &length, &m_osWrite); if(!ret) { if(GetLastError() == ERROR_IO_PENDING) { GetOverlappedResult(m_hComm, &m_osWrite, &length, TRUE); //等待 } else { length = 0; } } return length; } DWORD CSerialComm::readComm(char *pbuf, DWORD len) { DWORD length = 0; DWORD errorflags; COMSTAT comstat; ClearCommError(m_hComm, &errorflags, &comstat); length = min(len, comstat.cbInQue); ReadFile(m_hComm, pbuf, length, &length, &m_osRead); return length; } void CSerialComm::enumerateSerialPorts(CUIntArray& ports) { //Make sure we clear out any elements which may already be in the array ports.RemoveAll(); //Determine what OS we are running on OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); BOOL bGetVer = GetVersionEx(&osvi); //On NT use the QueryDosDevice API if (bGetVer && (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)) { //Use QueryDosDevice to look for all devices of the form COMx. This is a better //solution as it means that no ports have to be opened at all. TCHAR szDevices[65535]; DWORD dwChars = QueryDosDevice(NULL, szDevices, 65535); if (dwChars) { int i = 0; for ( ;; ) { //Get the current device name TCHAR* pszCurrentDevice = &szDevices[i]; //If it looks like "COMX" then //add it to the array which will be returned int nLen = _tcslen(pszCurrentDevice); if (nLen > 3 && _tcsnicmp(pszCurrentDevice, _T("COM"), 3) == 0) { //Work out the port number int nPort = _ttoi(&pszCurrentDevice[3]); ports.Add(nPort); } // Go to next NULL character while(szDevices[i] != _T('\0')) i ; // Bump pointer to the next string i ; // The list is double-NULL terminated, so if the character is // now NULL, we're at the end if (szDevices[i] == _T('\0')) break; } } else TRACE(_T("Failed in call to QueryDosDevice, GetLastError:%d\n"), GetLastError()); } else { //On 95/98 open up each port to determine their existence //Up to 255 COM ports are supported so we iterate through all of them seeing //if we can open them or if we fail to open them, get an access denied or general error error. //Both of these cases indicate that there is a COM port at that number. for (UINT i=1; i<256; i ) { //Form the Raw device name CString sPort; sPort.Format(_T("\\\\.\\COM%d"), i); //Try to open the port BOOL bSuccess = FALSE; HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError(); //Check to see if the error was because some other app had the port open or a general failure if (dwError == ERROR_ACCESS_DENIED || dwError == ERROR_GEN_FAILURE) bSuccess = TRUE; } else { //The port was opened successfully bSuccess = TRUE; //Don't forget to close the port, since we are going to do nothing with it anyway CloseHandle(hPort); } //Add the port number to the array which will be returned if (bSuccess) ports.Add(i); } } }
好例子网口号:伸出你的我的手 — 分享!
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论