历史上的今天
返回首页

历史上的今天

今天是:2025年02月26日(星期三)

正在发生

2020年02月26日 | 用qt编写上位机与stm32通信

2020-02-26 来源:eefocus

好的文章 

1、Qt5.5.1实现通用串口程序https://www.2cto.com/kf/201607/524028.html 

2、QT实现串口通信 https://www.2cto.com/kf/201610/558768.html


资源下载:https://download.csdn.net/download/hellybobo/9950904?web=web


本文采用的的开发环境是VS2010+Qt5.5.1版本,所有程序不是通过Qt Creator编译的,如果有需要可以介绍VS2010和Qt环境的搭建和简单的使用。


QSerialPort

QSerialPort这个类是从QT5.1开始引入的,之前都是通过QIODevice自己定义串口类,从而实现串口程序的开发。现在引入这个类了,将会非常方便的开发串口程序。为了使用这个类,需要在工程目录和附加依赖项中加入include的路径,以及链接库的路径,以及链接库的名称:


项目—>属性—> C++ —> 常规 —>C:QtQt5.5.15.5msvc2010includeQtSerialPort项目—>属性—> 输入++ —> 附加依赖项—>Qt5SerialPort.lib(如果是Debug版本,则是Qt5SerialPortd.lib)版本源文件或者头文件需要加入#include 串口的信息可以通过QSerialPortInfo类获得,通过这个类,你可以正确的确定你要开启的串口,同时可以获得串口的描述性信息以及厂家信息。串口有三种打开模式,即ReadOnly,WriteOnly,以及ReadWrite。同时可以设置其停止位,波特率,数据位,校验方式以及流控,对应的函数方式分别为:setStopBits(),setBaudRates(),setDataBits(),setParity(),以及setFlowControl()。 


串口数据的写入是通过writeData(const char * data, qint64 maxSize)以及write(const char * data, qint64 maxSize),前者是protected属性,只能在子类中访问,而后者则是public属性。在串口打开并且具有可写属性,即可通过write函数写入数据。


串口数据的读入是通过 readData(char * data, qint64 maxSize) ,read(qint64 maxSize)实现的,如果需要一次性读完所有的数据,则可以通过readAll()全部读取串口缓冲区中的数据。


串口内部的缓冲区大小可以通过:setReadBufferSize(qint64 size)实现。当设定缓冲区大小时,串口只能接收size大小的数据流,因此存在数据丢书的可能。当设置为0的时候,并不是指的缓冲区大小为0,而是无穷大,这样就可以保存数据的全部接收完整。这是缓冲区大小的默认属性。


是否有新的数据读入缓冲区是通过readReady()信号来来确定的。这是通过时间驱动的方式来确定是否有数据可以读入。此外还有waitForReadyRead()来等待轮询是否有数据到达串口,但是这是一种阻塞性读入,个人觉得不是太好,所以写串口的时候采用的是事件驱动的方式来确定是够有数据可以读入。


QSerialPortInfo

Use the static functions to generate a list of QSerialPortInfo objects. Each QSerialPortInfo object in the list represents a single serial port and can be queried for the port name, system location, description, and manufacturer. The QSerialPortInfo class can also be used as an input parameter for the setPort() method of the QSerialPort class.


可能会用得比较多的函数是description(),manufacturer(),以及serialNumber()。从而得到描述性信息,比如通信端口。USB转串口等描述串口的信息、串口的生产商信息以及串口名,在电脑上表现为COM~等。


如何获取电脑上所有的串口

void CameraSerialPort::getSerialPortID()

{

     serialInfo=new QSerialPortInfo();

     serialList=serialInfo->availablePorts();

    int nSerialnum=serialList.length();

    for(int i=0;iaddItem(serialName);

    }


    QString currentPort=serialPortAssitant.serialPortcomboBox->currentText();

    portToOpen=currentPort;

    QString  portStatus=currentPort+" closed";

    serialPortAssitant.status->statusInfo->setText(portStatus.toUpper());

    QPalette font_palette;

    font_palette.setColor(QPalette::WindowText,Qt::red);

    serialPortAssitant.status->statusInfo->setPalette(font_palette);


因为直接从自己的项目文件拷过来的源码,这里稍微介绍一下属性:


1、变量的定义,在头文件中,这里没有贴出来,截取定义如下:


QSerialPortInfo* serialInfo;

QListserialList;

1

2

2、QListavailablePorts() 返回的是一个关于QSerialPortInfo的列表,在数据结构QList中存储。 

3、serialPortcomBox是一个QComboBox,下拉列表。


4、最后几行是用来显示串口的状态信息,达到的效果如图: 

这里写图片描述

打开串口并且通过串口写数据

得到串口信息后,就可以选择端口,进行打开和读写数据。贴出代码,然后在给分析分析:


void CameraSerialPort::Write()

{

    QString sendMsg=serialPortAssitant.sendLine->text();

    QByteArray temp=sendMsg.toLatin1();

    if(IsSendByHex)

    {

        temp=HexStrToByteArray(sendMsg);

    }

    char *sendContent=temp.data();

    qint64 sendedNum=serialPort->write(sendContent,temp.count());


    //---------------判断发送数据是否成功----------------------//

    if(sendedNum==-1)

    {

        errorValue=serialPort->error();

        if(IsShowCurrentTime)

        {

            errorInfo=" ";

            currentTime=QDateTime::currentDateTime();

            timeinfo=currentTime.toString("yyyy__MM__d__hh:mm:ss");

            errorInfo=QString::fromLocal8Bit("错误提示信息   ");

            errorInfo+=timeinfo;

            errorInfo+="n";

        }

        else

        {

            errorInfo=" ";

            errorInfo=QString::fromLocal8Bit("错误提示信息   ");

            errorInfo+="n";

        }

        serialPortAssitant.ReciveWidget->append(errorInfo+getValueContent(errorValue));

        return;

    }

    //-------------显示发送数据-----------------------//


    //temp的size的依据是是否以16进制发送

    sendCount+=temp.count();

    serialPortAssitant.status->TxByte->setText(QString::number(sendCount));

    QString showSendMsg;

    if(IsShowSendMsg)

    {

        if(IsShowCurrentTime)

        {


            currentTime=QDateTime::currentDateTime();

            timeinfo=currentTime.toString("yyyy__MM__d__hh:mm:ss");

            showSendMsg+=QString::fromLocal8Bit("发送数据 : ");

            showSendMsg+=timeinfo;

            showSendMsg+="n";

            //判断显示16进制还是ACSII字符

            if(IsSendByHex)

                showSendMsg+=ByteArrayToHexStr(temp);

            else

                showSendMsg+=temp;

        }   

        else

        {

            showSendMsg=QString::fromLocal8Bit("发送数据 : ");

            if(IsSendByHex)

                showSendMsg+=ByteArrayToHexStr(temp);

            else

                showSendMsg+=temp;


        }   

        serialPortAssitant.ReciveWidget->append(showSendMsg);


    }   

    IsWrittenSuccessed=true;

}


void CameraSerialPort::sendData()

{

    if(!IsSerialPortOpen)

    {

            if(serialPort!=NULL)

            {

                serialPort->close();

            }

            serialPort=new QSerialPort(portToOpen);

            if(serialPort==NULL)

            {

                errorValue=serialPort->error();

                QString errorContent=getValueContent(errorValue);

                if(IsShowCurrentTime)

                {

                        errorInfo=" ";

                        currentTime=QDateTime::currentDateTime();

                        timeinfo=currentTime.toString("yyyy__MM__d__hh:mm:ss");

                        errorInfo=QString::fromLocal8Bit("错误提示信息   ");

                        errorInfo+=timeinfo;

                        errorInfo+="n";

                }

                    else

                {

                        errorInfo=" ";

                        errorInfo=QString::fromLocal8Bit("错误提示信息   ");

                        errorInfo+="n";

                }

                    serialPortAssitant.ReciveWidget->append(errorInfo +errorContent+QString::fromLocal8Bit(", 请重新选择正确的端口n"));

                    return;     

            }


        if(!serialPort->open(QIODevice::ReadWrite))

        {

            errorValue=serialPort->error();

            QString errorContent=getValueContent(errorValue);

            if(IsShowCurrentTime)

            {

推荐阅读

史海拾趣

Eurotech公司的发展小趣事

Eurofarad公司自创立之初,就专注于电容器技术的研发。在当时,电容器市场已经相当成熟,但Eurofarad公司凭借对材料科学的深入研究,成功开发出一种新型的高性能电容器。这种电容器不仅具有更高的能量密度,而且寿命更长,稳定性更好。这一技术突破为Eurofarad公司赢得了市场的初步认可,也为公司后续的发展奠定了坚实的基础。

Advanced Thermal Products Inc公司的发展小趣事

ATP公司深知品质是企业生存和发展的基石。因此,他们建立了严格的质量管理体系,从原材料采购到产品出厂的每一个环节都进行严格把控。同时,公司注重品牌建设,通过广告宣传、参加展会等方式提升品牌知名度和美誉度。这些举措使得ATP公司在市场上逐渐树立了良好的品牌形象。

富瀚(Fullhan)公司的发展小趣事
观察电动机保护器是否在达到过载条件后迅速切断电源。如果保护器正常工作,电动机应停止运行,且保护器上的指示灯或显示屏会显示相应的过载保护信息。
兵字(BingZi)公司的发展小趣事

随着市场的不断变化和客户需求的日益多样化,兵字公司意识到,要想在市场中保持领先地位,就必须不断进行技术创新。于是,公司投入大量研发资源,成功研发出了小型精密互感器。这一创新产品不仅填补了市场空白,还为公司带来了可观的收益。同时,兵字公司也凭借这一技术突破,进一步巩固了在电子元器件领域的领先地位。

BOT公司的发展小趣事

广西来宾电厂是中国第一个国家正式批准的BOT试点项目。该项目由法国电力国际和通用电气阿尔斯通公司作为项目公司的主要股东,总投资为6.16亿美元。这个电厂的装机规模为72万千瓦,安装了两台36万千瓦的进口燃煤机组。在长达18年的特许经营期内,该项目为广西地区提供了稳定的电力供应,同时也为项目公司带来了可观的投资回报。随着时间的推移,该项目成为了BOT模式在中国成功应用的典范,为后来的类似项目提供了宝贵的经验。

Big-Sun Electronics Co Ltd公司的发展小趣事

面对电子行业的快速变化和市场竞争的加剧,Big-Sun Electronics Co Ltd公司积极实施多元化战略。公司不仅继续深耕电子芯片领域,还逐步拓展至智能家居、物联网等新兴领域。通过产业转型和升级,Big-Sun成功实现了业务的多元化发展,为公司的可持续发展奠定了坚实基础。

问答坊 | AI 解惑

公司委托我招兵买马:玩具类电子工程师

企业名称: 东莞市康大五金电子厂 营业执照: 4419002356421 工厂地址: 东莞万江区共联管理区 本公司成立于1998年,港资独资企业; 公司已通过ISO9001:2000认证; 公司员工超过7000人,实行人性化管理; 所有职位包食宿,并提 ...…

查看全部问答>

关于共射放大电路的失真问题

问一下各位,放大电路产生不对称失真是什么原因啊,即输出波形的正负半波幅值,时间不对称。…

查看全部问答>

小心别上当!曝光“电子驱蚊灭鼠器”_applevista

作者:applevista 前两天,父亲在庙会上买了两个黑猫神牌电子驱蚊灭鼠器,5块一个。 前两年,见过这样东西,样子不一样,也提醒父亲这是骗人的,还是被骗了。 要是一块一个倒也不错,它其实就是一个简单的彩灯。 这个与卫星增台器、节电器一样 ...…

查看全部问答>

cadence问题3求助!!

请教各位高手 我在画原理图时(orcad) 有下列两个疑问: 1、请问处理器(在page1上)上的一个引脚如A1需要连接两个外围芯片x,y    可是芯片X我是用层次法(层次图上层在page1上)画的,与芯片y的连接是用平坦式画法     ...…

查看全部问答>

F2812编译顺利通过,烧写时提示如下错误,为什么呢?

**** Begin Erase/Program/Verify Operation. *** Erase/Program/Verify Operation in progress... Erase operation in progress... Erase operation was successful. Program operation in progress... Flash API Error #31: There was a Ze ...…

查看全部问答>

编译时给出的警告

Error[Ms003]:could not open file \"E:\\A\\Debug\\obj.r43\" for writing 以上是什么原因啊? 用的IAR…

查看全部问答>

每天复习一些ARM指令及汇编

ARM处理器寻址方式 寻址方式是根据指令中给出的地址码字段来实现寻找真实操作数地址的方式,ARM 处理器有9种基本寻址方式。 寄存器寻址 操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直 接取出寄存器值操作。 ...…

查看全部问答>

stm32f207的外扩NAND flash读取ID问题

本人想用stm32f207VG做下外扩NAND flash,先读取ID不行,GPIO配置如下:   RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC,ENABLE);   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE |     ...…

查看全部问答>