首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

PcommPro 串口通訊開發實戰:C++Builder 快速構建雙向傳輸程式

     編輯:關於C++

為什麼選擇 PcommPro?

Windows 串口程式設計涉及複雜的 Win32 API (`CreateFile`, `SetCommState`, `WaitCommEvent`, `ReadFile`/`WriteFile` 重疊 I/O) 与多執行緒同步,開發門檻高、易出錯。**MOXA PcommPro** 將這些底層細節封裝為簡單的 `sio_xxx()` 函式庫 (DLL),讓開發者專注於業務邏輯。本文以 C++Builder 3/5/6/10+ 為例,示範從專案建立到完整收發程式的全流程。

一、環境準備與專案設定

  1. 下載安裝 PcommPro (預設路徑 `C:\Program Files\PcommPro`)。
  2. C++Builder 專案管理器 → 右鍵「Add」 → 選擇 `PcommPro\Lib\Pcommb.lib` 加入專案。
  3. 主單元 (`.cpp`) 頂端加入: ```cpp #include "C:\\Program Files\\PcommPro\\Lib\\PComm.h" ```

二、表單元件佈局與屬性設定

元件NameCaption/Text用途
ButtonbtnOpen開啟埠觸發 sio_open()
ButtonbtnSend發送資料觸發 sio_write()
ButtonbtnClose關閉埠觸發 sio_close()
EditedtSend(空)發送緩衝區
EditedtRecv(空)接收顯示區
ComboBoxcbPortCOM1~COM4選擇通訊埠 (可擴充)
ComboBoxcbBaud2400,9600,19200,38400,57600,115200鮑率

三、核心程式碼實作

全域/成員變數宣告


class TForm1 : public TForm {
    ...
private:
    int  nPort;              // 0=COM1, 1=COM2...
    AnsiString sSendData;    // 發送字串
    AnsiString sRecvData;    // 接收字串
    void __stdcall CntIrq(int port); // 中斷服務函數 (需 __stdcall)
};

開啟埠與參數設定


void __fastcall TForm1::btnOpenClick(TObject *Sender)
{
    nPort = cbPort->ItemIndex; // 0-based
    if (sio_open(nPort) != 0) {
        ShowMessage("開啟埠失敗!"); return;
    }

    // 參數對應:B2400=2400, P_NONE=無奇偶, BIT_7=7資料位, STOP_1=1停止位
    // 實際應從 cbBaud/cbParity/cbDataBits/cbStopBits 讀取組合
    int nBaud = B2400; // 範例固定 2400
    int nMode = P_NONE | BIT_7 | STOP_1;
    if (sio_ioctl(nPort, nBaud, nMode) != 0) {
        ShowMessage("參數設定失敗!"); sio_close(nPort); return;
    }

    // 掛載中斷回調:當接收緩衝區有資料 (計數 >= 1) 觸發 CntIrq
    void (__stdcall *pIrq)(int) = CntIrq;
    if (sio_cnt_irq(nPort, pIrq, 1) != 0) {
        ShowMessage("中斷掛載失敗!"); sio_close(nPort); return;
    }

    btnOpen->Enabled = false;
    btnClose->Enabled = true;
    btnSend->Enabled = true;
}

發送資料


void __fastcall TForm1::btnSendClick(TObject *Sender)
{
    sSendData = edtSend->Text;
    if (sSendData.IsEmpty()) return;

    // AnsiString → char* (Pcomm 需 char 緩衝區)
    char* pBuf = new char[sSendData.Length() + 1];
    strcpy(pBuf, sSendData.c_str());

    int nSent = sio_write(nPort, pBuf, strlen(pBuf));
    if (nSent < 0) ShowMessage("發送失敗!");
    else edtSend->Clear();

    delete[] pBuf;
}

中斷服務程序 (ISR) — 接收資料


void __stdcall TForm1::CntIrq(int port)
{
    // 此函數在 Pcomm 內部執行緒呼叫,**嚴禁直接操作 VCL 控制項**!
    // 僅讀取資料到成員變數,再用 PostMessage/ Synchronize 通知主執行緒更新 UI。

    char buf[256];
    int nRead = sio_read(port, buf, sizeof(buf) - 1);
    if (nRead > 0) {
        buf[nRead] = '\0';
        sRecvData = AnsiString(buf); // 暫存

        // 發送自訂訊息給主視窗,觸發 UI 更新
        PostMessage(Handle, WM_USER + 1, 0, 0);
    }
}

// 主執行緒訊息處理器 (需在類別宣告加入 MESSAGE_HANDLER)
void __fastcall TForm1::OnRecvData(TMessage &Msg)
{
    edtRecv->Text = sRecvData; // 安全更新 UI
}

關閉埠


void __fastcall TForm1::btnCloseClick(TObject *Sender)
{
    sio_close(nPort);
    btnOpen->Enabled = true;
    btnClose->Enabled = false;
    btnSend->Enabled = false;
}

四、關鍵 API 速查表

函式原型說明
sio_open`int sio_open(int port)`開啟埠,成功回 0。port: 0=COM1...
sio_close`int sio_close(int port)`關閉埠
sio_ioctl`int sio_ioctl(int port, int baud, int mode)`設定參數。baud: B300~B115200。mode: 位元組組合 (P_NONE/P_ODD/P_EVEN \| BIT_5~BIT_8 \| STOP_1/STOP_2)
sio_write`int sio_write(int port, char* buf, int len)`發送資料,回傳實際發送位元組數
sio_read`int sio_read(int port, char* buf, int len)`讀取資料,回傳實際讀取位元組數
sio_cnt_irq`int sio_cnt_irq(int port, void(__stdcall* func)(int), int count)`設定接收中斷。當接收緩衝區資料量 ≥ count 觸發 func。func 需 `__stdcall` 慣例。
sio_flush`int sio_flush(int port, int queue)`清空緩衝區。queue: 0=接收, 1=發送, 2=雙向

五、進階擴充:動態參數配置 UI

在表單加入 `ComboBox` 對應鮑率、資料位、停止位、奇偶校驗、流控 (RTS/CTS, XON/XOFF),`btnOpenClick` 內依使用者選擇組合 `nBaud` 與 `nMode` 即可。PcommPro 亦支援 `sio_flow_ctrl()` 設定硬體/軟體流控。

六、常見坑與避雷指南

  1. ISR 執行緒安全:`CntIrq` 在 Pcomm 內部執行緒,**絕對不可直接操作 VCL 控制項** (會導致 Access Violation 或死鎖)。必須用 `PostMessage`/`SendMessage` 或 `TThread::Synchronize` 傳遞資料給主執行緒。
  2. 字串編碼:Pcomm 傳輸 `char*` (ANSI/二進位)。若傳中文,確保雙端代碼頁一致 (如同為 Big5/GBK/UTF-8),或改用十六進位/ASCII 協定。
  3. 緩衝區大小:`sio_read` 第三參數指定最大讀取長度,**必須預留結尾 `\0` 空間**。
  4. 埠號映射:Pcomm `port=0` 對應 `COM1`,Windows `CreateFile` 需 `"\\\\.\\COM1"`,勿混淆。
  5. DLL 部署:發布時需將 `PComm.dll`、`PCommDrv.sys` (核心驅動) 隨應用程式同目錄或系統目錄安裝。

七、總結

PcommPro 以極簡 API (`open/ioctl/write/read/cnt_irq/close`) 隱藏了 Windows 串口程式設計的所有複雜性:DCB 結構、重疊事件、執行緒同步、驅動交互。配合 C++Builder 快速視覺化開發,幾十行代碼即可構建穩定的工業級串口收發程式。掌握 **ISR 執行緒隔離** 與 **字串/二進位轉換** 兩大關鍵,即可應對絕大多數 RS-232/422/485 通訊場景。

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