看过好几篇有关于串口收发的博客,通过学习,写了一个较完整功能的串口,包含16进制的发送、接受和换行插入(有些上位机的奇偶校验和停止位都写死了,实际使用中都需要用到,我加入了选择)
一、新建工程后在mainwindow.ui界面隐藏菜单栏,并放入Containers中Tab Widget。再在工程新建文件类型widget,命名为serial,串口功能函数都写在这(这样如果想加入新功能再新建Widget窗口把功能函数写在相应cpp文件中即可)
接着在mainwindow.cpp中添加代码
serial *interface1;
interface1 = new serial();
//移除原先的两个tab
const int originalTabNum = ui->tabWidget->count();
for(int i=0; i<originalTabNum; i++)
{
ui->tabWidget->removeTab(0);
}
//增加新的tabWidget窗口
ui->tabWidget->addTab(interface1, "串口助手");
二、qt5集成了串口的功能函数,为了调用,在工程pro文件中添加代码serialport(pro文件中 TARGET = serial 这行可以更改生成app的名字)
QT += core gui serialport
在serial.h头文件中添加代码
#include "QSerialPort" //串口访问
#include "QSerialPortInfo" //串口端口信息访问
在头文件public中添加代码
void Init();//串口初始化主函数中调用
在头文件private slots中添加代码
void serial_Read();//串口数据读取显示
在头文件private中添加代码
QSerialPort SerialPort;
三、搜索端口(打开上位机后插入串口设备时使用)
void serial::on_searchBtn_clicked()
{
ui->portBox->clear();
//通过QSerialPortInfo查找可用串口
foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts())
{ //在portBox中显示可用串口
ui->portBox->addItem(info.portName());
}
}
四、串口初始化
void serial::Init()
{
//读取串口信息
foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
{
// 自动读取串口号添加到端口portBox中
QSerialPort serial;
serial.setPort(info);
if(serial.open(QIODevice::ReadWrite))
{
ui->portBox->addItem(info.portName());
serial.close();
}
}
QStringList baudList; //波特率
QStringList parityList; //校验位
QStringList dataBitsList; //数据位
QStringList stopBitsList; //停止位
// 波特率 //波特率默认选择下拉第三项:9600
baudList<<"1200"<<"2400"<<"4800"<<"9600"
<<"14400"<<"19200"<<"38400"<<"56000"
<<"57600"<<"115200";
ui->rateBox->addItems(baudList);
ui->rateBox->setCurrentIndex(3);
// 校验 //校验默认选择无
parityList<<"无"<<"奇"<<"偶";
ui->checkBox->addItems(parityList);
ui->checkBox->setCurrentIndex(0);
// 数据位 //数据位默认选择8位
dataBitsList<<"5"<<"6"<<"7"<<"8";
ui->dataBox->addItems(dataBitsList);
ui->dataBox->setCurrentIndex(3);
// 停止位 //停止位默认选择1位
stopBitsList<<"1"<<"2";
ui->stopBox->addItems(stopBitsList);
ui->stopBox->setCurrentIndex(0);
}
五、打开串口
void serial::on_openBtn_clicked()
{
// 打开串口
if(ui->openBtn->text() == "打开串口")
{
// 设置串口号
SerialPort.setPortName(ui->portBox->currentText());
// 打开串口
if(SerialPort.open(QIODevice::ReadWrite))
{
// 设置波特率
SerialPort.setBaudRate(ui->rateBox->currentText().toInt());
//设置数据位数
switch(ui->dataBox->currentIndex())
{
case 5: SerialPort.setDataBits(QSerialPort::Data5); break;
case 6: SerialPort.setDataBits(QSerialPort::Data6); break;
case 7: SerialPort.setDataBits(QSerialPort::Data7); break;
case 8: SerialPort.setDataBits(QSerialPort::Data8); break;
default: break;
}
// 设置校验位
//SerialPort->setParity(QSerialPort::NoParity);
//设置奇偶校验
switch(ui->checkBox->currentIndex())
{
case 0: SerialPort.setParity(QSerialPort::NoParity); break;
case 1: SerialPort.setParity(QSerialPort::OddParity); break;
case 2: SerialPort.setParity(QSerialPort::EvenParity); break;
default: break;
}
// 设置流控制
SerialPort.setFlowControl(QSerialPort::NoFlowControl);
//设置停止位
switch(ui->stopBox->currentIndex())
{
case 1: SerialPort.setStopBits(QSerialPort::OneStop); break;
case 2: SerialPort.setStopBits(QSerialPort::TwoStop); break;
default: break;
}
}
//打开串口
else
{
QMessageBox::about(NULL, "提示", "串口无法打开\r\n不存在或已被占用");
return;
}
ui->openBtn->setText("关闭串口");
//下拉菜单控件使能
ui->portBox->setEnabled(false);
ui->rateBox->setEnabled(false);
ui->dataBox->setEnabled(false);
ui->checkBox->setEnabled(false);
ui->stopBox->setEnabled(false);
//搜索串口按键使能
ui->searchBtn->setEnabled(false);
//发送按键使能
ui->sendBox->setEnabled(true);
}
// 关闭串口
else
{
SerialPort.close();
ui->openBtn->setText("打开串口");
//下拉按键使能
ui->portBox->setEnabled(true);
ui->rateBox->setEnabled(true);
ui->dataBox->setEnabled(true);
ui->checkBox->setEnabled(true);
ui->stopBox->setEnabled(true);
//搜索串口按键使能
ui->searchBtn->setEnabled(true);
//发送按键使能
ui->sendBox->setEnabled(false);
}
}
六、接受显示代码
void serial::serial_Read()
{ QString buffer_1;
//从缓冲区中读取数据
QByteArray buffer = SerialPort.readAll();
if(!buffer.isEmpty())//如果非空说明有数据接收
{ //转换成16进制大写
QString str=buffer.toHex().data();
str=str.toUpper()
//一个16进制占4位,8位为一字节,所以每两位16进制空一格
for(int i=0;i<str.length();i+=2)
{
QString str_1 = str.mid (i,2);
buffer_1 += str_1;
buffer_1 += " ";
}
//读取之前显示数据
QString receive = ui->receiveData->toPlainText();
//清空显示
ui->receiveData->clear();
//重新显示
if(a==0){
receive += QString(buffer);
ui->receiveData->append(receive);
}//直接显示
else {
receive += QString(buffer_1);
ui->receiveData->append(receive);
}//16进制显示
}
buffer.clear();
}
七、发送代码
void serial::on_sendBox_clicked()
{ QByteArray Data_1;
//获取输入窗口sendData的数据
QString Data = ui->sendData->toPlainText();
if(c) {Data+='\r';Data+='\n';}//插入换行
if(b==0) Data_1 = Data.toUtf8();//转换成utf8格式的字节流发送
else Data_1 = QByteArray::fromHex (Data.toLatin1().data());//按十六进制编码发送
// 写入发送缓存区
SerialPort.write(Data_1);
}
八、测试串口接法rx tx短接
九、效果显示