RS232打印机多打印问题:如何读取Xon-Xoff协议的XOn信号?
解决方案
一、修复串口初始化异常问题
你的测试代码注释掉了所有串口参数配置,导致用默认参数打开串口,和打印机要求的波特率、流控等不匹配,这是打开异常的核心原因。必须在打开串口前完成所有参数配置,且事件绑定要在打开前操作:
Dim targetPort As String = "COM1" ' 先检查目标端口是否存在 If SerialPort.GetPortNames().Contains(targetPort) Then Try ' 配置所有串口参数(必须在Open之前设置) SerialPort1.BaudRate = 9600 SerialPort1.DataBits = 8 SerialPort1.Parity = Parity.None SerialPort1.StopBits = StopBits.One SerialPort1.Handshake = Handshake.XOnXOff ' 启用Xon-Xoff流控 SerialPort1.ReadTimeout = 5000 ' 可选:设置读取超时,避免无限等待 ' 先绑定数据接收事件,再打开串口 AddHandler SerialPort1.DataReceived, AddressOf DataReceivedHandler If Not SerialPort1.IsOpen Then SerialPort1.Open() MessageBox.Show("串口COM1已成功打开") End If Catch ex As Exception MessageBox.Show("打开串口失败:" & ex.Message) End Try Else MessageBox.Show("未找到COM1端口") End If
二、读取XOn字符实现批量打印逻辑
要实现等待XOn(DC1,十六进制0x11,十进制17)再发送下一条消息,需按以下步骤实现:
1. 定义线程安全的就绪标志
在窗体类或模块中定义线程安全的信号量,标记打印机是否就绪:
' 用AutoResetEvent实现高效的等待通知,初始状态设为未触发 Private printerReady As New AutoResetEvent(False)
2. 实现DataReceived事件处理器
在事件中读取串口数据,判断是否收到XOn字符,收到后触发就绪信号:
Private Sub DataReceivedHandler(sender As Object, e As SerialDataReceivedEventArgs) Dim sp As SerialPort = CType(sender, SerialPort) ' 读取串口缓冲区的所有字节 Dim buffer(sp.BytesToRead - 1) As Byte sp.Read(buffer, 0, buffer.Length) ' 检查是否包含XOn字符(0x11) If buffer.Contains(&H11) Then ' 触发就绪信号,通知可以发送下一条 printerReady.Set() End If End Sub
3. 批量打印的循环逻辑
发送每条打印指令后,等待就绪信号触发,再发送下一条:
' 示例:批量打印5条测试消息 Private Sub BatchPrint() If Not SerialPort1.IsOpen Then MessageBox.Show("请先打开串口") Return End If Dim printMessages As String() = {"<MESSAGE1>", "<MESSAGE2>", "<MESSAGE3>", "<MESSAGE4>", "<MESSAGE5>"} For Each msg In printMessages ' 发送当前打印消息 SerialPort1.WriteLine(msg) ' 等待打印机返回XOn信号(最多等待10秒,避免死等) If printerReady.WaitOne(10000) Then MessageBox.Show("已收到XOn,准备发送下一条") Else MessageBox.Show("等待XOn超时,停止批量打印") Exit For End If Next End Sub
关键注意点
- 流控设置:确保
Handshake设为Handshake.XOnXOff,手册明确要求使用该协议,不要用硬件流控 - 线程安全:串口的DataReceived事件在后台线程触发,必须用线程安全机制(如
AutoResetEvent)管理就绪状态,不能用普通布尔值 - 超时处理:等待XOn时一定要设置超时,避免程序无限挂起
- 异常捕获:串口操作易出现端口断开、打印机离线等异常,关键步骤需添加异常捕获
内容的提问来源于stack exchange,提问作者Gianfranco Vrech
相关产品推荐
相关产品推荐

