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

📄 serial.cpp

📁 开发环境为EVC++,这个是一个我的一个简单的拨号程序,是通过串口接的GPRS模块,有开发WinCE下的同志可以以次入门
💻 CPP
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "Serial.h"

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

#ifdef _DEBUG

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

#endif

HANDLE hPort=NULL;
CString strInChar("");

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

CSerial::CSerial()
{
	
}

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

BOOL CSerial::OpenPort(LPTSTR lpszPortName,UINT uiBaudRate)
{
	DWORD dwError;
	DWORD dwThreadID;
	if((hPort!=NULL)&& (hPort!=INVALID_HANDLE_VALUE))
	{
		return FALSE;
	}
	//打开串口
//	hPort = CreateFile (lpszPortName, GENERIC_READ | GENERIC_WRITE,
//						0, NULL, OPEN_EXISTING,0, NULL);//多一个冒号....
//	GetLastError();
	hPort = CreateFile(lpszPortName, GENERIC_READ | GENERIC_WRITE,
						0, NULL, OPEN_EXISTING,0, NULL);
	//如果打开端口出错, 返回FALSE
	if(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;
	}
	//指定端口监测的事件集
	SetCommMask (hPort, EV_RXCHAR);
	//分配设备缓冲区    
	SetupComm(hPort,512,512);
	//初始化缓冲区中的信息
	PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
	//配置串行端口
	if(!InitDCB(uiBaudRate))
	{
		MessageBox (NULL,_T("InitDCB Failed"),TEXT("Error"), MB_OK);
		return FALSE;
	}
	//设置端口超时值
	if(!InitCommTimeouts())
	{
		MessageBox (NULL,_T("InitCommTimeouts Failed"),TEXT("Error"), MB_OK);
		return FALSE;
	}
	//设置端口上指定信号的状态
	// SETDTR: 发送DTR (data-terminal-ready)信号
	// SETRTS: 发送RTS (request-to-send)信号

//	EscapeCommFunction (hPort, SETDTR);
//	EscapeCommFunction (hPort, SETRTS);

	//创建一个从串口读取数据的线程

	if(hReadThread=CreateThread (NULL, 0, ReadPortThread, 0, 0,&dwThreadID))
	{

	}
	else
	{
		//不能创建线程
		MessageBox (NULL, _T("Unable to create the read thread"),_T("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(hPort,buf,dwCharToWrite*sizeof(TCHAR),&dwBytesWritten,NULL);
	if(!fWriteState)
	{
		//不能写数据
		MessageBox(NULL,_T("Can't Write String to Comm"),_T("Error"),MB_OK);
		dwBytesWritten=0;
	}
	return dwBytesWritten;
}

DWORD WINAPI ReadPortThread(LPVOID lpvoid)
{
	BOOL fReadState;
	DWORD dwCommModemStatus;
	DWORD dwLength;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	while (hPort != INVALID_HANDLE_VALUE) 
	{
	//等待串口的事件发生
	WaitCommEvent (hPort, &dwCommModemStatus, 0);
	if(dwCommModemStatus & EV_RXCHAR)
	{
		ClearCommError(hPort,&dwErrorFlags,&ComStat);
	//cbInQue返回在串行驱动程序输入队列中的字符数
		dwLength=ComStat.cbInQue;
		if(dwLength>0)
		{
			//从串口读取数据
			TCHAR* buf=new TCHAR[256];
			fReadState=ReadFile(hPort,buf,dwLength,&dwLength,NULL);
			if(!fReadState)
			{
				//不能从串口读取数据
				MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
			}
			else
			{
				//把数据赋值给全局变量,回车格式为"\r\n"
				  buf[0]&=0x00ff;
				  buf[1]='\0';
				  strInChar+=buf;
				  int iFoundSpaicChar=strInChar.Find('\r',0);
				  if(iFoundSpaicChar!=-1)
				  {
					  if(iFoundSpaicChar<=(strInChar.GetLength()-2))
					  {
						  strInChar=strInChar.Right(1);
					  }
					  else
					  {

					  }

				  }
			//	strInChar=buf;
			}
			delete[] buf;
		} 
	}
	//GetCommModemStatus (hPort, &dwCommModemStatus);
	}
	return 0;
}


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

BOOL CSerial::InitDCB(UINT uiBaudRate)
{
	DCB PortDCB;
	DWORD dwError;
	PortDCB.DCBlength = sizeof(DCB); 
	//得到端口的默认设置信息
	GetCommState (hPort, &PortDCB);
	//改变DCB结构设置
	PortDCB.BaudRate = uiBaudRate;//19200; //波特率 
	PortDCB.fBinary = TRUE; //Win32不支持非二进制串行传输模式,必须为TRUE 
	PortDCB.fParity = TRUE; //启用奇偶校验 
	PortDCB.fOutxCtsFlow = FALSE;//TRUE; //串行端口的输出由CTS线控制
	PortDCB.fOutxDsrFlow = FALSE;//关闭串行端口的DSR流控制
	PortDCB.fDtrControl = DTR_CONTROL_DISABLE;//DTR_CONTROL_ENABLE; //启用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 = FALSE;//WINCE串行驱动程序的默认执行将忽略这个字段
	PortDCB.fNull = FALSE;//设为TRUE将使串行驱动程序忽略收到的空字节
	PortDCB.fRtsControl = RTS_CONTROL_DISABLE;//RTS_CONTROL_ENABLE; //启用RTS线
	PortDCB.fAbortOnError = FALSE; //WINCE串行驱动程序的默认执行将忽略这个字段
	PortDCB.ByteSize = 8; //每字节的位数
	PortDCB.Parity = NOPARITY;//无奇偶校验 
	PortDCB.StopBits = ONESTOPBIT; //每字节一位停止位 
	//根据DCB结构配置端口
	if(!SetCommState (hPort, &PortDCB))
	{
		//不能配置串行端口
		MessageBox (NULL, TEXT("Unable to configure the serial port"),_T("Error"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
	}
	return TRUE;
}


BOOL CSerial::InitCommTimeouts()
{
	COMMTIMEOUTS CommTimeouts;
	DWORD dwError;
	//得到超时参数
	GetCommTimeouts (hPort, &CommTimeouts);
	//改变COMMTIMEOUTS结构设置,0 表示无限等待
	CommTimeouts.ReadIntervalTimeout = MAXDWORD;
	CommTimeouts.ReadTotalTimeoutMultiplier = 0;
	CommTimeouts.ReadTotalTimeoutConstant = 0;
	CommTimeouts.WriteTotalTimeoutMultiplier = 0;//10;
	CommTimeouts.WriteTotalTimeoutConstant = 0;//1000;
	//设置端口超时值 
	if (!SetCommTimeouts (hPort, &CommTimeouts))
	{
		//不能设置超时值
		MessageBox (NULL, _T("Unable to set the time-out parameters"),_T("Error"), MB_OK);

		dwError = GetLastError ();
		return FALSE;
	}
	return TRUE;
}

void CSerial::ClosePort()
{
	if(!CloseHandle (hPort))
	{
		MessageBox(NULL, _T("Unable to Close Port"),_T("Error"), MB_OK);
	}
}

CString CSerial::GetPortData()
{
	return strInChar;
}

⌨️ 快捷键说明

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