#pragma once
#include "Win32_Note_Define.h"
#include <windows.h>
/*******************************************
文件名: 串口操作
创建人: 陈泽丹
创建时间: 09-6-25
版本号: 1.0
描述: 实现一些基础操作
*******************************************/
class Comm
{
public:
Comm(void);
~Comm(void);
// 打开串口
// 输入: pPort - 串口名称或设备路径,可用"COM1"或"//./COM1"两种方式,建议用后者
// nBaudRate - 波特率
// nParity - 奇偶校验
// nByteSize - 数据字节宽度
// nStopBits - 停止位
BOOL OpenComm(LPCWSTR pPort = L"COM1", int nBaudRate=9600, int nByteSize=8, int nStopBits=ONESTOPBIT, int nParity=NOPARITY);
// 关闭串口
BOOL CloseComm();
// 读串口
// 输入: pData - 待读的数据缓冲区指针
// nLength - 待读的最大数据长度
// 返回: 实际读出的数据长度
int ReadComm(void* pData, int nLength);
// 写串口
// 输入: pData - 待写的数据缓冲区指针
// nLength - 待写的数据长度
// 返回: 实际写入的数据长度
int WriteComm(void* pData, int nLength);
// 清除收发缓冲区
void ClearBuff();
private:
// 串口设备句柄
HANDLE hComm;
};
///
#include "StdAfx.h"
#include "Comm.h"
Comm::Comm(void):hComm(INVALID_HANDLE_VALUE)
{
}
Comm::~Comm(void)
{
}
// 打开串口
// 输入: pPort - 串口名称或设备路径,可用"COM1"或"//./COM1"两种方式,建议用后者
// nBaudRate - 波特率
// nParity - 奇偶校验
// nByteSize - 数据字节宽度
// nStopBits - 停止位
BOOL Comm::OpenComm(LPCWSTR pPort, int nBaudRate, int nByteSize, int nStopBits, int nParity)
{
//CloseComm(); //先关闭原有串口
//接入串口
hComm = CreateFile(pPort, // 串口名称或设备路径
GENERIC_READ | GENERIC_WRITE, // 读写方式
0, // 共享方式:独占
0, // 默认的安全描述符
OPEN_EXISTING, // 创建方式
0, // 不需设置文件属性
0); // 不需参照模板文件
if( INVALID_HANDLE_VALUE == hComm)
{
Debug_Assert(false, "INVALID_HANDLE_VALUE == hComm");
return FALSE; // 打开串口失败
}
Sleep(500);
//串口参数处理
DCB dcb; // 串口控制块
if( !GetCommState(hComm, &dcb))
{// 读取DCB
Debug_Assert(false, "GetCommState(hComm, &dcb) == FALSE");
return FALSE; // 打开串口失败
};
dcb.BaudRate = nBaudRate;
dcb.ByteSize = nByteSize;
dcb.Parity = nParity;
dcb.StopBits = nStopBits;
dcb.fParity = FALSE; // 禁止奇偶校验
dcb.fBinary = TRUE; // 禁止流量控制
dcb.fDtrControl = 0;
dcb.fRtsControl = 0;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fTXContinueOnXoff = 0;
SetCommMask(hComm, EV_RXCHAR); // 串口事件: 接收到一个字符
SetupComm(hComm, 4096, 4096); // 设置输入输出缓冲区大小
if( !SetCommState(hComm, &dcb)) // 设置串口DCB
{
Debug_Assert(false, "!SetCommState(hComm, &dcb)");
CloseComm();
return FALSE;
}
//超时处理
COMMTIMEOUTS CommTimeOuts;
GetCommTimeouts(hComm, &CommTimeOuts);
CommTimeOuts.ReadIntervalTimeout = 100; // 接收字符间最大时间间隔
CommTimeOuts.ReadTotalTimeoutMultiplier = 1; // 读操作时每字符的时间: 1 ms (n个字符总共为n ms)
CommTimeOuts.ReadTotalTimeoutConstant = 500; // 读数据总超时常量
CommTimeOuts.WriteTotalTimeoutMultiplier = 1; // 写操作时每字符的时间: 1 ms (n个字符总共为n ms)
CommTimeOuts.WriteTotalTimeoutConstant = 100; // 基本的(额外的)写超时时间: 100 ms
if( !SetCommTimeouts(hComm, &CommTimeOuts))
{
Debug_Assert(false, "!SetCommTimeouts(hComm, &CommTimeOuts)");
CloseComm();
return FALSE;
}
PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); // 清除收发缓冲
return TRUE;
}
// 关闭串口
BOOL Comm::CloseComm()
{
if( INVALID_HANDLE_VALUE != hComm)
{
SetCommMask(hComm, 0); // 串口事件
PurgeComm(hComm, PURGE_TXCLEAR|PURGE_RXCLEAR); // 清除收发缓冲
CloseHandle(hComm);
hComm = INVALID_HANDLE_VALUE;
return TRUE;
}
return FALSE;
}
// 读串口
// 输入: pData - 待读的数据缓冲区指针
// nLength - 待读的最大数据长度
// 返回: 实际读出的数据长度
int Comm::ReadComm(void* pData, int nLength)
{
if( INVALID_HANDLE_VALUE != hComm)
{
DWORD dwNumRead = 0; // 串口收到的数据长度
if( FALSE == ReadFile(hComm, pData, (DWORD)nLength, &dwNumRead, NULL))
return 0;
return (int)dwNumRead;
}
return 0;
}
// 写串口
// 输入: pData - 待写的数据缓冲区指针
// nLength - 待写的数据长度
// 返回: 实际写入的数据长度
int Comm::WriteComm(void* pData, int nLength)
{
if( INVALID_HANDLE_VALUE != hComm)
{
DWORD dwNumWrite = 0; // 串口发出的数据长度
WriteFile(hComm, pData, (DWORD)nLength, &dwNumWrite, NULL);
return (int)dwNumWrite;
}
return 0;
}
void Comm::ClearBuff()
{
if( INVALID_HANDLE_VALUE != hComm)
{
PurgeComm(hComm, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); // 清除收发缓冲
}
}