You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 09:46:03