繁体   English   中英

Windows 7上的奇怪行为QT QSerialPort不会更改串行com端口的设置

[英]Weird behavior QT QSerialPort on windows 7 doesn't change the settings of the serial com port

我正在编写一个qt桥,以通过Web应用程序访问串行热敏打印机。 我在设置串行端口设置时遇到问题,这是我的代码:

bool Bridge::printToSerial(QByteArray arr, QString serialPortName, quint16 baud) {

/*
QProcess    proc;
QStringList args = QStringList() << QString("mode COM1 BAUD=%1 PARITY=%2 DATA=%3" ).arg(9600).arg( "n" ).arg(8);
proc.start( "cmd.exe", args );
proc.waitForStarted();
proc.close();
*/

QSerialPort* m_port = new QSerialPort(this);
m_port->setPortName(serialPortName); // \\.\COM1
if(!m_port->open(QSerialPort::ReadWrite)) {
   qDebug() << "Error serial open";
} else {
    if (arr.isEmpty()) {
        qDebug() << QObject::tr("Either no data was currently available on the standard input for reading, or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
        delete m_port;
        return 1;
    }

    m_port->setBaudRate(baud);
    m_port->setDataBits(QSerialPort::Data8);
    m_port->setParity(QSerialPort::NoParity);
    m_port->setStopBits(QSerialPort::OneStop);

    //m_port->setBreakEnabled(true);

    qint64 bytesWritten = m_port->write(arr);
    if (bytesWritten == -1) {
        qDebug() << QObject::tr("Failed to write the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
        delete m_port;
        return 1;
    } else if (bytesWritten != arr.size()) {
        qDebug() << QObject::tr("Failed to write all the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
        delete m_port;
        return 1;
    } else if (!m_port->waitForBytesWritten(500)) {
        qDebug() << QObject::tr("Operation timed out or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
        delete m_port;
        return 1;
    }
    m_port->close();
    delete m_port;
    qDebug() << QObject::tr("Data successfully sent to port %1").arg(serialPortName) << endl;
    return false;
}
delete m_port;
return true;
}

问题是数据可以打印但没有完成,这使我感到数据位未设置为8位。

我执行了以下命令:模式COM1,它显示端口配置不正确(波特率,位,奇偶校验均错误)。 顺便说一句,设备管理器显示的是端口的默认设置,其结果与cmd行不同:“ mode COM1”

为了使其工作,我要么必须执行cmd行:在运行程序之前,模式COM1 BAUD = 9600 PARITY = n DATA = 8。 或调用m_port-> setBreakEnabled(true); 打开端口后 该调用将程序挂起,并且我不得不重新编译exe而不起作用。 系统重新启动时,命令行模式显示旧结果(波特率1200,数据位7等)

任何线索为什么我有这种行为? 看来QSerialPort无法有效地更改我需要的所有设置。

为什么每次发送一些数据时都要打开和关闭端口? 此外,仅因为writewaitForBytesWritten返回了表明该数据已“写入”的内容,它仅意味着该数据已从顶级设备驱动程序的缓冲区中清除。 USB请求实际上将所有数据推送到硬件的请求可能仍在等待中,设备的FIFO可能仍具有数据,依此类推。

但是,当您关闭设备时,通常会中止所有仍在进行的事务,并导致硬件清除其缓冲区。 写入是异步的,并且通过流传输来保持性能,而设备关闭则是操作的同步,即时结果类型。

保持设备打开。 仅当您以特定于平台的方式得知设备将要消失或正在添加新设备时,才需要重新打开它。

@库巴·奥伯是对的。 我最终将功能修改为如下所示,跟踪打开的端口:(我不知道是否每个端口都应该有QSerialPort指针,或者像下面这样使用它在每次写入数据时重新定义端口设置,但是上面的方法仍然有效。)

bool Bridge::printToSerial(QByteArray arr, QString serialPortName, quint16 baud) {

if (arr.isEmpty()) {
    qDebug() << QObject::tr("Either no data was currently available on the standard input for reading, or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
    return false;
}

bool portOpen = m_opened.contains(serialPortName);

if(!portOpen) {
    if(m_port == NULL) {
        m_port = new QSerialPort(this);
    }
    m_port->setPortName(serialPortName);
    if(!m_port->open(QSerialPort::WriteOnly)) {
        qDebug() << "Error serial open";
        return false;
    }
    portOpen = true;
    m_opened[serialPortName] = true;
} else {
    m_port->setPortName(serialPortName); // \\.\COM1
}

m_port->setBaudRate(baud);
m_port->setDataBits(QSerialPort::Data8);
m_port->setParity(QSerialPort::NoParity);
m_port->setStopBits(QSerialPort::OneStop);

qint64 bytesWritten = m_port->write(arr);
if (bytesWritten == -1) {
    qDebug() << QObject::tr("Failed to write the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
    delete m_port;
    return 1;
} else if (bytesWritten != arr.size()) {
    qDebug() << QObject::tr("Failed to write all the data to port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
    delete m_port;
    return 1;
} else if (!m_port->waitForBytesWritten(5000)) {
    qDebug() << QObject::tr("Operation timed out or an error occurred for port %1, error: %2").arg(serialPortName).arg(m_port->errorString()) << endl;
    delete m_port;
    return 1;
}
qDebug() << QObject::tr("Data successfully sent to port %1").arg(serialPortName) << endl;
return true;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM