⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cserial.cpp

📁 在WinCE下面
💻 CPP
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "CSerial.h"
#include "UartTest.h"

const CM_THREADCOMMWRITE = WM_USER+110;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//*******************************************//
CSerial::CSerial()
{
	m_hComm = INVALID_HANDLE_VALUE;
//	m_bOpened = FALSE;
}
//******************************************//

CSerial::~CSerial()
{
	ClosePort();
}

//*******************************************//
BOOL CSerial::WritetoPort(HANDLE hComm,const BYTE *buf,DWORD bufLen)
{
	DWORD dwNumBytesWritten;
	DWORD dwHaveNumWritten = 0;
	ASSERT(hComm != INVALID_HANDLE_VALUE);
	do
	{
		if(WriteFile(hComm,
					 buf+dwHaveNumWritten,
					 bufLen - dwHaveNumWritten,
					 &dwNumBytesWritten,
					 NULL))
		{
			dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
			if (dwHaveNumWritten == bufLen)
			{
				break;
			}
			Sleep(10);
		}
		else
		{
			return FALSE;
		}
	}while(TRUE);
	return TRUE;
}

//***********************************************//
//串口读线程函数
DWORD CSerial::ReadThreadFunc(LPVOID lparam)
{
	CSerial *ceSeries = (CSerial *)lparam;
	DWORD evtMask;
	BYTE* readBuf = NULL;
	DWORD actualReadLen = 0;
	DWORD willReadLen;
	DWORD dwReadErrors;
	COMSTAT cmState;
	//清空缓冲
	ASSERT(ceSeries->m_hComm != INVALID_HANDLE_VALUE);
	//清空串口
	PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR);
	SetCommMask(ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
	while(TRUE)
	{
		if(WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
		{
			SetCommMask(ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
			if(evtMask & EV_RXCHAR)
			{
				ClearCommError(ceSeries->m_hComm, &dwReadErrors, &cmState);
				willReadLen = cmState.cbInQue;
				if(willReadLen <= 0)
				{
					continue;
				}
				readBuf = new BYTE[willReadLen];
				ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen ,0);
				if(actualReadLen>0)
				{
					((CUartTest *)(ceSeries->m_pPortOwner))->response(readBuf,actualReadLen);

				}
				delete[] readBuf;
			}
		}
		if(WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
		{
			break;
		}
	}
	return 0;
}
//************************************************//
//串口写线程函数
DWORD CSerial::WriteThreadFunc(LPVOID lparam)
{
	CSerial *ceSeries = (CSerial *)lparam;
	MSG msg;
	DWORD dwWriteLen = 0;
	BYTE* buf = NULL;
	while(TRUE)
	{
		if(PeekMessage(&msg,0,0,0,PM_REMOVE))
		{
			if(msg.hwnd != 0)
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
				continue;
			}
			if(msg.message == CM_THREADCOMMWRITE)
			{
				buf = (BYTE*)msg.lParam;
				dwWriteLen = msg.wParam;
				WritetoPort(ceSeries->m_hComm,buf,dwWriteLen);
				delete[] buf;
			}
		}
		if(WaitForSingleObject(ceSeries->m_hWriteCloseEvent ,500) == WAIT_OBJECT_0)
		{
			break;
		}
		ceSeries->m_hWriteThread = NULL;
	}
	return 0;
}
//***********************************************//
//关闭读线程
void CSerial::CloseReadThread()
{
	SetEvent(m_hReadCloseEvent);
	SetCommMask(m_hComm,0);
	PurgeComm(m_hComm,PURGE_RXCLEAR);
	if(WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT)
	{
		TerminateThread(m_hReadThread,0);
	}
	m_hReadThread = NULL;
}
//***********************************************//
//关闭写线程
void CSerial::CloseWriteThread()
{
	SetEvent(m_hWriteCloseEvent);
	SetCommMask(m_hComm,0);
	PurgeComm(m_hComm,PURGE_TXCLEAR);
	if(WaitForSingleObject(m_hWriteThread,10000) == WAIT_TIMEOUT)
	{
		TerminateThread(m_hWriteThread,0);
	}
	m_hWriteThread = NULL;
}
//***********************************************//
//打开串口
BOOL CSerial::OpenPort(CWnd* pPortOwner,
				       UINT portNo,
				       DWORD baud,
				       BYTE parity,
				       BYTE databits,
				       BYTE stopbits)
{
	DCB commParam;
	TCHAR szPort[15];
	if(m_hComm != INVALID_HANDLE_VALUE)
	{
		return TRUE;
	}
	ASSERT(pPortOwner != NULL);
	ASSERT(portNo > 0 && portNo <5);
	//设置串口名
	wsprintf(szPort ,_T("COM%d:"), portNo);
	m_hComm = CreateFile(
		szPort,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		0,
		NULL 
		);
	if(m_hComm == INVALID_HANDLE_VALUE)
	{
		TRACE(_T("CreateFile return invalid handle"));
		return FALSE;
	}
	if(!GetCommState(m_hComm,&commParam))
	{
		return FALSE;
	}
	commParam.BaudRate = baud;
	commParam.ByteSize = databits;
	commParam.Parity = parity;  // 0-4=no,odd,even,mark,space 
	commParam.StopBits = stopbits;
	if(!SetCommState(m_hComm, &commParam))
	{
		TRACE(_T("SetCommState error"));
		return FALSE;
	}
	//设置串口读写时间
	COMMTIMEOUTS CommTimeOuts;
	GetCommTimeouts (m_hComm, &CommTimeOuts);
    CommTimeOuts.ReadIntervalTimeout = MAXDWORD;  
    CommTimeOuts.ReadTotalTimeoutMultiplier = 0;  
    CommTimeOuts.ReadTotalTimeoutConstant = 0;    
    CommTimeOuts.WriteTotalTimeoutMultiplier = 10;  
    CommTimeOuts.WriteTotalTimeoutConstant = 1000;
	if(!SetCommTimeouts(m_hComm,&CommTimeOuts))
	{
		TRACE(_T("SetCommTimeouts wrong!"));
	}
	m_pPortOwner = pPortOwner;
	SetCommMask(m_hComm,EV_RXCHAR);
	SetupComm(m_hComm,512,512);
	PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
	m_hReadCloseEvent = CreateEvent(NULL ,TRUE ,FALSE ,NULL);
	m_hWriteCloseEvent = CreateEvent(NULL ,TRUE ,FALSE ,NULL);
	//创建读串口线程
	m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
    //创建写串口线程
	m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc, this,0,&m_dwWriteThreadID);
	TRACE(_T("Serial Port Open Successful!"));
	return TRUE;
}
//**************************************************//
//关闭串口
void CSerial::ClosePort()
{
	if(m_hComm == INVALID_HANDLE_VALUE)
	{
		return;
	}
	CloseReadThread();
	CloseWriteThread();
	if(!CloseHandle(m_hComm))
	{
		m_hComm = INVALID_HANDLE_VALUE;
		return;
	}
}
//*****************************************************//
//公用写串口
BOOL CSerial::WritePort(const BYTE *buf , DWORD bufLen)
{
	if(PostThreadMessage(m_dwWriteThreadID,CM_THREADCOMMWRITE,WPARAM(bufLen),LPARAM(buf)))
	{
		return TRUE;
	}
	return FALSE;
}
//*******************************************************//
//设置串口超时
BOOL CSerial::SetSeriesTimeOuts(COMMTIMEOUTS CommTimeOuts)
{
	ASSERT(m_hComm != INVALID_HANDLE_VALUE);
	return SetCommTimeouts(m_hComm,&CommTimeOuts);
}


	



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -