相对于使用QT5的QSerialPort串口类需要各种麻烦,还是选中了QExtSerialPort.
qextserialport下载:http://sourceforge.net/projects/qextserialport/
需要使用到的文件:
windows平台下:qextserialbase.cpp,extserialbase.h,win_qextserialport.cpp,win_qextserialport.h
linux平台下:qextserialbase.cpp,extserialbase.h,posix_qextserialport.cpp,posix_qextserialport.h
在linux下使用时编译会出现错误。
直接将第一个参数Settings.Timeout_Sec删除即可
我是使用USB转TTL实现雷达和上位机串口通信的,基于我下面的测试代码,总是无法打开串口
报错如下:
Trying to open File
Could not open File! Error code : 5
1、检查系统是否支持usb转串口:
# lsmod | grep usbserial
如果有usbserial,说明系统支持USB转串口。
2、查看usb转串口、串口的安装状态
# dmesg | grep ttyUSB*
# dmesg | grep ttyS*
例如,在终端输入:dmesg | grepttyS*显示从系统启动到现在串口插入拔出的信息,然后我在电脑上插入一个usb转rs232线,再在终端输入:dmesg | grepttyS* ,会显示: usb 1-8: ch341-uart converter now attached to ttyUSB0;可以通过此法确定我新插入的串口线对应的串口号ttyUSB0。
一般USB转串口设备/dev/ttyUSB*,如果是普通的串口设备会是/dev/ttyS*
https://blog.csdn.net/uncle_guo/article/details/80867169
3、最终解决
https://blog.csdn.net/ouening/article/details/79117871?utm_source=blogxgwz8
由于使用的是USB转串口(CH341),所以在/dev
目录下面看到的串口名为ttyUSB0
,但是后面使用串口助手助手的时候会提升打不开,权限不够,需要我们执行sudo chmod 666 /dev/ttyUSB0
更改权限(好像每次启动之后都要这样操作)
代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore/QList>
#include<qdebug.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
test();
}
MainWindow::~MainWindow()
{
myCom->close(); //关闭串口
myCom=NULL;
delete myCom;
delete ui;
}
void MainWindow::test()
{
myCom = new Posix_QextSerialPort("/dev/ttyUSB0",QextSerialBase::Polling);
if(myCom ->open(QIODevice::ReadWrite))//以读写方式打开串口
{
myCom->setBaudRate(BAUD9600); //波特率设置,我们设置为9600
myCom->setDataBits(DATA_8); //数据位设置,我们设置为8位数据位
myCom->setParity(PAR_NONE); //奇偶校验设置,我们设置为无校验
myCom->setStopBits(STOP_1); //停止位设置,我们设置为1位停止位
myCom->setFlowControl(FLOW_OFF); //数据流控制设置,我们设置为无数据流控制
//QList<QextPortInfo> m_ports = QextSerialEnumerator::getPorts(); //获取到端口信息
myCom->setTimeout(200); //延时设置,我们设置为延时200ms,如果设置为500ms的话,会造成程序无响应,原因未知
}
readTimer = new QTimer(this); //设置读取计时器
readTimer->start(100); //设置延时为100ms
connect(readTimer,SIGNAL(timeout()),this,SLOT(readMyCom()));
}
/*
* @breif 将16进制字符串转换为对应的字节序列
*/ QByteArray MainWindow::HexStringToByteArray(QString HexString)
{
bool ok;
QByteArray ret;
HexString = HexString.trimmed();
HexString = HexString.simplified();
QStringList sl = HexString.split(" ");
foreach (QString s, sl) {
if(!s.isEmpty())
{ char c = s.toInt(&ok,16)&0xFF;
if(ok)
{
ret.append(c);
}
else{
//qDebug()<<"非法的16进制字符:"<<s;
//QMessageBox::warning(0,tr("错误:"),QString("非法的16进制字符: \"%1\"").arg(s));
}
}
}
//qDebug()<<ret;
return ret;
}
QString MainWindow::ByteArrayToHexString(QByteArray data){
QString ret(data.toHex().toUpper());
int len = ret.length()/2;
//qDebug()<<len;
for(int i=1;i<len;i++)
{
//qDebug()<<i;
ret.insert(2*i+i-1," ");
}
return ret;
}
void MainWindow::on_pushButton_clicked() //发送数据
{
QString showSendMsg;
QString sendMsg=ui->lineEdit->text();;
QByteArray temp=sendMsg.toAscii(); //以ASCII码形式将数据写入串口,在Qt5中使用toLatin1
temp=HexStringToByteArray(sendMsg);
char *sendContent=temp.data();
myCom->write(sendContent,temp.count());
ui->textBrowser->insertPlainText(temp);
showSendMsg=QString::fromLocal8Bit("发送数据 : ");
showSendMsg+=ByteArrayToHexString(temp);
ui->textBrowser->insertPlainText(showSendMsg);
}
void MainWindow::readMyCom() //读取串口数据并显示出来
{
QByteArray temp = myCom->readAll(); //读取串口缓冲区的所有数据给临时变量temp
QString string;
string=ByteArrayToHexString(temp);
ui->textBrowser->insertPlainText(string); //将串口的数据显示在窗口的文本浏览器中
}