串口封装类

#ifndef  _StkComm_H
#define  _StkComm_H

#include <Windows.h>
#include <process.h>
#include <string>
#include <list>

#include "def.h"

using namespace std;


//串口数据回调函数
typedef void(CALLBACK *OnComDataCallback)(DWORD dwSize, const char *pData);


class CStkComm
{
public:
CStkComm();
~CStkComm();

//打开串口
bool Open(DWORD dwPort, DWORD dwBaudRate, BYTE btParity = NOPARITY, BYTE btByteSize = 8, BYTE btStopBits = ONESTOPBIT);

//关闭串口
void Close();

void SetCommDataCallback(OnComDataCallback pComDataCallback);

void SendCommData(const string &str);

protected:
static unsigned __stdcall RecvCommDataThread(void *pParam);

static unsigned __stdcall SendCommDataThread(void *pParam);

private:
HANDLE  m_hComm;

bool  m_bRun;

HANDLE  m_hRecv, m_hSend;

CRITICAL_SECTION m_cs;

list<string> m_listData;

OnComDataCallback  m_pOnCommData;
};

#endif




#include "StkComm.h"
#include <assert.h>

CStkComm::CStkComm()
: m_hComm(INVALID_HANDLE_VALUE)
{
m_bRun = false;

m_pOnCommData = NULL;

m_hRecv = NULL;
m_hSend = NULL;

InitializeCriticalSection(&m_cs);
}

CStkComm::~CStkComm()
{
m_listData.clear();

DeleteCriticalSection(&m_cs);
}

bool CStkComm::Open(DWORD dwPort, DWORD dwBaudRate, BYTE btParity, BYTE btByteSize, BYTE btStopBits)
{
assert(dwPort>=1 && dwPort<=1024);

if(INVALID_HANDLE_VALUE != m_hComm)
{
CloseHandle(m_hComm);

m_hComm = INVALID_HANDLE_VALUE;
}

char szName[64] = "";

sprintf_s(szName,64,"COM%d",dwPort);

m_hComm = CreateFileA(szName,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

if(INVALID_HANDLE_VALUE == m_hComm)
{
return false;
}

BOOL bRet = SetupComm(m_hComm,dwInQueue,dwOutQueue);

if(!bRet)
{
return false;
}

DCB dcb;

memset(&dcb,0,sizeof(DCB));
dcb.DCBlength = sizeof(DCB);

bRet = GetCommState(m_hComm,&dcb);

if(!bRet)
{
return false;
}

dcb.BaudRate = dwBaudRate;
dcb.ByteSize = btByteSize;
dcb.Parity   = btParity;
dcb.StopBits = btStopBits;
//dcb.fParity  = (btParity != 0);

bRet = SetCommState(m_hComm,&dcb);

if(!bRet)
{
return false;
}

COMMTIMEOUTS CommTimeouts;

CommTimeouts.ReadIntervalTimeout = 500;//! 配置超时结构 字符最小间隔100ms
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 250;//! 读超时 阻塞I/O模式下250毫秒
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 250;

bRet = SetCommTimeouts(m_hComm,&CommTimeouts);

if(!bRet)
{
return false;
}

m_bRun = true;

m_hRecv = (HANDLE)_beginthreadex(NULL,0,&RecvCommDataThread,this,0,NULL);

if(0 == m_hRecv)
{
return false;
}

m_hSend = (HANDLE)_beginthreadex(NULL,0,&SendCommDataThread,this,0,NULL);

if(0 == m_hSend)
{
return false;
}

return true;
}

void CStkComm::Close()
{
m_bRun = false;

if(0 != m_hRecv)
{
WaitForSingleObject(m_hRecv,INFINITE);

CloseHandle(m_hRecv);
}

if(0 != m_hSend)
{
WaitForSingleObject(m_hSend,INFINITE);

CloseHandle(m_hSend);
}

m_listData.clear();

if(INVALID_HANDLE_VALUE != m_hComm)
{
CloseHandle(m_hComm);

m_hComm = INVALID_HANDLE_VALUE;
}
}

void CStkComm::SetCommDataCallback(OnComDataCallback pComDataCallback)
{
m_pOnCommData = pComDataCallback;
}

void CStkComm::SendCommData(const string &str)
{
EnterCriticalSection(&m_cs);

m_listData.push_back(str);

LeaveCriticalSection(&m_cs);
}

unsigned __stdcall CStkComm::RecvCommDataThread(void *pParam)
{
CStkComm *p = (CStkComm*)pParam;

char buf[1024] = "";

DWORD dwRead;

COMSTAT ComStat;
DWORD dwErrorFlags;

while(p->m_bRun)
{
memset(buf,0,1024);

ClearCommError(p->m_hComm,&dwErrorFlags,&ComStat);

ReadFile(p->m_hComm,(LPVOID)buf,/*ComStat.cbInQue*/1024,&dwRead,NULL);

if(dwRead > 0)
{
p->m_pOnCommData(dwRead,buf);
}

Sleep(10);
}

return 0;
}

unsigned __stdcall CStkComm::SendCommDataThread(void *pParam)
{
CStkComm *p = (CStkComm*)pParam;

DWORD dwWrite;

while(p->m_bRun)
{
while(!p->m_listData.empty())
{
string str = p->m_listData.front();

WriteFile(p->m_hComm,str.c_str(),str.length(),&dwWrite,NULL);

EnterCriticalSection(&p->m_cs);

p->m_listData.pop_front();

LeaveCriticalSection(&p->m_cs);
}

Sleep(10);
}

return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值