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

解决C# WinForm无法从PCI-E串口扩展卡读取条码数据问题

问题:PCIe串口扩展卡读取条码返回全\0,原生COM口正常

问题详情

开发了一个C# Windows窗体应用,功能为通过RS232串口读取条码数据并显示到文本框:

  • 条码扫描器连接电脑原生COM口时,功能完全正常
  • 连接PCI Express串口扩展卡时,扫描后仅能读取到\0\0\0\0\0\0\0\0

现有代码

串口初始化代码

string path = ".\\Setting\\Config.ini";
IniFile inisys = new IniFile(path);

string PortName = inisys.GetString("FORMULA", "BarcodeCOM", "COM5");
int BaudRate = inisys.GetInt32("FORMULA", "baudrate", 9600);

port = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One);
port.Open();
if (port.IsOpen)
{
    // set the 'invoke' delegate and attach the 'receive-data' function
    // to the serial port 'receive' event.
    accessControlFromCentralThread = displayTextReadIn;
    port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}

数据接收事件

private void port_DataReceived(object sender, SerialDataReceivedEventArgs rcvdData)
{
    while (port.BytesToRead > 0)
    {
        lineReadIn += port.ReadExisting();
        Thread.Sleep(100);
    }

    // display what we've acquired.
    displayTextReadIn(lineReadIn);
}

界面更新方法

private void displayTextReadIn(string ToBeDisplayed)
{
    if (Txt_itemNo.InvokeRequired)
        Txt_itemNo.Invoke(accessControlFromCentralThread, ToBeDisplayed);
    else
        Txt_itemNo.Text = ToBeDisplayed;
}

修复步骤

1. 严格匹配串口参数

原生COM口可能自动兼容扫描器参数,但PCIe扩展卡需要完全匹配。除波特率外,检查以下设置:

  • 奇偶校验:尝试Parity.Even/Parity.Odd替代Parity.None
  • 数据位:部分扫描器使用7位而非8位
  • 停止位:确认是否为StopBits.Two
  • 流控制:添加硬件流控制,这是扩展卡常见的兼容性问题

修改初始化代码:

port = new SerialPort(PortName, BaudRate, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.RequestToSend; // 启用硬件流控制
port.ReadTimeout = 500;
port.WriteTimeout = 500;
port.Open();

2. 排查硬件与驱动

  • 卸载并重新安装扩展卡的官方最新驱动,不要使用系统默认驱动
  • 更换PCIe插槽,排除插槽供电或兼容性问题
  • 用串口调试工具(如SSCOM)直接测试扩展卡串口:
    • 若调试工具也读到全\0,说明是硬件/驱动问题,联系厂商或更换设备
    • 若调试工具能正常读取,再回到代码排查

3. 修正数据接收逻辑

现有接收逻辑存在两个隐患:全局变量lineReadIn未清空会导致数据累积;Thread.Sleep(100)依赖延迟判断接收完成,可靠性差。

改为基于终止符的读取(多数条码扫描器以\r/\n为结束符):

private void port_DataReceived(object sender, SerialDataReceivedEventArgs rcvdData)
{
    SerialPort sp = (SerialPort)sender;
    string received = sp.ReadLine();
    // 过滤控制字符
    received = received.Trim(new char[] {'\r', '\n', '\0'});
    displayTextReadIn(received);
}

若无终止符,改用字节读取并过滤空字节:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs rcvdData)
{
    SerialPort sp = (SerialPort)sender;
    byte[] buffer = new byte[sp.BytesToRead];
    sp.Read(buffer, 0, buffer.Length);
    string received = Encoding.ASCII.GetString(buffer).Replace("\0", "");
    displayTextReadIn(received);
}

4. 确认串口编号正确性

打开设备管理器→端口(COM和LPT),确认扩展卡对应的串口名称(如COM6),检查Config.ini中的BarcodeCOM是否匹配,避免配置读取错误。

内容的提问来源于stack exchange,提问作者DongPham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:35:20