vc 串口通信代码
2015-09-14 16:07
274 查看
#include "StdAfx.h" #include "comm.h" #include "publib.h" #include <process.h> CommModule::CommModule() { m_hCOM = NULL; m_bLog = FALSE; m_hThread = NULL; m_hStopEvt = NULL; m_data_cb = NULL; } CommModule::~CommModule() { } HANDLE CommModule::Init_Port(const char *port) { COMSTAT comstat; DWORD errors; CString s = CString(port); m_flowCtrl = COMM_FC_HW; m_baud = 115200; // 20120131 by foil - open com port fail int count = 1; while (count <= 50) // try 50 times { m_hCOM = CreateFile(s, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if(m_hCOM == INVALID_HANDLE_VALUE ) { DebugOut(_T("try %d: Failed to open %s, err = %d\n"), count, (LPCTSTR)s, GetLastError()); Sleep(100); count ++; } else break; } if(m_hCOM == INVALID_HANDLE_VALUE ) { // if(m_bLog) DebugOut(_T("eventually Failed to open %s, err = %d\n"), (LPCTSTR)s, GetLastError()); m_hCOM = NULL; return NULL; } else DebugOut(_T("Open %s succeeded!!!\n"), (LPCTSTR)s); ::ClearCommError(m_hCOM, &errors, &comstat); //turn off fAbort first DCB dcb; if( GetCommState(m_hCOM, &dcb)==FALSE ) { CloseHandle(m_hCOM); m_hCOM = NULL; return NULL; } dcb.DCBlength = sizeof(DCB); dcb.Parity = NOPARITY; dcb.ByteSize = 8; dcb.StopBits = ONESTOPBIT; dcb.BaudRate = m_baud; dcb.fBinary = TRUE; dcb.fParity = FALSE; if(m_flowCtrl == COMM_FC_HW) dcb.fOutxCtsFlow = TRUE; else dcb.fOutxCtsFlow = FALSE; dcb.fOutxDsrFlow = FALSE; dcb.fDtrControl = DTR_CONTROL_DISABLE; dcb.fDsrSensitivity = FALSE; dcb.fTXContinueOnXoff = FALSE; dcb.fErrorChar = FALSE; dcb.fNull = FALSE; dcb.fAbortOnError = FALSE; if(m_flowCtrl == COMM_FC_SW) { dcb.fOutX = TRUE; dcb.fInX = TRUE; } else { dcb.fOutX = FALSE; dcb.fInX = FALSE; } if(m_flowCtrl == COMM_FC_SW || m_flowCtrl == COMM_FC_NONE) dcb.fRtsControl = RTS_CONTROL_ENABLE; else if(m_flowCtrl == COMM_FC_HW) dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; if(m_flowCtrl == COMM_FC_SW) { dcb.XonChar = 0x11; dcb.XoffChar = 0x13; } else { dcb.XonChar = 0; dcb.XoffChar = 0; } dcb.ErrorChar = 0; dcb.EofChar = 0; dcb.EvtChar = 0; ::ClearCommError(m_hCOM, &errors, &comstat); if( SetCommState(m_hCOM, &dcb)==FALSE ) { CloseHandle(m_hCOM); m_hCOM = NULL; return NULL; } if( ::SetupComm(m_hCOM, 8192, 8192)==FALSE ) { CloseHandle(m_hCOM); m_hCOM = NULL; return NULL; } if( ::PurgeComm(m_hCOM, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR)==FALSE ) { CloseHandle(m_hCOM); m_hCOM = NULL; return NULL; } // Communications Properties COMMPROP cp; if(GetCommProperties(m_hCOM, &cp) == FALSE) { CloseHandle(m_hCOM); m_hCOM = NULL; return NULL; } COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = 0xFFFFFFFF; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 2000; if( ::SetCommTimeouts(m_hCOM, &timeouts) == FALSE ) { CloseHandle(m_hCOM); m_hCOM = NULL; return NULL; } m_hStopEvt = ::CreateEvent(NULL, TRUE, FALSE, NULL); if(m_hStopEvt == NULL) { CloseHandle(m_hCOM); m_hCOM = NULL; return false; } if(StartThread() == false) { return NULL; } return m_hCOM; } // Wait for thread void CommModule::WaitForExit() { if(m_hThread == NULL) return; WaitForSingleObject(m_hThread, INFINITE); CloseHandle(m_hThread); m_hThread = NULL; } void CommModule::StopThread() { if(m_hThread == NULL) return ; ::SetEvent(m_hStopEvt); WaitForExit(); } bool CommModule::StartThread() { m_hThread = (HANDLE)_beginthreadex( NULL, 0, (PBEGINTHREADEX_THREADFUNC)CommModule::HelpThreadFunc, (LPVOID)this, 0, NULL); if( m_hThread ) return true; return false; } DWORD CommModule::ThreadFunc() { COMSTAT comstat; DWORD errors; while(1) { //If dwMilliseconds is zero, the function tests the object's state and returns immediately if( ::WaitForSingleObject(m_hStopEvt, 0)==WAIT_OBJECT_0 ) { ::ClearCommError(m_hCOM, &errors, &comstat); break; } ::ClearCommError(m_hCOM, &errors, &comstat); if( !comstat.cbInQue ) { Sleep(1); //dwMilliseconds continue; } int dwBytesRead = (DWORD) comstat.cbInQue; if( 512 <= (int) dwBytesRead ) dwBytesRead = 512; if( ::ReadFile(m_hCOM, rawchars, dwBytesRead, &m_dwRead, NULL) ) { if( m_dwRead==0 || m_data_cb==NULL) continue; m_iRead = m_dwRead; rawchars[m_dwRead] = 0; if(m_bLog) DebugOutA("\r\n[rxd] %s\r\n", rawchars); m_data_cb(0, (const char*)rawchars, m_iRead, m_pData); } } return 0; } DWORD CommModule::HelpThreadFunc(LPVOID param) { CommModule *pto = (CommModule *)param; return pto->ThreadFunc(); } bool CommModule::WriteData(const char *Buf, const int size) { CString strDebug, strTemp; int nRetryCount = 0; int nSentBytes = 0; while( nSentBytes < size ) { int wbytes = 0; int nPerSend = 0; // reset write bytes wbytes = 0; // set send bytes nPerSend = size - nSentBytes; // if (nPerSend%8 == 0) // nPerSend--; // write to com BOOL bWriteResult = WriteFile(m_hCOM, ((char*)Buf)+nSentBytes, nPerSend, (unsigned long*)&wbytes, NULL); // check result if(!bWriteResult) { if(m_bLog) DebugOutA("\r\n[error] WriteFile failed: %d\r\n", GetLastError()); // clear com error ::ClearCommError(m_hCOM, NULL, NULL); } else if( wbytes < nPerSend ) { nSentBytes += wbytes; if(m_bLog) DebugOutA("\r\n[error] not write done. To write =%d, written = %d\r\n", nPerSend, wbytes); } else { // update the counts of sent bytes nSentBytes += wbytes; // reset retry count and continue to skip retry nRetryCount = 0; continue; } // check retry count if( 3 <= nRetryCount ) { if(m_bLog) DebugOutA("\r\n[error] write failed: <%s>\r\n", Buf); return false; } // increase retry count nRetryCount++; // receiver might be in busy status, sleep awhile Sleep(100); } if(m_bLog) DebugOutA("\r\n[txd] %s\r\n", Buf); return true; } int CommModule::SetCallBack(DataNotify reply, void *pExt) { m_data_cb = reply; m_pData = pExt; return 1; } void CommModule::Deinit_Port() { StopThread(); if(m_hCOM!=NULL) { CloseHandle(m_hCOM); m_hCOM = NULL; } if(m_hStopEvt!=NULL) { CloseHandle(m_hStopEvt); m_hStopEvt = NULL; } } void CommModule::EnableLog(BOOL bEnable) { m_bLog = bEnable; }
相关文章推荐
- 顺序表(C++语言实现)
- java反射修改静态方法的值setAccessible
- Java 字节流与字符流的区别
- 设计模式C++实现(10)——桥接模式
- 设计模式C++实现(9)——享元模式
- 解决:eclipse导入android时工程下没有R文件的问题,以及style.xml文件报错
- Matlab处理数据完成后自动发送邮箱提醒
- spring beans源码解读之 ioc容器之始祖--DefaultListableBeanFactory
- python编程:使用opencv按一定间隔截取视频帧
- C# 将RichTextBox中内容的文档以二进制形式存
- Python线程同步--互斥锁
- java.lang.OutOfMemoryError: Java heap space错误及处理办法(收集整理、转)
- asp.net 防止服务器代码多次提交问题
- ffmpeg的安装&&在c++工程中引用ffmpeg类库
- 苏宁2016研发工程师编程题
- 《Java编程思想》作者:C++不垃圾,只是Java很傲慢
- 【转】【Egit】如何将eclipse中的项目上传至Git
- Java源码阅读的真实体会
- thinkphp+ajax 实现二级联动
- Python访问Access数据库