文章目录
一、概要
对于一个QT初学者的我,我选择串口程序作为第一次练手项目,第一是因为它简单,能够在短时间里实现基本功能,能够很好的增加一个初学者的信心;第二是我想把这些基本功能都练习一遍,做到要用的时候直接调用就可以。下面就是我的代码片段,已经调试成功了,不过还有个小问题没有解决,没有好办法封装接收的部分代码。
二、代码区
第一步,在项目文件添加串口模块和串口功能的头文件
xxxx.pro中加入:
QT += serialport #串口模块
CONFIG+=qaxcontainer
使用串口功能的头文件中加入:
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
第二步,新建一个类,在.h文件的类里声明变量和函数
我新建的类名是“SerialPort ”,下面是.h的全部代码
SerialPort.h:
#ifndef SERIALPORT_H
#define SERIALPORT_H
#include <QObject>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
class SerialPort : public QObject
{
Q_OBJECT
public:
explicit SerialPort(QObject *parent = 0);
void openPort();//打开串口
void closePort();//关闭串口//关闭串口
QStringList getPortNameList(); //获取串口列表
QString ByteArrayToHexString(QByteArray &ba);//十六进制转十六进制字符串
void serialPortTx(QString str);//发送十六进制
void StringToHex(QString str, QByteArray &senddata);//字符串转十六进制
char ConvertHexChar(char ch);//十六进制转字符
QSerialPort* m_serialPort; //串口类
QStringList m_portNameList; //串口列表名
QString cNuber; //串口号
QString cBaudRate;//波特率
QString cParity; //校验位
QString cDataBits; //数据位
QString cStopBits; //停止位
QString cFlowControl;//设置控流
QString Rx_Str;//接收的数据,转成字符串
private:
signals:
public slots:
void serialPortRx();//接收
};
#endif // SERIALPORT_H
第三步,在SerialPort.cpp添加函数主体
SerialPort.cpp:
#include "serialport.h"
#include <QDebug>
#include <QApplication>
#include <QMessageBox>
#include <QList>
#include <QByteArray>
#include <QString.h>
#include <QDataStream>
SerialPort NSerialPort;
SerialPort::SerialPort(QObject *parent) : QObject(parent)
{
}
QStringList SerialPort::getPortNameList() //获取串口列表
{
QStringList m_serialPortName;
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{
m_serialPortName << info.portName();
//qDebug()<<"serialPortName:"<<info.portName();
}
return m_serialPortName;
}
static QSerialPort::BaudRate getBaudRate(int baudRate) //设置波特率
{
switch (baudRate)
{
case 1200:
return QSerialPort::Baud1200;
case 2400:
return QSerialPort::Baud2400;
case 4800:
return QSerialPort::Baud4800;
case 9600:
return QSerialPort::Baud9600;
case 19200:
return QSerialPort::Baud19200;
case 38400:
return QSerialPort::Baud38400;
case 57600:
return QSerialPort::Baud57600;
case 115200:
return QSerialPort::Baud115200;
default:
return QSerialPort::UnknownBaud;
}
}
static QSerialPort::DataBits getDataBits(int databits) //设置数据位
{
switch (databits)
{
case 5:
return QSerialPort::Data5;
case 6:
return QSerialPort::Data6;
case 7:
return QSerialPort::Data7;
case 8:
return QSerialPort::Data8;
default:
return QSerialPort::UnknownDataBits;
}
}
static QSerialPort::Parity getParity(QString parity) //设置校验位
{
if(parity == "None")
{
return QSerialPort::NoParity;
}
else if(parity == "Odd")
{
return QSerialPort::OddParity;
}
else if(parity == "Even")
{
return QSerialPort::EvenParity;
}
else if(parity == "Mark")
{
return QSerialPort::MarkParity;
}
else if(parity == "Space")
{
return QSerialPort::SpaceParity;
}
else
{
return QSerialPort::UnknownParity;
}
}
static QSerialPort::StopBits getStopBits(float StopBits) //设置停止位
{
if(StopBits == 1)
{
return QSerialPort::OneStop;
}
else if(StopBits == 1.5)
{
return QSerialPort::OneAndHalfStop;
}
else if(StopBits == 2)
{
return QSerialPort::TwoStop;
}
else
{
return QSerialPort::UnknownStopBits;
}
}
static QSerialPort::FlowControl getFlowControl(QString FlowControl)//设置控流
{
if(FlowControl == "None")
{
return QSerialPort::NoFlowControl;
}
else if(FlowControl == "Hardware")
{
return QSerialPort::HardwareControl;
}
else if(FlowControl == "Software")
{
return QSerialPort::SoftwareControl;
}
else
{
return QSerialPort::UnknownFlowControl;
}
}
void SerialPort::openPort() //打开串口
{
if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了
{
m_serialPort->clear();
m_serialPort->close();
}
m_serialPort->setPortName(cNuber);//当前选择的串口名字
if(!m_serialPort->open(QIODevice::ReadWrite))//用ReadWrite 的模式尝试打开串口
{
qDebug()<<"打开失败!";
return;
}
qDebug()<<"串口打开成功!";
m_serialPort->setBaudRate(getBaudRate(cBaudRate.toInt()),QSerialPort::AllDirections);//设置波特率和读写方向
qDebug()<<"波特率:"<<cBaudRate.toInt();
//m_serialPort->setDataBits(QSerialPort::Data8); //数据位为8位
m_serialPort->setDataBits(getDataBits(cDataBits.toInt()));
qDebug()<<"数据位:"<<cDataBits.toInt();
//m_serialPort->setFlowControl(QSerialPort::NoFlowControl);//无流控制
m_serialPort->setFlowControl(getFlowControl(cFlowControl));//流控制
qDebug()<<"流控制:"<<cFlowControl;
//m_serialPort->setParity(QSerialPort::NoParity); //无校验位
m_serialPort->setParity(getParity(cParity)); //校验位
qDebug()<<"校验位:"<<cParity;
//m_serialPort->setStopBits(QSerialPort::OneStop); //一位停止位
m_serialPort->setStopBits(getStopBits(cStopBits.toFloat())); //一位停止位
qDebug()<<"停止位:"<<cStopBits.toFloat();
m_serialPort->open(QSerialPort::ReadWrite); //打开串口为收发模式
connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(serialPortRx()));
}
void SerialPort::closePort() //关闭串口
{
if(m_serialPort->isOpen())//如果串口已经打开了 先给他关闭了
{
m_serialPort->clear();
m_serialPort->close();
}
}
void SerialPort::serialPortRx()
{
QByteArray temp = m_serialPort->readAll();
qDebug()<<"接收到十六进制数据:"<<temp;
Rx_Str = ByteArrayToHexString(temp);
qDebug()<<"接收到十六进制转字符串数据:"<<Rx_Str;
}
QString SerialPort::ByteArrayToHexString(QByteArray &ba)
{
QString buf;
QString str;
QString str1;
QDataStream out(&ba,QIODevice::ReadWrite); //将str的数据 读到out里面去
while(!out.atEnd())
{
qint8 outChar = 0;
out>>outChar; //每字节填充一次,直到结束
//十六进制的转换
str = QString("%1").arg(outChar&0xFF,2,16,QLatin1Char('0'));
str1 = str1 + str +" ";
}
return str1;
}
void SerialPort::serialPortTx(QString str)
{
/*把字符串转换为16进制发送*/
QString str1 = str;
qDebug()<<"发送的数据:"<<str;
QByteArray senddata;
StringToHex(str1,senddata);//将str字符串转换为16进制的形式
m_serialPort->write(senddata);//发送到串口
}
char SerialPort::ConvertHexChar(char ch)
{
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);
}
void SerialPort::StringToHex(QString str, QByteArray &senddata)
{
int hexdata,lowhexdata;
int hexdatalen = 0;
int len = str.length();
senddata.resize(len/2);
char lstr,hstr;
for(int i=0; i<len; )
{
//char lstr,
hstr=str[i].toLatin1();
if(hstr == ' ')
{
i++;
continue;
}
i++;
if(i >= len)
break;
lstr = str[i].toLatin1();
hexdata = ConvertHexChar(hstr);
lowhexdata = ConvertHexChar(lstr);
if((hexdata == 16) || (lowhexdata == 16))
break;
else
hexdata = hexdata*16+lowhexdata;
i++;
senddata[hexdatalen] = (char)hexdata;
hexdatalen++;
}
senddata.resize(hexdatalen);
}
三、运用
1、设置各参数下拉栏内容
NSerialPort.m_portNameList = NSerialPort.getPortNameList(); //获取串口列表
ui->comboBoxSerial->addItems(NSerialPort.m_portNameList);
ui->comboBoxBaud->addItem("9600");
ui->comboBoxBaud->addItem("19200");
ui->comboBoxBaud->addItem("115200");
ui->comboBoxData->addItem("8");
ui->comboBoxData->addItem("7");
ui->comboBoxData->addItem("6");
ui->comboBoxData->addItem("5");
ui->comboBoxStop->addItem("1");
ui->comboBoxStop->addItem("1.5");
ui->comboBoxStop->addItem("2");
ui->comboBoxCheck->addItem("None");
ui->comboBoxCheck->addItem("Odd");
ui->comboBoxCheck->addItem("Even");
ui->comboBoxFlow->addItem("None");
ui->comboBoxFlow->addItem("Hardware");
ui->comboBoxFlow->addItem("Software");
ui->comboBoxFlow->addItem("Coston");
2、打开串口
void ten::on_pushButtonOpen_clicked()
{
NSerialPort.cNuber = ui->comboBoxSerial->currentText(); //串口号
NSerialPort.cBaudRate = ui->comboBoxBaud->currentText();//波特率
NSerialPort.cParity = ui->comboBoxCheck->currentText(); //校验位
NSerialPort.cDataBits = ui->comboBoxData->currentText(); //数据位
NSerialPort.cStopBits = ui->comboBoxStop->currentText(); //停止位
NSerialPort.cFlowControl = ui->comboBoxFlow->currentText();//设置控流
NSerialPort.openPort();//打开串口
}
3、发送内容
void ten::on_pushButtonSend_clicked()
{
QString data = ui->text_TX->toPlainText();
NSerialPort.serialPortTx(data);//发送十六进制
}