我需要使用 Jssc 库向串行打印机发送长文本。几次之后,我得到一个完整的缓冲区错误,所以我认为这可能是流量控制设置,因为对于较小的传输,一切正常。打印机可以使用 XON/XOFF 流量控制配置或 CTS/RTS 硬件信号。
软件流量控制
我打开端口的 jssc 代码是这样的:
serialPort.openPort();
serialPort.setParams(baud, data, stop, SerialPort.PARITY_NONE);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_XONXOFF_IN | SerialPort.FLOWCONTROL_XONXOFF_OUT);
这仅适用于小文本输出,对于较长的输出,打印机会抛出一个完整的缓冲区错误。
硬件流量控制
我还尝试将打印机切换到 cts/rts 流控制并将我的代码更改为:
serialPort.openPort();
serialPort.setParams(baud, data, stop, SerialPort.PARITY_NONE, true, false);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
但没有任何改变。我仍然收到长输出的缓冲区错误。
如果我的打印机在填充其缓冲区之前正确发送 XOFF 字符或 CTS 信号,我会使用 COM 监视器检查它,它运行良好!
最后,我尝试手动管理输出流在 CTS 信号关闭时停止它(使用事件处理程序),这样一切都适用于长输出......但这不是流控制应该自动执行的操作吗?
手动硬件流量控制测试
这是我的手动硬件流控制测试。它使用 canSend 布尔变量来控制输出流。
private boolean canSend=true;
public void openPort(
serialPort.openPort();
serialPort.setParams(baud, data, stop, SerialPort.PARITY_NONE, true, false);
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
serialPort.addEventListener(new SerialPortReader(), SerialPort.MASK_CTS);
canSend=true;
}
public void write(byte[] content) throws Exception {
ByteArrayInputStream b= new ByteArrayInputStream (content);
byte[] bytes =new byte[OUT_BUFFER_SIZE];
int byteread=0;
while ((byteread=b.read(bytes, 0, bytes.length)) >= 0) {
if(byteread>0){
while(!canSend){
Thread.sleep(CTS_WAIT);
}
if(byteread<bytes.length){
byte[] tocopy=new byte[byteread];
System.arraycopy(bytes, 0, tocopy, 0, byteread);
serialPort.writeBytes(tocopy);
}else{
serialPort.writeBytes(bytes);
}
}
}
}
private class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if(event.isCTS()){
canSend=event.getEventValue() == 1;
}
}
}
似乎完全忽略了流控制设置。可以是什么?jssc错误是Windows驱动程序错误吗?
我还尝试使用 getFlowControlMode() 对其进行检查,并且我正确地获得了硬件流控制测试的值 3。