0

我必须为基于 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(&notifAreaPort,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,表示没有发生错误!

想法?

——赛义德·阿姆罗拉希·博尤基

4

3 回答 3

0

您的代码中有几个问题,但我将重点介绍其中最重要的问题:

  • 您在打开之前设置参数。这应该打开后发生。这就是 API 的设计方式,但我们正在对其进行改进。

  • 您应该阅读我在 5.2 中添加的命令行示例吗?您似乎不知道如何阅读,这些会给您一个简单的例子。简而言之:您基本上是在写入可能完成之前尝试阅读。

于 2014-02-12T12:57:11.307 回答
0

您不能QSerialPort在同一个函数中写入然后从 a 中读取。

我使用两种方法进行QSerialPort处理:

METHOD ONE 创建并打开您的QSerialPort对象。设置一个QTimer大约 50 毫秒左右的超时(取决于硬件)。

将信号连接readyRead()到一个插槽,该插槽基本上只是将所有数据读入缓冲区(QByteArray对此非常理想)。插槽停止QTimer,使用 readAll() 读取所有可用数据,然后重新启动QTimer并返回。

timeout将 的信号连接QTimer到函数以处理输入的读取字节。

这里的前提是最终所有数据都将到达并且QTimer将超时,此时您将在缓冲区中处理所有数据。

METHOD TWO 处理readyRead()信号的槽可以检查缓冲区中的所有数据是否有一些“标记”,这表示某些数据块已经完全到达。许多设备使用0x0D0x0d0x0A作为分隔符。其他人使用 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;
    }
}

这允许在数据到达时读取 QSerialPort,然后程序可以返回到事件循环,以防止 GUI 变得无响应。典型的串行读取很小且持续时间很短,因此使用这些方法很少发生 UI 冻结。

于 2017-11-24T21:48:02.087 回答
-1

“手工制作的 USB 转串口适配器”——听起来很有趣。你确定这可以正常工作吗?我认为连接 PIN 2(Rx) 和 3(Tx) 是个好主意,这样你就可以获取数据了。现在您可以使用任何其他终端软件测试您的设备。对于串行端口,我始终使用 readyRead() 信号,并在使用 port->bytesAvailable() 读取之前进行检查。我用 port->open(QIODevice::ReadWrite | QIODevice::Unbuffered) 打开我的端口。

于 2014-02-08T11:08:11.297 回答