QSerialPort理论总结
- 一、概述
- 二、使用流程
- 1. 错误处理
- 2. 阻塞串行端口编程
- 3. 非阻塞串行端口编程
- 三、信号
- 四、注意事项
一、概述
QSerialPort 类其实就是一个打开串口,进行串口通信传输数据的功能类。我们可以使用QSerialPortInfo帮助类获取有关可用串行端口的信息,这个类能直接列举出系统中的所有串行端口。QSerialPortInfo类主要是我们在使用QSerialPort要通信的时候为指定我们具体操作哪一个串口,我们可以将QSerialPortInfo类的对象作为参数传递给setPort()或setPortName()方法,以分配所需的串行设备。Qt中的这个串口指的是 RS232串口,也是全双工的。
在具体使用每个函数的参数的时候,
二、使用流程
使用的流程其实也很简单
打开串口其实就是一个 在构造函数里传递一个 QSerialPortInfo 对象,或者一开始声明一个空参数对象,然后用 setPort() 来绑定一个串口 。
设置端口后,可以使用 open() 方法以只读(r/o)、只读(w/o)或读写(r/w)方式打开端口。因为QSerialPort是继承至QIODevice的。
注意:串口总是以独占访问方式打开的 (也就是说,没有其他进程或线程可以访问已经打开的串口,也就是程序只能在同一时刻操作一个串口)。
使用close()方法关闭端口并取消I/O操作。
成功打开后,QSerialPort将尝试确定端口的当前配置并初始化自身。您可以使用setBaudRate(), setDataBits(), setParity(), setStopBits() 和 setFlowControl()方法将端口重新配置为所需的设置。这些参数其实就是标准的一个设置流程。具体的看看那个串口协议就好。
有几个属性可以使用pinout信号,即:QSerialPort::dataTerminalReady, QSerialPort::requestToSend。也可以使用pinoutSignals()方法来查询当前的pinout信号集。
一旦知道端口可以读或写了,就可以使用read()或write()方法。另外,还可以调用 readLine() 和 readAll() 方便方法。
如果不是一次读取所有数据,剩余的数据将在以后可用,因为新的传入数据将追加到QSerialPort的内部读缓冲区。可以使用setReadBufferSize()限制读取缓冲区的大小,设置这个大小来配置一次读取的大小,这个看具体的协议内容的大小。能一次读完就一次读完最好。
1. 错误处理
如果在任何时间点发生错误,QSerialPort将发出 errorOccurred() 信号。
您还可以调用error()来查找上次发生的错误类型。我们从整个错误类型知道是为什么错误
使用阻塞串行端口编程与使用非阻塞串行端口编程完全不同。阻塞串行端口不需要事件循环,通常会使用更简单的代码。然而,在GUI应用程序中,阻塞串口应该只用于非GUI线程,以避免冻结用户界面。
2. 阻塞串行端口编程
QSerialPort提供了一组函数,用于挂起调用线程,直到发出特定信号。下面的例子就是一个阻塞式的。
这些函数可以用来实现阻塞串口:
- waitForReadyRead()阻塞调用,直到有新的数据可供读取。
- waitForBytesWritten()阻塞调用,直到一个数据负载被写入串口。
下面就是 读数据,用的 read() 来读 示例如下:
int numRead = 0, numReadTotal = 0;
char buffer[50];
for (;;) {
numRead = serial.read(buffer, 50);
// Do whatever with the array
numReadTotal += numRead;
if (numRead == 0 && !serial.waitForReadyRead())
break;
}
如果waitForReadyRead()返回false,则表示连接已关闭或发生错误。
写也是一样的,就是在循环中使用 waitForBytesWritten() 来完成
3. 非阻塞串行端口编程
非阻塞式编程就是用的信号槽的方式。
-
在读数据的时候:可以使用 read() 或 readAll() 方法,以及 readyRead() 信号。
readyRead()信号是继承至 QIODevice:这个信号的含义即是-> 每当有新的数据可以从设备的当前读取通道读取时,该信号就会发出一次。只有在有新数据可用时,比如有新的网络数据到达网络套接字时,或者有新数据块添加到设备时,才会再次触发。
readyRead()不是递归触发的;如果你重新进入事件循环或在与readyRead()信号相连的插槽中调用waitForReadyRead(),信号将不会重新发出(尽管waitForReadyRead()仍然可能返回true)。
实现QIODevice派生类的开发人员注意:当有新数据到达时,应该总是发出readyRead()(不要仅仅因为缓冲区中还有数据需要读取而发出它)。在其他情况下不要触发readyRead()。 -
在写数据的时候:使用 write() 方法和 bytesWritten() 信号。
每当有数据写入设备的当前写入通道时,就会发出该信号。 bytes参数设置为写入该有效载荷的字节数。
bytesWritten()不会递归地发出;如果你重新进入事件循环或在连接bytesWritten()信号的插槽中调用waitForBytesWritten(),信号将不会重新发出(尽管waitForBytesWritten()仍然可能返回true)。
三、信号
在 QSerialPort 里面的信号,主要是一些配置发生改变的信号,
四、注意事项
QSerialPort类也可以与QTextStream和QDataStream的流操作符(操作符<<()和操作符>>())一起使用。但是,有一个问题需要注意:在尝试使用运算符>>()重载运算符读取之前,请确保有足够的数据可用。