使用qt封装的串口类
pro
QT += serialport
h
#include <QSerialPortInfo>
private:
QSerialPort *ComportZK1;
void OpenDevice();
private slots:
void ReadComport();
cpp
构造函数{
ComportZK1 = new QSerialPort;
connect(ComportZK1,SIGNAL(readyRead()),this,SLOT(ReadComport()));
}
bool MainWindow::OpenDevice()
{
ComportZK1->setPort(QSerialPortInfo(sZWCom));
if(ComportZK1->isOpen())
{
ComportZK1->clear();
ComportZK1->close();
}
if(!ComportZK1->open(QIODevice::ReadWrite))
{
addMsg("登录指纹仪打开失败"+sZWCom);
return false;
}
else
{
addMsg("登录指纹仪打开成功"+sZWCom);
ComportZK1->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
ComportZK1->setDataBits(QSerialPort::Data8);
ComportZK1->setFlowControl(QSerialPort::NoFlowControl);
ComportZK1->setParity(QSerialPort::NoParity);
ComportZK1->setStopBits(QSerialPort::OneStop);
bZWInit = true;
return true;
}
}
void MainWindow::ReadComport()
{
QByteArray buf;
buf = ComportZK1->readAll();
}
使用C++串口类
h
#ifndef COMP_H
#define COMP_H
#include <tchar.h>
#include <math.h>
#include <iostream>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>
extern BYTE aaaa[4096];
class Comp
{
public:
Comp();
~Comp();
bool InitCOM(LPCTSTR Port,int bautrate);
void UninitCOM();
bool ComWrite(LPBYTE buf,int &len);
static unsigned int __stdcall OnRecv(void*);
volatile bool m_IsOpen;
private:
HANDLE m_hCom;
OVERLAPPED m_ovWrite;
OVERLAPPED m_ovRead;
OVERLAPPED m_ovWait;
HANDLE m_Thread;
};
#endif // COMP_H
cpp
#include "comp.h"
HANDLE hCom;
unsigned char d[8];
DWORD dwBytesWritten = 9;
DWORD dwErrorFlags=0;
COMSTAT ComStat;
OVERLAPPED m_osWrite;
BOOL bWriteStat;
bool a;
int i;
int flag=1;
int serialflag=0;
int receiveSign;
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
char RXBuff;
BYTE aaaa[4096];
Comp::Comp():
m_hCom(INVALID_HANDLE_VALUE),
m_IsOpen(false),
m_Thread(NULL)
{
memset(&m_ovWait, 0, sizeof(m_ovWait));
memset(&m_ovWrite, 0, sizeof(m_ovWrite));
memset(&m_ovRead, 0, sizeof(m_ovRead));
}
Comp::~Comp()
{
UninitCOM();
}
bool Comp::InitCOM(LPCTSTR Port,int bautrate)
{
m_hCom = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,NULL);
if (INVALID_HANDLE_VALUE == m_hCom)
{
return false;
}
SetupComm(m_hCom, 4096, 4096);//设置发送接收缓存
DCB dcb;//96n81模式
GetCommState(m_hCom, &dcb);
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = bautrate;//波特率
dcb.StopBits = ONESTOPBIT;//停止位数为1位
dcb.Parity = 0;//校验方式为无校验
dcb.ByteSize = 8;//数据位为8位
SetCommState(m_hCom, &dcb);//配置串口
PurgeComm(m_hCom, PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT);
COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = MAXDWORD;//两字符之间最大的延时,读取无延时,因为有WaitCommEvent等待数据
ct.ReadTotalTimeoutConstant = 0; //读时间常量
ct.ReadTotalTimeoutMultiplier = 0;// 读时间系数
ct.WriteTotalTimeoutMultiplier = 500;// 写时间系数
ct.WriteTotalTimeoutConstant = 5000;// 写时间常量
SetCommTimeouts(m_hCom, &ct);//配置读写超时
//创建事件对象
m_ovRead.hEvent = CreateEvent(NULL, false, false, NULL);
m_ovWrite.hEvent = CreateEvent(NULL, false, false, NULL);
m_ovWait.hEvent = CreateEvent(NULL, false, false, NULL);
SetCommMask(m_hCom, EV_ERR | EV_RXCHAR);//设置接受事件
//创建读取线程
m_Thread = (HANDLE)_beginthreadex(NULL, 0, &Comp::OnRecv, this, 0, NULL);
m_IsOpen = true;
return true;
}
void Comp::UninitCOM()
{
m_IsOpen = false;
if (INVALID_HANDLE_VALUE != m_hCom)
{
CloseHandle(m_hCom);
m_hCom = INVALID_HANDLE_VALUE;
}
if (NULL != m_ovRead.hEvent)
{
CloseHandle(m_ovRead.hEvent);
m_ovRead.hEvent = NULL;
}
if (NULL != m_ovWrite.hEvent)
{
CloseHandle(m_ovWrite.hEvent);
m_ovWrite.hEvent = NULL;
}
if (NULL != m_ovWait.hEvent)
{
CloseHandle(m_ovWait.hEvent);
m_ovWait.hEvent = NULL;
}
if (NULL != m_Thread)
{
WaitForSingleObject(m_Thread, 5000);//等待线程结束
CloseHandle(m_Thread);
m_Thread = NULL;
}
}
bool Comp::ComWrite(LPBYTE buf, int &len)
{
BOOL rtn = FALSE;
DWORD WriteSize = 0;
PurgeComm(m_hCom, PURGE_TXCLEAR|PURGE_TXABORT);
m_ovWait.Offset = 0;
rtn = WriteFile(m_hCom, buf, len, &WriteSize, &m_ovWrite);
len = 0;
if (FALSE == rtn && GetLastError() == ERROR_IO_PENDING)//后台读取
{
//等待数据写入完成
if (FALSE == ::GetOverlappedResult(m_hCom, &m_ovWrite, &WriteSize, TRUE))
{
return false;
}
}
len = WriteSize;
return rtn != FALSE;
}
unsigned int Comp::OnRecv(void *LPParam)
{
Comp *obj = static_cast<Comp*>(LPParam);
DWORD WaitEvent = 0, Bytes = 0;
BOOL Status = FALSE;
BYTE ReadBuf[4096];
DWORD Error;
COMSTAT cs = {0};
while(obj->m_IsOpen)
{
WaitEvent = 0;
obj->m_ovWait.Offset = 0;
Status = WaitCommEvent(obj->m_hCom,&WaitEvent, &obj->m_ovWait );
//WaitCommEvent也是一个异步命令,所以需要等待
if (FALSE == Status && GetLastError() == ERROR_IO_PENDING)//
{
//如果缓存中无数据线程会停在此,如果hCom关闭会立即返回False
Status = GetOverlappedResult(obj->m_hCom, &obj->m_ovWait, &Bytes, TRUE);
}
ClearCommError(obj->m_hCom, &Error, &cs);
if (TRUE == Status //等待事件成功
&& WaitEvent&EV_RXCHAR//缓存中有数据到达
&& cs.cbInQue > 0)//有数据
{
Bytes = 0;
obj->m_ovRead.Offset = 0;
memset(ReadBuf, 0, sizeof(ReadBuf));
//数据已经到达缓存区,ReadFile不会当成异步命令,而是立即读取并返回True
Status = ReadFile(obj->m_hCom, ReadBuf, sizeof(ReadBuf), &Bytes, &obj->m_ovRead);
PurgeComm(obj->m_hCom, PURGE_RXCLEAR|PURGE_RXABORT);
for(int i=0;i<4096;i++)
aaaa[i]=ReadBuf[i];
}
}
return 0;
}