Qt串口通讯(Qt类和C++类)

使用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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值