📄 ceseries.cpp
字号:
// CESeries.cpp: implementation of the CCESeries class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "GPSCOM.h"
#include "CESeries.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//定义向写线程发送的消息常量
const CM_THREADCOMMWRITE = WM_USER+110;
//#define CM_THREADCOMMWRITE 32772
CCESeries::CCESeries()
{
m_hComm=INVALID_HANDLE_VALUE;
m_hComm1=INVALID_HANDLE_VALUE;
}
CCESeries::~CCESeries()
{
}
BOOL CCESeries::OpenPort()
{
// 已经打开的话,直接返回
if (m_hComm != INVALID_HANDLE_VALUE)
{
return TRUE;
}
//以同步读取方式打开串口COM1
m_hComm = CreateFile(_T("COM1:"),
GENERIC_READ, //允许读
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0,
NULL);
if (m_hComm == INVALID_HANDLE_VALUE)
{
// 无效句柄,返回。
return FALSE;
}
// 配置串口,得到打开串口的当前属性参数,修改后再重新设置串口。
DCB portDCB;
portDCB.DCBlength=sizeof(DCB); //DCB结构大小
//默认串口参数
if(!GetCommState(m_hComm,&portDCB))
{
return FALSE;
}
portDCB.BaudRate=9600; //波特率
portDCB.ByteSize=8; //字符位
portDCB.Parity=NOPARITY; //奇偶校验位
portDCB.StopBits=ONESTOPBIT;//停止位
if (!SetCommState(m_hComm,&portDCB))
{
//配置串口失败
return FALSE;
}
//设置串口读写时间
//配置超时
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(m_hComm,&CommTimeouts);
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
if (!SetCommTimeouts(m_hComm,&CommTimeouts))
{
//不能设置超时参数
return FALSE;
}
//指定端口监测的事件集
SetCommMask (m_hComm, EV_RXCHAR);
//分配设备缓冲区
SetupComm(m_hComm,512,512);
//初始化缓冲区中的信息
PurgeComm(m_hComm,PURGE_TXCLEAR|PURGE_RXCLEAR);
m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
//创建读串口线程
m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
//创建写串口线程
m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);
return TRUE;
}
//串口读线程函数
DWORD CCESeries::ReadThreadFunc(LPVOID lparam)
{
CCESeries *ceSeries = (CCESeries*)lparam;
DWORD evtMask;
//BYTE * readBuf = NULL;//读取的字节
BYTE * readBuf = NULL;//读取的字节
DWORD actualReadLen=0;//实际读取的字节数
DWORD willReadLen;
DWORD dwReadErrors;
COMSTAT cmState;
// 清空缓冲,并检查串口是否打开。
ASSERT(ceSeries->m_hComm !=INVALID_HANDLE_VALUE);
//清空串口
PurgeComm(ceSeries->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR );
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
while (TRUE)
{
if (WaitCommEvent(ceSeries->m_hComm,&evtMask,0))
{
SetCommMask (ceSeries->m_hComm, EV_RXCHAR | EV_CTS | EV_DSR );
//表示串口收到字符
if (evtMask & EV_RXCHAR)
{
//清除错误并查询状态
ClearCommError(ceSeries->m_hComm,&dwReadErrors,&cmState);
willReadLen = cmState.cbInQue ;//接收缓冲区中存储的待读取的字符数
if (willReadLen <= 0)
{
continue;
}
//willReadLen=4;
//willReadLen=willReadLen/2+1;
readBuf = new BYTE[willReadLen+1];
ReadFile(ceSeries->m_hComm, readBuf, willReadLen, &actualReadLen,0);
readBuf[willReadLen]=0;
//BYTE * Buf1 = NULL;
//Buf1 = new BYTE[actualReadLen+1];
//memcpy(Buf1,readBuf,actualReadLen);
//Buf1[actualReadLen]=0;
//如果读取的数据大于0,
if (actualReadLen>0)
{
//触发读取回调函数
ceSeries->m_OnSeriesRead(ceSeries->m_pPortOwner,readBuf,actualReadLen);
}
}
}
//如果收到读线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hReadCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
}
return 0;
}
void CCESeries::ClosePort()
{
//表示串口还没有打开
if (m_hComm == INVALID_HANDLE_VALUE)
{
return ;
}
//关闭读线程
CloseReadThread();
//关闭写线程
CloseWriteThread();
//关闭串口
if (!CloseHandle (m_hComm))
{
m_hComm = INVALID_HANDLE_VALUE;
return ;
}
}
void CCESeries::CloseReadThread()
{
SetEvent(m_hReadCloseEvent);
//设置所有事件无效无效
SetCommMask(m_hComm, 0);
//清空所有将要读的数据
PurgeComm( m_hComm, PURGE_RXCLEAR );
//等待10秒,如果读线程没有退出,则强制退出
if (WaitForSingleObject(m_hReadThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hReadThread,0);
}
m_hReadThread = NULL;
}
BOOL CCESeries::WritePort(BYTE *buf, int bufLen)
{
//将要发送的数据传递到写线程消息队列
if (PostThreadMessage(m_dwWriteThreadID,CM_THREADCOMMWRITE,
WPARAM(bufLen), LPARAM(buf)))
{
return TRUE;
}
return FALSE;
}
BOOL CCESeries::WritePort(HANDLE hComm, BYTE *buf, int bufLen)
{
DWORD dwNumBytesWritten;
DWORD dwHaveNumWritten =0 ; //已经写入多少
ASSERT(hComm != INVALID_HANDLE_VALUE);
do
{
if (WriteFile (hComm, //串口句柄
buf+dwHaveNumWritten, //被写数据缓冲区
bufLen - dwHaveNumWritten, //被写数据缓冲区大小
&dwNumBytesWritten, //函数执行成功后,返回实际向串口写的个数
NULL)) //此处必须设置NULL
{
dwHaveNumWritten = dwHaveNumWritten + dwNumBytesWritten;
//写入完成
if (dwHaveNumWritten ==(DWORD) bufLen)
{
break;
}
Sleep(10);
}
else
{
return FALSE;
}
}while (TRUE);
return TRUE;
}
void CCESeries::CloseWriteThread()
{
SetEvent(m_hWriteCloseEvent);
//清空所有将要写的数据
PurgeComm( m_hComm1, PURGE_TXCLEAR );
//等待10秒,如果读线程没有退出,则强制退出
if (WaitForSingleObject(m_hWriteThread,10000) == WAIT_TIMEOUT)
{
TerminateThread(m_hWriteThread,0);
}
m_hWriteThread = NULL;
}
DWORD CCESeries::WriteThreadFunc(LPVOID lparam)
{
CCESeries *ceSeries = (CCESeries*)lparam;
MSG msg;
DWORD dwWriteLen = 0;
BYTE * buf1;
while (TRUE)
{
//如果捕捉到线程消息
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.hwnd != 0 )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
continue;
}
if (msg.message == CM_THREADCOMMWRITE)
{
//向串口写
buf1 = (BYTE*)msg.lParam;
dwWriteLen = msg.wParam;
//向串口写
WritePort(ceSeries->m_hComm1,buf1,dwWriteLen);
// delete[] buf1;
Sleep(10);
}
}
//如果收到写线程退出信号,则退出线程
if (WaitForSingleObject(ceSeries->m_hWriteCloseEvent,500) == WAIT_OBJECT_0)
{
break;
}
ceSeries->m_hWriteThread = NULL;
}
return 0;
}
BOOL CCESeries::OpenPort1()
{
// 已经打开的话,直接返回
if (m_hComm1 != INVALID_HANDLE_VALUE)
{
return TRUE;
}
//以同步读取方式打开串口COM1
m_hComm1 = CreateFile(_T("COM1:"),
GENERIC_READ| GENERIC_WRITE, //允许读写
0, //独占方式
NULL,
OPEN_EXISTING, //打开而不是创建
0,
NULL);
if (m_hComm1 == INVALID_HANDLE_VALUE)
{
// 无效句柄,返回。
return FALSE;
}
// 配置串口,得到打开串口的当前属性参数,修改后再重新设置串口。
DCB portDCB;
portDCB.DCBlength=sizeof(DCB); //DCB结构大小
//默认串口参数
if(!GetCommState(m_hComm1,&portDCB))
{
return FALSE;
}
portDCB.BaudRate=9600; //波特率
portDCB.ByteSize=8; //字符位
portDCB.Parity=NOPARITY; //奇偶校验位
portDCB.StopBits=ONESTOPBIT;//停止位
if (!SetCommState(m_hComm1,&portDCB))
{
//配置串口失败
return FALSE;
}
//设置串口读写时间
//配置超时
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts(m_hComm1,&CommTimeouts);
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
if (!SetCommTimeouts(m_hComm1,&CommTimeouts))
{
//不能设置超时参数
return FALSE;
}
//指定端口监测的事件集
SetCommMask (m_hComm1, EV_RXCHAR);
//分配设备缓冲区
SetupComm(m_hComm1,512,512);
//初始化缓冲区中的信息
PurgeComm(m_hComm1,PURGE_TXCLEAR|PURGE_RXCLEAR);
//m_hReadCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
m_hWriteCloseEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
//创建读串口线程
//m_hReadThread = CreateThread(NULL,0,ReadThreadFunc,this,0,&m_dwReadThreadID);
//创建写串口线程
m_hWriteThread = CreateThread(NULL,0,WriteThreadFunc,this,0,&m_dwWriteThreadID);
return TRUE;
}
void CCESeries::ClosePort1()
{
//表示串口还没有打开
if (m_hComm1 == INVALID_HANDLE_VALUE)
{
return ;
}
//关闭写线程
CloseWriteThread();
//关闭串口
if (!CloseHandle (m_hComm1))
{
m_hComm1 = INVALID_HANDLE_VALUE;
return ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -