解决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
相关产品推荐
相关产品推荐

