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

📄 serial.cpp

📁 一个好用的基于wince下的串口读写类
💻 CPP
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TestSerial0.h"
#include "Serial.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//HANDLE hPort;
//CString strInChar;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSerial::CSerial()
{
	m_hPort	= NULL;
}

CSerial::~CSerial()
{
	if(m_hPort != INVALID_HANDLE_VALUE)
		ClosePort();
}

BOOL CSerial::OpenPort(LPTSTR lpszPortName,DWORD dwBandRate)
{
	DWORD dwError,dwThreadID;
	
	if(m_hPort)
	{
		return FALSE;
	}
	
	//打开串口
	m_hPort = CreateFile (lpszPortName, GENERIC_READ | GENERIC_WRITE,
		0, NULL, OPEN_EXISTING,0, NULL);
	
	//如果打开端口出错, 返回FALSE
	
	if ( m_hPort == INVALID_HANDLE_VALUE ) 
	{
		//不能打开端口
		CString strError;
		strError.Format(_T("Unable to open %s, Error No.=%d"), 
			lpszPortName, GetLastError());
		MessageBox (NULL, strError, TEXT("Error"), MB_OK);
		return FALSE;
		
	}

	m_threadparam.hPort	= m_hPort;
	m_threadparam.lpvoid = lpszPortName;
	
	//指定端口监测的事件集
	
	if(!SetCommMask (m_hPort, EV_RXCHAR|EV_RXFLAG|EV_ERR))
		return false;
	
	//分配设备缓冲区
	
	SetupComm(m_hPort,1024,1024);
	
	//初始化缓冲区中的信息
	
//	PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
	
	//配置串行端口
	
	if(!InitDCB(dwBandRate))
		return FALSE;
	//设置端口超时值
	
	if(!InitCommTimeouts())
		return FALSE;
	
	//设置端口上指定信号的状态
	// SETDTR: 发送DTR (data-terminal-ready)信号
	// SETRTS: 发送RTS (request-to-send)信号
	
//	EscapeCommFunction (hPort, SETDTR);
//	EscapeCommFunction (hPort, SETRTS);
	
	//创建一个从串口读取数据的线程
	
	if (hReadThread = CreateThread (NULL, 0, ReadPortThread, (LPVOID)&m_threadparam, 0,&dwThreadID))
	{
	}
	else
	{
		//不能创建线程
		MessageBox (NULL, TEXT("Unable to create the read thread"), 
			TEXT("Error"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
	}
	m_bConnected=TRUE;
	return TRUE;
}

DWORD CSerial::WritePort(TCHAR *buf,DWORD dwCharToWrite)
{
	BOOL fWriteState;
	DWORD dwBytesWritten;
	//写入数据
	
	fWriteState=WriteFile(m_hPort,buf,dwCharToWrite*sizeof(TCHAR),&dwBytesWritten,NULL);
	
	if(!fWriteState)
	{
		//不能写数据
		MessageBox(NULL,TEXT("Can't Write String to Comm"),TEXT("Error"),MB_OK);
		dwBytesWritten=0;
	}
	
	return dwBytesWritten;
}

DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{	
//	LPTSTR strcom	= (LPTSTR)lpvoid;
	THREADPARAM * thparam		= (THREADPARAM*)lpvoid;
	BOOL fReadState;
	DWORD dwCommModemStatus = 0;
	DWORD dwLength;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
//	::SendMessage(HWND_BROADCAST,WM_READPORT,0,0);
	while (thparam->hPort != INVALID_HANDLE_VALUE) 
	{
		//等待串口的事件发生
		WaitCommEvent (thparam->hPort, &dwCommModemStatus, 0);
//		if (dwCommModemStatus & EV_RXCHAR) 
		{
			ClearCommError(thparam->hPort,&dwErrorFlags,&ComStat);
			//cbInQue返回在串行驱动程序输入队列中的字符数
			dwLength=ComStat.cbInQue;
			if(dwLength>0)
			{
				//从串口读取数据
				char buf[1024];
				memset(buf,0,sizeof(buf));//=new TCHAR[256];
				fReadState=ReadFile(thparam->hPort,buf,dwLength,&dwLength,NULL);
				if(!fReadState)
				{
					//不能从串口读取数据
					MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
				}
				else
				{
					//把数据赋值给全局变量
//					strInChar=buf;
					::SendMessage(HWND_BROADCAST,WM_READPORT,(WPARAM)buf,(LPARAM)lpvoid);
				}
				delete[] buf;
			} 
		}
		GetCommModemStatus (thparam->hPort, &dwCommModemStatus);
	}
	return 0;
}

BOOL CSerial::ClosePort()
{
	if (m_hPort != INVALID_HANDLE_VALUE)
	{
		//设置连接属性为FALSE
		m_bConnected=FALSE;
		//结束线程中WaitCommEvent的等待
		SetCommMask(m_hPort,0);
		//阻塞至线程停止
		if(hReadThread)
		{
			TerminateThread(hReadThread,0);
			CloseHandle(hReadThread);
		}
		
		//清除端口上指定信号的状态
//		EscapeCommFunction(hPort,CLRDTR);
//		EscapeCommFunction(hPort,CLRRTS);
		//清除驱动程序内部的发送和接收队列
		PurgeComm(m_hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
		
		//关闭串口
		CloseHandle (m_hPort);
		m_hPort = NULL;
		
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

BOOL CSerial::InitDCB(DWORD dwBandRate)
{
	DCB PortDCB;
	DWORD dwError;
	
	PortDCB.DCBlength = sizeof (DCB); 
	
	//得到端口的默认设置信息
	GetCommState (m_hPort, &PortDCB);
	//改变DCB结构设置
	PortDCB.BaudRate = dwBandRate; //波特率 
	/*
	PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE 
	PortDCB.fParity = TRUE; //启用奇偶校验 
	PortDCB.fOutxCtsFlow = FALSE; //串行端口的输出由CTS线控制
	PortDCB.fOutxDsrFlow = FALSE; //关闭串行端口的DSR流控制 
	PortDCB.fDtrControl = DTR_CONTROL_DISABLE; //启用DTR线
	PortDCB.fDsrSensitivity = FALSE; //如果设为TRUE将忽略任何输入的字节,除非DSR线被启用 
	//PortDCB.fTXContinueOnXoff = TRUE; //当为TRUE时,如果接收缓冲区已满且驱动程序已传送XOFF字符,将使驱动程序停止传输字符
	
	PortDCB.fTXContinueOnXoff = FALSE;
	PortDCB.fOutX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输出 
	PortDCB.fInX = FALSE; //设为TRUE指定XON/XOFF控制被用于控制串行输入 
	PortDCB.fErrorChar = -64; //WINCE串行驱动程序的默认执行将忽略这个字段 
	PortDCB.fNull = FALSE; //设为TRUE将使串行驱动程序忽略收到的空字节 
	PortDCB.fRtsControl = RTS_CONTROL_DISABLE; //启用RTS线 
	PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
	*/
	PortDCB.ByteSize = (BYTE)8; //每字节的位数 
	PortDCB.Parity = NOPARITY; //无奇偶校验 
	PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位 
	
	//根据DCB结构配置端口 
	
	if (!SetCommState (m_hPort, &PortDCB))
	{
		//不能配置串行端口
		MessageBox (NULL, TEXT("Unable to configure the serial port"),TEXT("Error"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
	}
	return TRUE;
}

BOOL CSerial::InitCommTimeouts()
{
	COMMTIMEOUTS CommTimeouts;
	DWORD dwError;
	
	//得到超时参数
	GetCommTimeouts (m_hPort, &CommTimeouts);
	//改变COMMTIMEOUTS结构设置
	
	CommTimeouts.ReadIntervalTimeout = MAXDWORD; 
	CommTimeouts.ReadTotalTimeoutMultiplier = 0; 
	CommTimeouts.ReadTotalTimeoutConstant = 0; 
	CommTimeouts.WriteTotalTimeoutMultiplier = 0; 
	CommTimeouts.WriteTotalTimeoutConstant = 0; 
	
	//设置端口超时值 
	if (!SetCommTimeouts (m_hPort, &CommTimeouts))
	{
		//不能设置超时值
		MessageBox (NULL, TEXT("Unable to set the time-out parameters"), TEXT("Error"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
	}
	
	return TRUE;
} 

⌨️ 快捷键说明

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