串口通信--Qt

前言

最近给硬件组的同事做串口通信的界面,本来依凭着自己之前是电子信息专业的,自以为很快会完成的,但是现实总是和梦想相悖,架子搭出来了,一个字节的十六进制数据怎么也生成不了,难煞我,最终被人科普内存基础知识才恍然大悟,真是羞愧。

简言

Qt实现串口通信,挺简单的。Qt有封装好的类QSerialPort、QSerialPortInfo,只要熟悉这两个类,发送或接收数据是没问题的。对于界面通过串口控制硬件的操作来说,十六进制数据很重要,因为一般硬件接收的命令都是十六进制的,但是这个东西对于基础好的不算什么。

 

步骤

QSerialPort提供了访问串口的接口函数。使用辅助类QSerialPortInfo可以可用的串口信息。将QSerialPortInfo辅助类对象作为参数,使用setPort() 或setPortName()函数可以设置访问的串口设备。(要想对串口通信类更详细的了解,可参考博客http://blog.51cto.com/9291927/1879164)

在所有代码操作之前,要在pro文件里添加如下代码,添加串口通信模块。

QT       += serialport

当然在.h文件中,添加包含文件是少不了的。

#include<QSerialPort>
#include<QSerialPortInfo>

 

(1)串口设置和配置

 

设置访问的串口设备,上面已经说了要用到setPort() 或setPortName()函数。在本设计中,我通过下拉框来选择需要访问的串口,这里用到了串口辅助类QSerialPortInfo来获取系统可用的串口。具体代码如下:

为QComboBox添加项

foreach (const QSerialPortInfo &qspinfo, QSerialPortInfo::availablePorts())
          {
              ui->comboBox->addItem(qspinfo.portName());
          }

定义了一个槽函数,更改当前设置的串口设备

void SerialTest::changePort()
{
    QString portName=ui->comboBox->currentText();
    m_serialPort.close();
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
       if(info.portName()==portName)
        {
                m_serialPort.setPortName(info.systemLocation());
         }
    }
    m_isOpen=m_serialPort.open(QIODevice::ReadWrite);
    if(!m_isOpen)
    {
        qDebug()<<"open port is fail";
    }else{
        qDebug()<<"open port is successful";
    }

}

 

设置完需要访问的串口后,下面对串口进行配置,包括串口的波特率、数据位,奇偶校验、停止位等。在设置串口属性之前,先普及下基础知识:

 

①波特率:表示通信速度的参数,表示每秒传送bit的个数。

②数据位:表示通信中实际数据位的参数,表示有效数据位个数。

③奇偶校验:表示通信中检错方式。

④停止位:用于表示单个包的最后一位。典型的值为1,1.5和2。

配置代码如下:

QSerialPort m_serialPort;
m_serialPort.setDataBits(QSerialPort::Data8);
m_serialPort.setStopBits(QSerialPort::OneStop);
m_serialPort.setParity(QSerialPort::NoParity);
m_serialPort.setBaudRate(QSerialPort::Baud19200,QSerialPort::AllDirections);

 

(2)对串口的读写

串口的读写很简单,跟很多通信很像,都是用write()、read()或readAll(),都支持char* 和QByteArray。

本设计中只是给硬件发命令,有的有反馈有的没反馈,所以代码是这样书写的。data用来存储接收来的数据。

void SerialTest::sendOrder(QByteArray order, uchar* data)
{
    qDebug()<<m_serialPort.write(order);
    if(m_serialPort.waitForReadyRead(100))
    {
        m_serialPort.read((char*)data,16);
    }
}

十六进制

先说下(大白话),十六进制、十进制、ASCII码还是其他,最终都是转化成01二进制数据流,这个什么进制的只是方便人观看,他们只是一种显示方式。所以我们接收到是数据都是二进制数据流,这样转换成什么格式都是我们自己操作的。因为对硬件的都是十六进制显示的命令,所以这里也都是将接收的数据转化成十六进制进行显示,或者是将十六进制的数据发送出去。

 

接收的十六进制转字符串

因为uchar是一个字节,一个十六进制的数据大小也是一个字节(比如0xff),所以我是直接用一个数组接收(我接收的数据大小是16个字节,所以大小是16)。

uchar data[16]; 
memset(data,0,16);
m_serialPort.read((char*)data,16);

下面转化成十六进制,用的是QString::number()。

 QString str=QString::number(data[5],16)

当然,也可以用QByteArray接收数据。

        QByteArray data=m_serialPort.readAll();
        QString str=data.toHex();

 

字符串转十六进制

这个更简单,我只用了一行解决。

QByteArray type=QByteArray::fromHex(tr("B1").toLatin1());

 

结束语

这个串口通信界面的设计,让我深深的意识到自己的基础不扎实,所以没事的时候还是多看看C++基础知识吧,相信可以有很多收获。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值