Ruiko’s com

今天尝试了一波Qt实现比较经典的串口助手,能够完成串口数据的收发功能,采用的控件包括QCmoBox、QPushButton、QEditBox等,串口助手中可以设置的部分包括串口、数据位、停止位、校验位、波特率、流控制

第一步实现的功能是启动QCreator能够自动检测电脑可用的串口,之所以如此设计是因为后续需要用到具体的串口号及其一些其它的附属设置,而QSerialPortInfo提供了具体的信息查询功能实现

foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
	qDebug()<< "Name : "<<info.portName();
	qDebug()<< "Description : "<<info.description();
	qDebug()<< "Manufacturer: "<<info.manufacturer();
	qDebug()<< "Serial Number: "<<info.serialNumber();
	qDebug()<< "System Location: "<<info.systemLocation();
}

此部分代码是遍历可用的串口及其附属的信息,其内部的具体实现方式是怎样依托类实现的暂且不能够深究,只需要指导foreach这个方式可以实现对一个集合的遍历

foreach(const Typedef *,Typedef availble)

前述定义的变量类型,不仅是单一的变量可能,也可能是已经封装好模式,必须是与后续集合变量内部的定义是相同的,如此才能够实现遍历

接下来在上述的基础上进一步深入,QSerialPort类模式,此类可以调用设置串口的一些基本函数

if(serial.open(QIODevice::ReadWrite)==true)
{
	ui->Chuankou->addItem(serial.portName());
	serial.close();
}

读写方式对串口进行可用打开,实际上也是遍历式的打开,而serial这个串口型类变量又是如何进行定位的呢?我想至少得有一个设定是某个串口的类似于指针的变量吧

serial.setPort(info);

这个info是QSrialPortInfo类,涉及的是每次自动遍历读取到的串口信息集合,当然info的具体内容可能并不是很清楚,这里其实上面已经解释过了,为何先要了解具体的串口信息,甚至专门写了一部分代码

串口信息打印

所以可以猜测一波上面的代码是将info的串口类定位赋给serial类,此时serial执行的操作将是针对某一个com口位的,因此检测串口是否打开成功也是逐一检测,当能够被以读写方式打开的串口存在时,才将其写入可调用的下拉列表范围

在此基础上实际上已经完成了三分之一工作,因为剩下的是针对选择的串口进行配置和具体的操作结构,配置采用QComBox类结构,进行可预设选择性读取,而“打开”串口按钮实现将配置执行

在此函数内部,执行读取相应的信息问题,包括串口号、数据位、停止位、校验位、波特率,当然,这些是在上面已经初始化基础上选定的,读取完毕即开始打开并设置,我比较不能理解的是,什么定位到了指定的串口上,然后进行打开呢?还是只是识别规定的字符形式和一些设置呢?

serial.setPortName(ui->Chuankou->currentText());

我只能认为这行代码完成了指定串口的操作,其它的代码都必须放在这句代码之后开始执行才能够达到指定的效果,尤其是验证串口打开的语句

关闭则是比较简单了,一句代码足矣

serial.close();

其实看了别人写的比较好的设计之后才了解到,里面的程序架构设计真的还有很大的优化空间,比如按钮如何实现共用!

ui->Open->setText(QString("关闭"));
ui->Open->setText(QString("打开"));

上述的操作完成了指定串口的初始化和打开功能,剩下的是如何实现数据的发送和接收功能,这里将QSerialPort的serial定义为全局变量,实际上在校验串口可用性并写入时应该不需要用到,因为在此之后又将串口关闭了,但是,进行配置并打开之后,如果单独的在槽函数内部定义,则发送和接收可能会有问题,毕竟类这种东西可能会伴随着很强的指针操作!

extern QSerialPort serial;

可能之前的工程性文件写的比较多,所以这里有点习惯性的感觉,就给加上了,接下来的设计发送和响应函数时,自然也用到了serial变量

serial.write(sendData_2);
buf = serial.readAll();

读写貌似很简单,但是里面还是很有讲究的,单纯的读写字符实际上也有点讲究,更何况有时候还需要进行进制转换发送以及一些变换,更深层次的可能会要求发送文件等,这些都是可扩展的行为,在这里不做深入的讨论

当此上位机充当主机时,则进程为发送,点击发送按钮执行的是发送函数(槽函数),数据将被从发送框读取并发送到下位机!里面的一些细节之类的这里不多说,可以参照文章最后附上的源码,充当下位机时,负责的是接收,这里自然调用接收函数,读取数据并显示

疑问的是,读取通过什么触发呢?这类似于一个中断函数,接收数据完毕时会触发一次,跳转到指定的槽函数处理,此时connect类就起作用了!

connect(&serial, &QSerialPort::readyRead, this, &MainWindow::ReadData);

综合起来就完成了简单的串口助手,源码的下载点我:Ruiko’s com

注意,上位机本身不能同时发送接收数据,而硬件调试很麻烦,因此虚拟串口助手推荐一波,下载即可:虚拟串口助手

测试的挺好,能够发送和接收字符,顺便抽了个时间给软件换了个ico,背景计划换成图片的但是有点问题因此放弃了

还有一个问题是,Qt编写的文件制作安装包有点麻烦,不像之前的Python那样利于编译集成,貌似有专属的安装包设计过程,以后熟练后制作一波,这里制作失败,额,也还算完成了今天90%的计划,继续加油!

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注


皖ICP备2021003932号
召唤伊斯特瓦尔