串口初始化报错
这是自己的错 所以只是做笔记使用 对各位帮助可能不大
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]