串口通信
一、串口通信原理
处理器与外部设备通信的方式有串行通信和并行通信的方式,串口通信是串行通信。
同步通信:带有时钟同步信号的数据传输。发送端和接收端在同一时钟的控制下,同步传输数据。
异步通信:不带有时钟同步信号的数据传输。发送端和接收端使用各自不同的时钟控制数据的发送和接收过程。
单工模式:数据传输是单向的,通信双方中,一方固定为发送端,一方固定为接收端,信息只能沿一个方向传输,使用一根传输线。
半双工模式:通信使用同一根传输线,既可以发送数据又可以接收数据,但不能同时进行发送和接收。
全双工模式:通信使用同两根传输线,一根作为发送数据,另一根作为接收数据。
波特率:字符帧是按位依次传输,波特率即传输字符帧时的位速率,单位为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);
}
坚持成就伟大

浙公网安备 33010602011771号