串口通信

一、串口通信原理

  处理器与外部设备通信的方式有串行通信和并行通信的方式,串口通信是串行通信。

   同步通信:带有时钟同步信号的数据传输。发送端和接收端在同一时钟的控制下,同步传输数据。

  异步通信:不带有时钟同步信号的数据传输。发送端和接收端使用各自不同的时钟控制数据的发送和接收过程。

  单工模式:数据传输是单向的,通信双方中,一方固定为发送端,一方固定为接收端,信息只能沿一个方向传输,使用一根传输线。

  半双工模式:通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。

  全双工模式:通信使用同两根传输线,一根作为发送数据,另一根作为接收数据。

  波特率:字符帧是按位依次传输,波特率即传输字符帧时的位速率,单位为bit/s。通信双方要使用相同的波特率,常用的波特率如9600、115200。

二、数据格式说明

  字符帧由四个部分构成,分别是起始位、数据位、校验位以及停止位。起始位占1位,为逻辑0。数据位占5 ~ 8位,可配置。校验位占1位,可配置为奇校验、偶校验、无校验;配置为无校验时字符帧不包含校验位;配置为奇校验时,数据位中逻辑1的个数为奇数时,校验位的值为逻辑0,否则为逻辑1;配置为偶校验时,数据位中逻辑1的个数为偶数时,校验位的值为逻辑0,否则为逻辑1。停止位占1/1.5/2位,可配置,停止位的值为逻辑1。常用的字符帧格式如下图1.1所示,1位起始位、8位数据位、1位校验位、1位停止位。

 

 三、配置虚拟串口环境

  1.安装虚拟串口驱动程序,添加一对虚拟串口。(若成功可以通过设备管理查看添加的串口)

  2.使用串口调试工具根据配对的虚拟串口,分别作为收、发端进行收发数据试验。
四、QT实现串口通信

  头文件:

#ifndef SERIALPORT_H
#define SERIALPORT_H

#include <QObject>
#include <QSerialPort>
#include <QSerialPortInfo>

class SerialPort : public QObject
{
    Q_OBJECT
public:
    explicit SerialPort(QObject *parent = nullptr);
    QStringList getPortNumList();
    bool initSerial(const QString &portName, int baudRate, int dataBit, int parityBit, int stopBit);
    QString getError();
    qint64 sendData(const QByteArray &data);

signals:
    void sglSerialData(const QByteArray &data);

private:
    QSerialPort m_qSerialPort;
};

#endif // SERIALPORT_H

  源文件:

#include "SerialPort.h"
#include <QDebug>

SerialPort::SerialPort(QObject *parent)
    : QObject{parent}
{

}

QStringList SerialPort::getPortNumList()
{
    QStringList portNumList;
    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();
        portNumList.append(info.portName());
    }
    return portNumList;
}

bool SerialPort::initSerial(const QString &portName, int baudRate, int dataBit, int parityBit, int stopBit)
{
    m_qSerialPort.setPortName(portName);

    switch (baudRate) {
    case QSerialPort::Baud115200:
        m_qSerialPort.setBaudRate(QSerialPort::Baud115200);
        break;
    default:
        return false;
    }

    switch (dataBit) {
    case QSerialPort::Data8:
        m_qSerialPort.setDataBits(QSerialPort::Data8);
        break;
    default:
        return false;
    }

    switch (parityBit) {
    case QSerialPort::NoParity:
        m_qSerialPort.setParity(QSerialPort::NoParity);
        break;
    default:
        return false;
    }

    switch (stopBit) {
    case QSerialPort::OneStop:
        m_qSerialPort.setStopBits(QSerialPort::OneStop);
        break;
    default:
        return false;
    }

    if(!m_qSerialPort.setFlowControl(QSerialPort::NoFlowControl))
    {
        return false;
    }

    if(m_qSerialPort.open(QIODevice::ReadWrite))
    {
        connect(&m_qSerialPort, &QSerialPort::readyRead, this, [=](){
            emit sglSerialData(m_qSerialPort.readAll());
        });
          return true;
    }
    else
    {
        return false;
    }
}

QString SerialPort::getError()
{
    return QString("error code:%1").arg(m_qSerialPort.error());
}

qint64 SerialPort::sendData(const QByteArray &data)
{
    return m_qSerialPort.write(data);
}

  

  

  

posted @ 2022-11-06 23:29  xianyongchao  阅读(529)  评论(0编辑  收藏  举报