qt 串口通信

qt串口通信:需要用到QSerialport类。
1、pro文件中添加QT += serialport。
2、获取当前有哪些串口设备(QSerialPortInfo::availablePorts()))。
3、设置要打开的串口(setPortName),然后打开(open)。
4、设置串口的参数,波特率,数据位,控制位,奇偶未和停止位(setBaudRate,setDataBits,setFlowControl,setParity,setStopBits)
5、写数据和读数据。

虚拟串口百度云分享:
链接: https://pan.baidu.com/s/1sE_lFneZaFo8mvIYW4JA8Q 提取码: m8cn
如果只是练习,可以使用虚拟串口工具创建两个虚拟串口com6和com7.qt 串口通信_第1张图片
串口调试助手百度云分享:
链接: https://pan.baidu.com/s/1W3dSIrqxFDNhxMeGKRCUzg 提取码: 3wwq
然后和三方的串口调试工具通信,一个打开com6,一个打开com7.
qt 串口通信_第2张图片
如果不用第三方串口调试助手,可以自己开两个程序,一个打开com6,一个打开com7.
qt 串口通信_第3张图片
.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include 
#include 
#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    void convertStringToHex(const QString &str, QByteArray &byteData);
    char convertCharToHex(char ch);
    ~Widget();

private slots:
    void slotLoadSerialPort();
    void slotOpenSerialPort();
    void slotReadData();
    void slotSend();
    void slotCloseSerialPort();
private:
    Ui::Widget *ui;
    QPushButton* m_loadportbtn;
    QPushButton* m_openSerialPortbtn;
    QPushButton* m_sendbtn;
    QPushButton* m_closeSerialPortbtn;
    QComboBox* m_serialportbox;
    QComboBox* m_baudratebox;
    QComboBox* m_databitbox;
    QComboBox* m_stopbitbox;
    QComboBox* m_paritybox;
    QComboBox* m_flowcontrolbox;
    QLabel* m_portlab;
    QLabel* m_Baudratelab;
    QLabel* m_DataBitlab;
    QLabel* m_FlowControllab;
    QLabel* m_StopBitlab;
    QLabel* m_Paritylab;
    QLabel* m_readlab;
    QLineEdit* m_sendedit;
    QTextEdit* m_readedit;

    QStringList m_flowcontrollist;
    QStringList m_paritylist;
    QStringList m_stopbitlist;
    QStringList m_databitlist;
    QStringList m_baudratelist;
    QSerialPort* m_serialPort;
};

#endif // WIDGET_H


#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    m_serialPort = nullptr;
    m_portlab = new QLabel("端口:",this);
    m_serialportbox = new QComboBox(this);
    m_loadportbtn = new QPushButton("加载端口",this);
    m_openSerialPortbtn = new QPushButton("打开串口",this);
    m_closeSerialPortbtn = new QPushButton("关闭串口",this);
    m_Baudratelab = new QLabel("数据位:",this);
    m_DataBitlab = new QLabel("数据位:",this);
    m_FlowControllab = new QLabel("控制流:",this);
    m_Paritylab = new QLabel("校验位:",this);
    m_StopBitlab = new QLabel("停止位:",this);
    m_baudratebox = new QComboBox(this);
    m_databitbox = new QComboBox(this);
    m_flowcontrolbox = new QComboBox(this);
    m_paritybox = new QComboBox(this);
    m_stopbitbox = new QComboBox(this);
    m_sendbtn = new QPushButton("发送",this);
    m_sendedit = new QLineEdit(this);
    m_readlab = new QLabel("接收:",this);
    m_readedit = new QTextEdit(this);

    QGridLayout* lay = new QGridLayout(this);
    lay->addWidget(m_loadportbtn,0,0,1,2);
    lay->addWidget(m_portlab,1,0,1,1);
    lay->addWidget(m_serialportbox,1,1,1,1);
    lay->addWidget(m_Baudratelab,2,0,1,1);
    lay->addWidget(m_baudratebox,2,1,1,1);
    lay->addWidget(m_DataBitlab,3,0,1,1);
    lay->addWidget(m_databitbox,3,1,1,1);
    lay->addWidget(m_FlowControllab,4,0,1,1);
    lay->addWidget(m_flowcontrolbox,4,1,1,1);
    lay->addWidget(m_Paritylab,5,0,1,1);
    lay->addWidget(m_paritybox,5,1,1,1);
    lay->addWidget(m_StopBitlab,6,0,1,1);
    lay->addWidget(m_stopbitbox,6,1,1,1);
    lay->addWidget(m_openSerialPortbtn,7,0,1,2);
    lay->addWidget(m_closeSerialPortbtn,8,0,1,2);
    lay->addWidget(m_sendedit,9,0,1,1);
    lay->addWidget(m_sendbtn,9,1,1,1);
    lay->addWidget(m_readlab,10,0,1,1);
    lay->addWidget(m_readedit,11,0,1,2);
    this->setLayout(lay);

    m_flowcontrollist<<"无"<<"硬控制"<<"软控制";
    m_paritylist<<"No"<<"Even"<<"Odd"<<"Space"<<"Mark";
    m_baudratelist<<"1200"<<"2400"<<"4800"<<"9600"<<"19200"<<"38400"<<"57600"<<"115200";
    m_databitlist<<"5"<<"6"<<"7"<<"8";
    m_stopbitlist<<"1"<<"2"<<"1.5";
    m_baudratebox->addItems(m_baudratelist);
    m_databitbox->addItems(m_databitlist);
    m_flowcontrolbox->addItems(m_flowcontrollist);
    m_paritybox->addItems(m_paritylist);
    m_stopbitbox->addItems(m_stopbitlist);

    connect(m_loadportbtn,SIGNAL(clicked()),this,SLOT(slotLoadSerialPort()));
    connect(m_openSerialPortbtn,SIGNAL(clicked()),this,SLOT(slotOpenSerialPort()));
    connect(m_closeSerialPortbtn,SIGNAL(clicked()),this,SLOT(slotCloseSerialPort()));
    connect(m_sendbtn,SIGNAL(clicked()),this,SLOT(slotSend()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::slotLoadSerialPort()
{
    QStringList m_serialPortName;
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) //获取有效的串口列表
    {
        m_serialPortName << info.portName();
        qWarning()<<"serialPortName:"<clear();
    m_serialportbox->addItems(m_serialPortName);
}

void Widget::slotCloseSerialPort()
{
    if (m_serialPort)
        m_serialPort->close();
}

void Widget::slotOpenSerialPort()
{
    m_serialPort = new QSerialPort(this);

    if(m_serialPort->isOpen())
    {
        m_serialPort->clear();
        m_serialPort->close();
    }
    m_serialPort->setPortName(m_serialportbox->currentText());

    if (!m_serialPort->open(QIODevice::ReadWrite))
    {
        qWarning()<<"打开串口"<currentText()<<"失败";
        return;
    }

    m_serialPort->setBaudRate(m_baudratebox->currentText().toInt());
    m_serialPort->setDataBits((QSerialPort::DataBits)(m_databitbox->currentIndex()+5));
    m_serialPort->setFlowControl((QSerialPort::FlowControl)m_flowcontrolbox->currentIndex());
    int parity = m_paritybox->currentIndex();
    if (parity > 0)
        parity++;
    m_serialPort->setParity((QSerialPort::Parity)parity);
    m_serialPort->setStopBits((QSerialPort::StopBits)(m_stopbitbox->currentIndex()+1));

    qWarning()<<"打开串口"<currentText()<<"成功";

    connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(slotReadData()));
}

void Widget::slotReadData()
{
    QString data = m_serialPort->readAll();
    qWarning()<<"接收数据:"<append("接收数据:"+data);
}

void Widget::slotSend()
{
    if (m_serialPort)
    {
        if (!m_serialPort->isOpen())
            qWarning()<<"请打开一个串口";

        QString info = m_sendedit->text();
        QByteArray sendBuf;
//        if (info.contains(" "))
//        {
//            info.replace(QString(" "),QString(""));//我这里是把空格去掉,根据你们定的协议来
//        }
//        convertStringToHex(info, sendBuf); //把QString 转换 为 hex
        qWarning()<<"发送数据:"<baudRate()<dataBits()<flowControl()<parity()<stopBits();

        sendBuf = info.toLocal8Bit();
        m_serialPort->write(sendBuf);
    }
}

//Qstring 转为 16进制的函数
void Widget::convertStringToHex(const QString &str, QByteArray &byteData)
{
    int hexdata,lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    byteData.resize(len/2);
    char lstr,hstr;
    for(int i=0; i= len)
            break;
        lstr = str[i].toLatin1();
        hexdata = convertCharToHex(hstr);
        lowhexdata = convertCharToHex(lstr);
        if((hexdata == 16) || (lowhexdata == 16))
            break;
        else
            hexdata = hexdata*16+lowhexdata;
        i++;
        byteData[hexdatalen] = (char)hexdata;
        hexdatalen++;
    }
    byteData.resize(hexdatalen);
}

//另一个 函数 char 转为 16进制
char Widget::convertCharToHex(char ch)
{
    /*
            0x30等于十进制的48,48也是0的ASCII值,,
            1-9的ASCII值是49-57,,所以某一个值-0x30,,
            就是将字符0-9转换为0-9

            */
    if((ch >= '0') && (ch <= '9'))
        return ch-0x30;
    else if((ch >= 'A') && (ch <= 'F'))
        return ch-'A'+10;
    else if((ch >= 'a') && (ch <= 'f'))
        return ch-'a'+10;
    else return (-1);
}


注意:如果是在UBuntu系统上,你会发现有点不一样,串口可能打不开。
解决方法如下:
如果是第一次在UBuntu上打开串口,串口名一般为ttyUSB0,需要给串口设置权限,否则是无法打开成功的。设置权限方法如下:
方法一:

sudo chmod 666 /dev/ttyUSB0

方法二:
添加配置

sudo vim /etc/udev/rules.d/20-usb-serial.rules

内容为

KERNEL=="ttyUSB*"  MODE="0666"

匹配内核以 ttyUSB 开头的驱动, 权限为 666
使配置生效

sudo service udev reload
sudo service udev restart

如果不想修改权限, 还有一种方法是当前用户加入 dialout 组(ttyUSB0 设备文件属于这个组), 加入这个组后就有权限了, 之后重启一下

sudo usermod -aG dialout jianghuixin

详情介绍

你可能感兴趣的:(c/c++,QT,c语言,c++,qt,qt4,qt5)