Qt操作串口

阿紫 posted @ 2012年7月25日 17:44 in Qt , 6244 阅读

    以前写的串口通讯的工具,最近没事整理了一下记录下来。由于Qt没有实现关于串口操作的类,所以一般情况下可以自己写线程实现,也可以使用第三方类。这里使用第三方类。可以到网上去下载,也有关于这个第三方类的介绍。这里不多说了,在win下,主要就是下载这几个文件:qextserialbase.h,qextserialport.h,win_qextserialport.h,qextserialbase.cpp,qextserialport.cpp,win_qextserialport.cpp。如果是在linux下,则把win_qextserialport.h和win_qextserialport.cpp替换为posix_qextserialport.h和posix_qextserialport.cpp这两个文件即可。

    自动识别COM口:通过读注册表实现(当然linux下不可用)。

class mainwindow : public QMainWindow,public Ui_mainwindowClass
{
	Q_OBJECT

	public:
		mainwindow();
		~mainwindow(){};

	public:
		QString getcomm(int index,QString keyorvalue); //读取键名

	private:
		void init_com();
		Win_QextSerialPort *myCom;//声明对象
                QTimer *timer;
		QStringList m_listCommand;	//待发送的命令
		wchar_t subkey[80];
		wchar_t keyname[256]; //键名数组
		char keyvalue[256];  //键值数组
		int indexnum;
		DWORD keysize,type,valuesize;
		HKEY hKey;
        ......
}

 

void mainwindow::init_com()
{
	QString path="HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM";
	QSettings *settings=new QSettings(path,QSettings::NativeFormat);
	QStringList key=settings->allKeys();
	QStringList comlist ;
	QStringList Baudlist ;
	QStringList Paritylist ;
	QStringList DataBitslist;
	QStringList StopBitslist;
	QStringList ControlFlowlist;

	int kk = key.size();
	int i;
	comlist.clear();
	for(i=0;i<kk;i++)
	{
		comlist << getcomm(i,"value");
	}
	comboBox->addItems(comlist);

	//波特率
	Baudlist.clear();
	Baudlist<< "300" << "600" << "2400" << "4800" << "9600"<< "19200" << 
			 "56000" << "57600" << "115200"<<"128000"<<"256000"<< "921600";
	baudRateComboBox->addItems(Baudlist);

	......
}

QString mainwindow::getcomm(int index,QString keyorvalue)
{
	QString commresult="";
	QString strkey="HARDWARE\\DEVICEMAP\\SERIALCOMM";//子键路径
	int a=strkey.toWCharArray(subkey);
	subkey[a]=L'\0';
	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,KEY_READ|KEY_QUERY_VALUE,&hKey)!=0)
	{
		QString error="Cannot open regedit!";
	}

	QString keymessage="";//键名
	QString message="";
	QString valuemessage="";//键值
	indexnum=index;//要读取键值的索引号

	keysize=sizeof(keyname);
	valuesize=sizeof(keyvalue);

	if(::RegEnumValue(hKey,indexnum,keyname,&keysize,0,&type,(BYTE*)keyvalue,&valuesize)==0)
	{
		//读取键名
		for(int i=0;i<keysize;i++)
		{
			message=QString::fromStdWString(keyname);
			keymessage.append(message);
		}
		//读取键值
		for(int j=0;j<valuesize;j++)
		{
			if(keyvalue[j]!=0x00)
			{
				valuemessage.append(keyvalue[j]);
			}
		}

		if(keyorvalue=="key")
		{
			commresult=keymessage;
		}
		if(keyorvalue=="value")
		{
			commresult=valuemessage;
		}
	}
	else
	{
		commresult="nokey";
	}
	::RegCloseKey(hKey);//关闭注册表
	return commresult;
}

接下来便是打开并设置串口,注意,写串口程序时要先打开串口,然后再对它进行设置,否则设置就不会起作用。打开串口时,端口号在9以下的(包括9)与大于9的打开方式不同。

 

QString m_port = port_name.right(port_name.length()-3);
if(m_port.toInt()>9)
{
	QString xx = "\\\\.\\";
	xx.append(port_name);
	myCom->setPortName(xx);
}
else
{
	myCom->setPortName(port_name);
}

myCom->open(QIODevice::ReadWrite);

另外一个就是发送数据后,最好使用这句

 

connect(myCom,SIGNAL(readyRead()),this,SLOT(readMyCom()));//信号和槽关联,等串口缓冲区有数据时再进行读串口操作

等待串口有数据时再进行读。

 

QString str=sendEdit->toPlainText();//将sendEdit内容提取到str中
str.append("\r\n");
QByteArray aa=str.toAscii();
const char * strdata=aa.data();
int rec=myCom->writeData(strdata,qstrlen(strdata));
myCom->flush();

 

void mainwindow::readMyCom()
{	
	char buf[1024];
	memset(buf, 0, sizeof(buf));
	qint64 temp=myCom->readData(buf,sizeof(buf));
	buf[temp+1]=0;
}
  • 无匹配
kevin 说:
2015年5月06日 22:02

挺好的,刚好嫩用到,多谢了


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter