串口初始化报错

串口初始化报错

这是自己的错 所以只是做笔记使用 对各位帮助可能不大

cpp文件

void MainWindow::showEvent(QShowEvent *event)
{
    StrDir = qApp->applicationDirPath();//当前目录
    OpenCfgFile();
    CheckExistPorts();
    initComPort(comPortName);
    if(isComOpen)
        tmrWatchCom->start(10); //设置溢出时间为10ms,并启动定时器
    defaultCondData();
    LoadCondData();
    isComOpen = 0;		//error
}

报错情况如下:

在这里插入图片描述
这里的初始化:
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>+
#include <QPainter>     //QPainter类在小部件和其他绘图设备上执行低级绘图。
#include <QMouseEvent>
#include <QPushButton>
#include <QToolBar>
#include <QTimer>
#include <QDateTime>
#include <QTextFrame>
#include <QMessageBox>
#include <windows.h>
#include <QQueue>
#include <datasource.h>
#include <qsqldatabase.h>
#include <QSqlQuery>
#include <qdebug.h>

#include "datasource.h"

namespace Ui {
class MainWindow;
}


//extern MainWindow * mainWin;
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    //构造函数
    explicit MainWindow(QWidget *parent = 0);
    //析构函数
    ~MainWindow();

    //设定虚函数
    virtual void showEvent(QShowEvent *event);
    virtual void paintEvent(QPaintEvent *event);//测试按钮图形展示
    virtual void mouseReleaseEvent(QMouseEvent *event); //鼠标事件
    virtual void closeEvent(QCloseEvent *event);        //关闭窗口事件

    //变量

    QString StrDir;
    //通讯串口
    QString comPortName;
    HANDLE idComDev;            //
    int isComOpen;                 //是否已打开
    DWORD LWpt,LRpt;            // 写出字节/读取字节的指针
    DWORD dwErrorFlag;          //定义了错误类型的32位变量
    OVERLAPPED ovlp;            //OVERLAPPED结构体指针
    COMSTAT state;              //返回设备状态的控制块 0|1
    unsigned char bufComSend[512],bufComRead[1024];
    QTimer *tmrWatchCom;

    QString nm_TestCond;        //最后一次的测试型号
    MEAS_COND condMeasure;
    QSqlDatabase dbCond;
    QSqlQuery *dbCondQuery;

    MEAS_PARAM paraMeasure;

    QPushButton* pButton;

    void OpenCfgFile();
    void SaveCfgFiel();

    void CheckExistPorts();                         //查询串口的函数
    int GetComPortsN();
    QString GetComPortStr(int idx);

    int initComPort(QString pnm);
    int comReadBytes(unsigned char *rbuf,int len);  //读入
    int comSendBytes(unsigned char *sbuf,int len);  //写出
    void comClose();                                //关闭串口
    int comWatchPort();                             //监控串口

    void defaultCondData();         //默认条件数据
    QString ledAry2String(unsigned char *ary);
    void Str2LedAry(QString str1,unsigned char *ary);

    int LoadCondData();
    /*-------myconddb---------*/
    bool ifTheCondExist(QString md);
    int CreateCondDb();
    bool DeleteOneCondByModel(QString md);
    bool UpdateOneCond(MEAS_COND cond);
    QQueue<MEAS_COND> QueryAllCond();
    MEAS_COND QueryOneCondByModel(QString md);
    bool AddOneCond(MEAS_COND cond);
    /*-------myresultdb---------*/



private slots:


    //系统设置
    void on_sysSettingBtn_triggered();

    //参数设置
    void on_paramEdit_triggered();

    //参数调用
    void on_paramLoad_triggered();

    //历史数据
    void on_historyData_triggered();

    //时间显示
    void on_tmrWatchCom();


    //显示最后一次测试型号
    void on_actionmeasCond_triggered();

private:
    Ui::MainWindow *ui;

};

#endif // MAINWINDOW_H

mainwindow.cpp文件:

void MainWindow::showEvent(QShowEvent *event)
{
    StrDir = qApp->applicationDirPath();//当前目录
    OpenCfgFile();
    CheckExistPorts();
    initComPort(comPortName);
    if(isComOpen)
        tmrWatchCom->start(10); //设置溢出时间为10ms,并启动定时器
    defaultCondData();
    LoadCondData();
}

串口主要源文件:comfile1.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

void MainWindow::CheckExistPorts()            //查询串口的函数
{
    HKEY   hKey;
    LONG   ret;
    OSVERSIONINFO     osvi;
//	BOOL   bOsVersionInfoEx;
    char   keyinfo[100],comm_name[200],ValueName[200];
    int   i;
    DWORD   sType,Reserved,cbData,cbValueName;

    ZeroMemory(&osvi,sizeof(OSVERSIONINFO));
  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    memset(keyinfo,0,100);
    strcpy(keyinfo,"HARDWARE\\DEVICEMAP\\SERIALCOMM");
    i=0;   sType=REG_SZ;  Reserved=0;
    GetVersionEx(&osvi);
//	bOsVersionInfoEx = GetVersionEx(&osvi);
  ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,keyinfo,Reserved,KEY_READ,&hKey);
    if(ret == ERROR_SUCCESS){
    ui->comboBoxPorts->clear();
      if(osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS){
            for(i=1;i<=128;i++){
                sprintf(comm_name,"COM%d",i);
                ui->comboBoxPorts->addItem((QString)comm_name);
            }
    }
    else if(osvi.dwPlatformId == VER_PLATFORM_WIN32_NT){
            do{
                cbData = 200;
                cbValueName = 200;
                memset(comm_name,0,200);
                memset(ValueName,0,200);
                ret = RegEnumValueA(hKey,i,ValueName,&cbValueName,NULL,&sType,(LPBYTE)comm_name,&cbData);
                if(strlen(comm_name) > 0){
                    ui->comboBoxPorts->addItem((QString)comm_name);
                }
                i++;
             }while(ret == ERROR_SUCCESS);
        }
    }
    RegCloseKey(hKey);
}

int MainWindow::GetComPortsN()
{
    int n;

    n = ui->comboBoxPorts->count();
    return n;
}

QString MainWindow::GetComPortStr(int idx)
{
    QString str1;

    str1 = ui->comboBoxPorts->itemText(idx);
    return str1;
}

int MainWindow::initComPort(QString pnm)
{
    int err;
    DCB dcb;
    QString str1;
    COMMTIMEOUTS to;
    QByteArray ba;
    char *cpt;

    if(isComOpen)
        CloseHandle(idComDev);
    str1 = comPortName;
    if(str1.length() > 4)
      str1 = "\\\\.\\"+str1;
    ba = str1.toLatin1();
    cpt = ba.data();
    idComDev = CreateFileA(cpt,GENERIC_READ|GENERIC_WRITE,0,NULL,
             OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
//             FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,NULL);
    if(idComDev==INVALID_HANDLE_VALUE){
        QMessageBox::question(this,tr("警告!"),tr("打开通讯口失败!"),QMessageBox::Yes | QMessageBox::Cancel);
      return 1;
    }
    SetupComm(idComDev,4096,1024);
    SetCommMask(idComDev,0);
    GetCommTimeouts(idComDev, &to);
    to.ReadIntervalTimeout = 4294967295;
    to.ReadTotalTimeoutMultiplier = 0;
    to.ReadTotalTimeoutConstant = 0;
    to.WriteTotalTimeoutMultiplier = 100;
    to.WriteTotalTimeoutConstant = 1000;
    SetCommTimeouts(idComDev, &to);
    err=GetCommState(idComDev,&dcb);
    if(!err){
        QMessageBox::question(this,tr("警告!"),tr("打开通讯口失败!"),QMessageBox::Yes | QMessageBox::Cancel);
      return 1;
    }
    dcb.BaudRate = 19200;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.fBinary = true;
    dcb.fParity = false;
    dcb.fOutxCtsFlow = false;
    dcb.fOutxDsrFlow = false;
    dcb.fDtrControl = DTR_CONTROL_DISABLE;
    dcb.fDsrSensitivity = false;
    dcb.fTXContinueOnXoff = true;
    dcb.fOutX = false;
    dcb.fInX = false;
    dcb.fErrorChar = false;
    dcb.fNull = false;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    dcb.fAbortOnError = false;
  /*  dcb.XonLim = ;
    dcb.XoffLim = ;
    dcb.XonChar = ;
    dcb.XoffChar = ;
    dcb.ErrorChar = ;
    dcb.EofChar = ;
    dcb.EvtChar = ;*/
    err=SetCommState(idComDev,&dcb);
    if(!err){
        QMessageBox::question(this,tr("警告!"),tr("打开通讯口失败!"),QMessageBox::Yes | QMessageBox::Cancel);
      return 1;
    }
    isComOpen = 1;
    return 0;
}

int MainWindow::comReadBytes(unsigned char *rbuf, int len)
{
    int err;

    if(!isComOpen){
        err = initComPort(comPortName);
        if(err){
          return 0;
        }
    }
    //从文件指针指向的位置开始将数据读出到一个文件中, 且支持同步和异步操作,
    //1.文件的句柄 2.用于保存读入数据的一个缓冲区 3.要读入的字节数 4.指向实际读取字节数的指针
    //5.如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。
    //5.该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
    ovlp.Internal = 0;
    ovlp.InternalHigh = 0;
    ovlp.Offset = 0;
    ovlp.OffsetHigh = 0;
    ovlp.hEvent = CreateEvent(NULL, true, false, NULL);
    ReadFile(idComDev,rbuf,len,&LRpt,&ovlp);
    return (int)LRpt;
}

int MainWindow::comSendBytes(unsigned char *sbuf, int len)
{
    if(!isComOpen){
        return 0;
    }
    //可以将数据写入一个文件或者I/O设备
    //1.文件句柄 2.数据缓存区指针 3.你要写的字节数 4.用于保存实际写入字节数的存储区域的指针 5.lpOverlapped  OVERLAPPED结构体指针
    ovlp.Internal = 0;
    ovlp.InternalHigh = 0;
    ovlp.Offset = 0;
    ovlp.OffsetHigh = 0;
    ovlp.hEvent = CreateEvent(NULL, true, false, NULL);
    //void* 在转换为其他数据类型时,赋值给void* 的类型 和目标类型必须保持一致
    WriteFile(idComDev,(void *)sbuf,(DWORD)len,&LWpt,&ovlp);
    return (int)LWpt;
}

void MainWindow::comClose()
{
    if(isComOpen)
        CloseHandle(idComDev);
    isComOpen = 0;
}

int MainWindow::comWatchPort()
{
    int i;
     //ClearCommError函数的
    //第一个参数hFile是由CreateFile函数返回指向已打开串行口的句柄。
    //第二个参数指向定义了错误类型的32位变量。
    //第三个参数指向一个返回设备状态的控制块COMSTAT。如果函数调用成功,则返回值为非0;若函数调用失败,则返回值为0
    ClearCommError(idComDev,&dwErrorFlag,&state);
    i = state.cbInQue;
    return i;
}

就是在showEvent里面 初始化后,又赋了一次值,所以会再次打开页面的时候,报错。

谢谢 一起学习 [email protected]

猜你喜欢

转载自blog.csdn.net/qq_45646951/article/details/106781713