首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

CSerialPort 類在 Win7 下 USB轉串口無法連續發送數據的線程同步問題分析

     編輯:程式設計綜合問答

問題現象

  • 環境:VS2008,CSerialPort 類,USB 轉 RS232 線連接兩台 Win7 電腦。
  • 現象:只能發送一條指令,隨後阻塞等待接收;收到字符後才能發送下一條。直連(無轉接線)則可正常連續收發。
  • 已排除:USB 轉接線硬件故障、驅動問題。

根本原因:線程同步機制導致的「發送-接收」串行化

CSerialPort 內部通常採用 發送線程 + 接收線程 架構,並使用 事件/信號量 同步:

  1. 發送數據前,發送線程等待「接收完成」信號。
  2. 接收線程收到數據後,觸發「接收完成」信號,喚醒發送線程。
  3. 此機制強制規定「發一條、收一條」,導致無法連續發送多條指令。

解決思路:修改同步邏輯,實現全雙工異步收發

方案一:註釋掉接收線程同步等待(快速驗證)

  1. 找到接收線程創建代碼,暫時註釋掉(僅保留發送功能)。
  2. 找到發送函數中等待「接收信號」的代碼(如 WaitForSingleObject),註釋掉。
  3. 測試連續發送是否正常。

方案二:重構為生產者-消費者模式(推薦生產環境)

  • 發送隊列:主線程將指令入隊,發送線程循環取隊發送,無需等待接收。
  • 接收回調:接收線程收到數據後,通過回調/事件通知上層業務,不阻塞發送。
  • 發送函數增加參數 bool needResponse:需應答的指令走「發送-等待應答」流程,無需應答的直接入隊返回。

關鍵代碼調整示例

// 發送函數修改
BOOL WriteData(const BYTE* data, int len, bool waitForResponse = false) {
    if (waitForResponse) {
        // 原有同步邏輯:發送 -> 等待接收事件 -> 返回
    } else {
        // 新異步邏輯:加入發送隊列 -> 立即返回 TRUE
        sendQueue.push(DataPacket(data, len));
        SetEvent(hSendEvent); // 通知發送線程
        return TRUE;
    }
}

調試建議

  • 使用串口監控工具(如 PortMon、Serial Port Monitor)抓包分析時序。
  • 在發送/接收線程關鍵點加日誌,輸出線程 ID、時間戳、數據內容。
  • 確認 USB 轉串口芯片(FT232/CH340/CP2102)驅動版本匹配 Win7 x64。

總結

CSerialPort 預設同步模式不適合「主動輪詢/連續下發」場景。通過剝離發送與接收的同步依賴,改為異步隊列模式,即可解決 Win7 下 USB轉串口無法連續發送的問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved