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

📄 serial.cpp

📁 基于WIN CE 的抄表系统,环境wince .net
💻 CPP
字号:
// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Cbsystem.h"
#include "Serial.h"

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


HANDLE hPort;
BYTE* Recbuf;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

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

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

}

BOOL CSerial::OpenPort(LPTSTR lpszPortName, UINT baud, /*CString parity,*/ UINT databits, UINT stopsbits)
{

	DWORD dwError,
    dwThreadID;
	if(hPort)
	{
		return FALSE;
	}
    //打开串口
	hPort = CreateFile(lpszPortName/*_T("COM1:")*/, 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,256,256);
	//初始化缓冲区中的信息
	PurgeComm(hPort,PURGE_TXCLEAR|PURGE_RXCLEAR);
	//配置串行端口
	if(!InitDCB(baud,databits,stopsbits))
		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, 0, 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(BYTE *buf,DWORD dwCharToWrite)
{
	BOOL fWriteState;
	DWORD dwBytesWritten;
	//写入数据
	fWriteState=WriteFile(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)
{
	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];
				BYTE* buf=new BYTE[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
				{
					//把数据赋值给全局变量
					Recbuf=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 TRUE;
	}
}

BOOL CSerial::InitDCB(UINT baud, UINT databits, UINT stopsbits)
{
	DCB PortDCB;
	DWORD dwError;
	PortDCB.DCBlength = sizeof (DCB); 
	//得到端口的默认设置信息
	GetCommState (hPort, &PortDCB);
	//改变DCB结构设置
	PortDCB.BaudRate = /*9600*/baud;       //波特率
	//PortDCB.fBinary = TRUE;       //Win32不支持非二进制串行传输模式,必须为TRUE
	//PortDCB.fParity = TRUE;       //启用奇偶校验
	//PortDCB.fOutxCtsFlow = TRUE;       //串行端口的输出由CTS线控制
	//PortDCB.fOutxDsrFlow = FALSE;     //关闭串行端口的DSR流控制
	//PortDCB.fDtrControl = 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_ENABLE;   //启用RTS线
	//PortDCB.fAbortOnError = FALSE;     //WINCE串行驱动程序的默认执行将忽略这个字段
	PortDCB.ByteSize = /*8*/databits;         //每字节的位数
	PortDCB.Parity = NOPARITY;       //无奇偶校验
	PortDCB.StopBits = stopsbits/*ONESTOPBIT*/;     //每字节一位停止位
	//根据DCB结构配置端口
	if (!SetCommState (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 (hPort, &CommTimeouts);
	//改变COMMTIMEOUTS结构设置
	CommTimeouts.ReadIntervalTimeout = MAXDWORD;
	CommTimeouts.ReadTotalTimeoutMultiplier = 0;
	CommTimeouts.ReadTotalTimeoutConstant = 0; 
	CommTimeouts.WriteTotalTimeoutMultiplier = 10;
	CommTimeouts.WriteTotalTimeoutConstant = 1000; 
	//设置端口超时值
	if (!SetCommTimeouts (hPort, &CommTimeouts))
	{
		//不能设置超时值
		MessageBox (NULL, TEXT("Unable to set the time-out parameters"),
				TEXT("Error"), MB_OK);
		dwError = GetLastError ();
		return FALSE;
  }
	return TRUE;
}

BYTE*	CSerial::ReadData(HANDLE hComm)
{
	BOOL fReadState;
	DWORD dwCommModemStatus;
	DWORD dwLength;
	COMSTAT ComStat;
	DWORD dwErrorFlags;
	BYTE* ReceiveData;
	while (hComm != 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];
				BYTE* buf=new BYTE[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
				{
					//把数据赋值给全局变量
					ReceiveData=buf;
					return ReceiveData;
				}
				delete[] buf;
			} 
		}
		GetCommModemStatus (hPort, &dwCommModemStatus);
	}
	
}



⌨️ 快捷键说明

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