我必须为嵌入式基于FriendlyARM的处理器系统开发一个C ++程序。 我使用Qt Creator 3.0.0(基于Qt 5.2.0)用于台式计算机。我的程序应该能够从Mini2440 FriendlyARM处理器的串口读取。
在进入目标系统(嵌入式系统)之前,我试图在笔记本电脑上读取/写入串口。我的主要问题是如何从串口读取。如您所知,新计算机和笔记本电脑没有串行端口,因此我尝试使用手工制作的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
}
写入串口是可以的。但阅读问题有时“没有这样的文件或目录”! 有时“文件暂时不可用! 奇怪的是notifAreaPort.error()返回0,这意味着没有错误 发生!
思想?
- Saeed Amrollahi Boyouki
答案 0 :(得分:0)
“手工制作USB转串口适配器” - 听起来很有趣。你确定这个工作正常吗?我认为连接PIN 2(Rx)和3(Tx)是个好主意,因此您可以获得数据。现在,您可以使用任何其他终端软件测试您的设备。 我用串行端口总是readyRead()信号,我在使用port-&gt; bytesAvailable()读取之前检查。 我用port-&gt; open打开我的端口(QIODevice :: ReadWrite | QIODevice :: Unbuffered)。
答案 1 :(得分:0)
您的代码中存在一些问题,但我将重点介绍其中最重要的一些问题:
您在打开前设置参数。这应该在打开后发生。这就是API设计得很糟糕的方式,但我们正在对其进行改造。
您应该在5.2中添加command line examples for reading吗?看来你不知道如何阅读,那些会给你一个简单的例子。简而言之:在写作可能甚至完成之前,你基本上都在尝试阅读。
答案 2 :(得分:0)
你不能在同一个函数中写QSerialPort
。
我使用两种方法进行QSerialPort
处理:
METHOD ONE
创建并打开QSerialPort
对象。
设置QTimer
,超时大约50毫秒左右(取决于硬件)。
将readyRead()
信号连接到一个插槽,该插槽基本上只是将所有数据读入缓冲区(QByteArray
非常适用于此)。插槽会停止QTimer
,读取readAll()的所有可用数据,然后重新启动QTimer
并返回。
将timeout
的{{1}}信号连接到函数以处理读取的输入字节。
这里的前提是,最终所有数据都将到达并且QTimer
将超时,此时您将在缓冲区中处理所有数据。
QTimer
处理METHOD TWO
信号的槽可以检查缓冲区中的所有数据是否有一些“标记”,表示某些数据块已完全到达。许多设备使用readyRead()
或0x0D
作为转发器。其他人使用NULL 0x0d0x0A
或其他字节。
在0x00
处理程序槽的每次迭代中评估缓冲区。
此示例显示了第二个选项,它适用于小读取。
readyRead()
这允许在数据到达时读取QSerialPort,然后程序可以返回到事件循环,以防止GUI变得无响应。典型的串行读取很小且持续时间很短,因此使用这些方法很少发生UI冻结。