使用QSerialPort从串行端口读取时出现问题 我必须开发一个基于嵌入式友好ARM处理器系统的C++程序。 我在桌面计算机上使用QtCreator3.0.0(基于Qt5.2.0)。我的程序应该能够从Mini2440 FriendlyARM处理器的串行端口读取数据
在进入目标系统(嵌入式系统)之前,我尝试从笔记本电脑的串行端口读写。我的主要问题是如何从串口读取数据。正如你们所知,新的计算机和笔记本电脑没有串行端口,所以我尝试使用手工制作的USB到串行适配器电缆来模拟串行端口编程。当USB串行电缆插入时,它在Ubuntu上被识别为“/dev/ttyUSB0”。它似乎工作得很好。 请注意,电缆的另一端(串行端口)没有连接到任何东西 我的第一个问题是:这样配置电缆可以吗,或者我必须将其连接到其他设备? 我尝试每10秒写入/dev/ttyUSB0并读取数据。我最终得到了以下代码:使用QSerialPort从串行端口读取时出现问题 我必须开发一个基于嵌入式友好ARM处理器系统的C++程序。 我在桌面计算机上使用QtCreator3.0.0(基于Qt5.2.0)。我的程序应该能够从Mini2440 FriendlyARM处理器的串行端口读取数据,qt,qtcore,qt-signals,qtserialport,qiodevice,Qt,Qtcore,Qt Signals,Qtserialport,Qiodevice,在进入目标系统(嵌入式系统)之前,我尝试从笔记本电脑的串行端口读写。我的主要问题是如何从串口读取数据。正如你们所知,新的计算机和笔记本电脑没有串行端口,所以我尝试使用手工制作的USB到串行适配器电缆来模拟串行端口编程。当USB串行电缆插入时,它在Ubuntu上被识别为“/dev/ttyUSB0”。它似乎工作得很好。 请注意,电缆的另一端(串行端口)没有连接到任何东西 我的第一个问题是:这样配置电缆可以吗,或者我必须将其连接到其他设备? 我尝试每10秒写入/dev/ttyUSB0并读取数据。我最终
void MainWindow::refreshNotificationArea()
{
generateNotifAreaData(); // a typical random data-generator
QList<QSerialPortInfo> L = QSerialPortInfo::availablePorts();
for (auto e : L)
qDebug() << e.portName() << '\n'; // it prints 1 serial port: :ttyUSB0
// write to the port
QSerialPort notifAreaPort;
// 1. set properties
notifAreaPort.setBaudRate(QSerialPort::Baud9600);
notifAreaPort.setStopBits(QSerialPort::OneStop);
notifAreaPort.setParity(QSerialPort::NoParity);
notifAreaPort.setDataBits(QSerialPort::Data8);
notifAreaPort.setFlowControl(QSerialPort::NoFlowControl);
QObject::connect(¬ifAreaPort,SIGNAL(error(QSerialPort::SerialPortError)),
this, SLOT(errorReport(QSerialPort::SerialPortError)));
notifAreaPort.setPortName(serial_device.c_str());
// 2. open port
notifAreaPort.open(QIODevice::ReadWrite);
if (!notifAreaPort.isOpen())
qDebug() << "Open failed"; // open is OK, no error message printed
string s = convertNotifAreadData2Str();
qDebug() << "Generated data " << s.c_str(); // OK
int a = notifAreaPort.write(s.c_str()); // write done
qDebug() << "Write count" << a; // OK
// now read the info
QByteArray ba = notifAreaPort.readLine(3); // read failed
QSerialPort::SerialPortError err = notifAreaPort.error();
qDebug() << "Error code" << err;
qDebug() << "What? " << notifAreaPort.errorString();
qDebug() << "Read count " << ba.size(); // 0
notifAreaPort.close();
}
void MainWindow::errorReport(QSerialPort::SerialPortError error)
{
if(error!=0)
qDebug()<<"ERROR:"<<endl<<error; // nothing printed
}
void主窗口::refreshNotificationArea()
{
generateNotifAreaData();//典型的随机数据生成器
QList L=QSerialPortInfo::availableport();
用于(自动e:L)
qDebug()“手工制作的USB到串行适配器”-听起来很有趣。你确定这工作正常吗?我认为连接针脚2(Rx)和针脚3(Tx)是个好主意,这样你就可以获得数据了。现在你可以用任何其他终端软件测试你的设备。
对于串行端口,我总是使用readyRead()信号,并在读取之前使用port->bytesavable()进行检查。
我用port->open(QIODevice::ReadWrite | QIODevice::Unbuffered)打开我的端口。您的代码中有几个问题,但我将强调其中最重要的问题:
- 您正在打开之前设置参数。这应该在打开之后进行。这就是API设计的方式,但我们正在对其进行改进
- 你应该知道我在5.2中添加了什么吗?似乎你不知道如何阅读,这会给你一个简单的例子。简言之:你基本上是在写作完成之前就尝试阅读
不能在同一函数中从QSerialPort
写入然后读取
有两种方法可用于QSerialPort
处理:
方法一
创建并打开QSerialPort
对象。
设置一个QTimer
,超时约50毫秒(取决于硬件)
将readyRead()
信号连接到一个插槽,该插槽基本上只将所有数据读入缓冲区(QByteArray
非常适合于此)。该插槽停止QTimer
,读取readAll()可用的所有数据,然后重新启动QTimer
,并返回
将QTimer
的timeout
信号连接到处理输入读取字节的函数
这里的前提是,最终所有数据都将到达,QTimer
将超时,此时您将在缓冲区中处理所有数据
方法二
处理readyRead()
信号的插槽可以检查缓冲区中的所有数据是否存在表示某个数据块已完全到达的“标记”。许多设备使用0x0D
或0x0d0a
作为增量。其他设备使用NULL0x00
或其他字节
在readyRead()
处理程序插槽的每次迭代中计算缓冲区
本例显示了第二种选择,它适用于小型读取
r_port = new QSerialPort(this);
r_port->setPortName("COM3");
r_port->setBaudRate(QSerialPort::Baud9600);
r_port->setDataBits(QSerialPort::Data8);
r_port->setParity(QSerialPort::NoParity);
r_port->setStopBits(QSerialPort::OneStop);
r_port->setFlowControl(QSerialPort::NoFlowControl);
if (r_port->open(QSerialPort::ReadWrite))
{
connect(r_port, &QSerialPort::readyRead, this, &MYPROG::on_readyRead);
connect(r_port, &QSerialPort::errorOccurred, this, &MYPROG::breakCaught);
}
else
{
QMessageBox::critical(this, "SERIAL PORT NOT CONNECTED", "Unable to connect to the radio.\n\nPlease check your connections\nand configuration and try again.");
return;
}
void MYPROG::on_readyRead()
{
// keep reading until we get a \r\n delimiter
rxBytes.append(r_port->readAll());
qDebug()<<"raw rxBtes"<<rxBytes;
if(!rxBytes.contains("\r\n"))
{
return;
}
int end = rxBytes.lastIndexOf("\r\n") + 2;
QStringList cmds = QString(rxBytes.mid(0, end)).split("\r\n", QString::SkipEmptyParts);
rxBytes = rxBytes.mid(end);
foreach(QString cmd, cmds){
qDebug()<<"serial read"<<cmd;
}
}
r\u端口=新的QSerialPort(此端口);
r_端口->设置端口名(“COM3”);
r_port->setBaudRate(QSerialPort::Baud9600);
r_port->setDataBits(QSerialPort::Data8);
r_端口->设置奇偶校验(QSerialPort::NoParity);
r_port->setStopBits(QSerialPort::OneStop);
r_port->setFlowControl(QSerialPort::NoFlowControl);
如果(r_端口->打开(QSerialPort::ReadWrite))
{
连接(r_端口,&QSerialPort::readyRead,this,&MYPROG::on_readyRead);
连接(r_端口,&QSerialPort::ErrorOccessed,this,&MYPROG::BreakCapture);
}
其他的
{
QMessageBox::critical(这是“串行端口未连接”、“无法连接到收音机”。\n\n请检查连接和配置,然后重试”);
回来
}
void MYPROG::on_readyRead()
{
//继续读取,直到获得分隔符\r\n
append(r_port->readAll());
qDebug()感谢您的反馈Matthias。我稍后会检查电缆。请回答我的第一个问题。为了测试串行端口的读写,串行电缆的一端连接到笔记本电脑,另一端未连接到设备(无论是什么串行设备)可以吗?Matthias.来自QSerialPort::open()文档:警告:模式必须为QIODevice::ReadOnly、QIODevice::WriteOnly或QIODevice::ReadWrite。其他模式不受支持。您编写了“qDebug()”我获取了源代码并检查了您的情况(未连接设备)。我在读取端口之前添加了port.clearError(),现在我收到了此“非套接字上的套接字操作”错误(错误代码=0)。当我添加额外的port.waitForReadyRead(1)时,我得到了相同的错误,但错误代码为12,这意味着超时,这是真的;-)