www.gusucode.com > VC写的短信串口发送程序源码程序 > VC写的短信串口发送程序源码程序/SMSDemo/Comm.cpp

    // Comm.cpp: implementation of the CComm class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SMSDemo.h"
#include "Comm.h"

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

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

CComm::CComm()
{
	m_hComm = INVALID_HANDLE_VALUE;
}

CComm::~CComm()
{
}

// 打开串口
// pPort: 串口名称或设备路径,可用"COM1"或"\\.\COM1"两种方式,建议用后者
// nBaudRate: 波特率
// nParity: 奇偶校验
// nByteSize: 数据字节宽度
// nStopBits: 停止位
BOOL CComm::Open(LPCTSTR pPort, int nBaudRate, int nParity, int nByteSize, int nStopBits)
{
	DCB dcb;		// 串口控制块
	COMMTIMEOUTS timeouts = {	// 串口超时控制参数
			0,				// 读字符间隔超时时间: 100 ms
			0,					// 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
			0,				// 基本的(额外的)读超时时间: 500 ms
			0,					// 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
			0};				// 基本的(额外的)写超时时间: 100 ms
	/*
	 COMMTIMEOUTS timeouts = {	// 串口超时控制参数
			300,				// 读字符间隔超时时间: 100 ms
			10,					// 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
			1000,				// 基本的(额外的)读超时时间: 500 ms
			1,					// 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
			100};				// 基本的(额外的)写超时时间: 100 ms
	 */

		
		m_hComm = CreateFile(pPort,	// 串口名称或设备路径
			GENERIC_READ | GENERIC_WRITE,	// 读写方式
			0,				// 共享方式:独占
			NULL,			// 默认的安全描述符
			OPEN_EXISTING,	// 创建方式
			FILE_FLAG_NO_BUFFERING,			// 不需设置文件属性
			NULL);			// 不需参照模板文件
		
		if(m_hComm == INVALID_HANDLE_VALUE) return FALSE;		// 打开串口失败
		
		GetCommState(m_hComm, &dcb);		// 取DCB
		
		dcb.BaudRate = nBaudRate;
		dcb.ByteSize = nByteSize;
		dcb.Parity = nParity;
		dcb.StopBits = nStopBits;
		
		SetCommState(m_hComm, &dcb);		// 设置DCB
		
		SetupComm(m_hComm, 4096, 4);	// 设置输入输出缓冲区大小
		
		BOOL bRet = ::SetCommTimeouts(m_hComm, &timeouts);	// 设置超时
		
		return TRUE;
}

// 关闭串口
BOOL CComm::Close()
{
	return CloseHandle(m_hComm);
}

// 写串口
// pData: 待写的数据缓冲区指针
// nLength: 待写的数据长度
void CComm::Write(void* pData, int nLength)
{
	DWORD dwNumWrite;	// 串口发出的数据长度
	WriteFile(m_hComm, pData, (DWORD)nLength, &dwNumWrite, NULL);
	/*
	DWORD dwNumWrite = 0;	// 串口发出的数据长度
	LPCTSTR p = (LPCTSTR)pData;
	//WriteFile(m_hComm, pData, (DWORD)nLength, &dwNumWrite, NULL);
	for(int i=0; i<nLength; i++)
	{
		WriteFile(m_hComm, &p[i], (DWORD)1, &dwNumWrite, NULL);
		Sleep(100);
	}
	*/
}

// 读串口
// pData: 待读的数据缓冲区指针
// nLength: 待读的最大数据长度
// 返回: 实际读入的数据长度
//ReadResponsion()
int CComm::Read(void* pData, int nLength, DWORD dwTimeOut)
{
	DWORD dwNumRead = 0;	// 串口收到的数据长度
	//ReadFile(m_hComm, pData, nLength, &dwNumRead, NULL);
	LPCTSTR buffer = (LPCTSTR)pData;

	while(TRUE)
	{
		COMSTAT ComStat;
		DWORD dwBytesRead, dwErrorFlags;
		ClearCommError(m_hComm, &dwErrorFlags, &ComStat);

		if(ComStat.cbInQue)
		{
			//DWORD dwWantRead = min(ComStat.cbInQue, nLength - ;
			ReadFile(m_hComm, (void*)&buffer[dwNumRead], ComStat.cbInQue, &dwBytesRead, NULL);
			dwNumRead += dwBytesRead;

			if(strstr(buffer, "OK\r\n") || strstr(buffer, "ERROR\r\n"))
				break;
		}
		else
		{
			MSG msg;
			if (::PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
				::DispatchMessage(&msg);
		}
	}
		
	/*
	//先进行等待直到读取到一个字节
	DWORD dwStartTicks = GetTickCount();
	while(TRUE)
	{
		if ((::GetTickCount() - dwStartTicks) >	dwTimeOut)
			return -1;

		DWORD nRead = 0;
		if(ReadFile(m_hComm, pData, 1, &nRead, NULL) && nRead == 1)
			break;
		else
			Sleep(100);
	}

	//继续读取其他部分
	LPCTSTR szBUffer = (LPCTSTR)pData;
	dwNumRead = 1;
	while(dwNumRead < (DWORD)nLength)
	{
		DWORD nRead = 0;
		if(ReadFile(m_hComm, (void*)&szBUffer[dwNumRead], 1, &nRead, NULL) && nRead == 1)
			dwNumRead ++;
		else
			break;
	}
	*/
	return (int)dwNumRead;
}