MSComm (Microsoft Communications Control) 是 ActiveX 控制項,封裝 Windows 串口 API,提供 Visual Basic 風格的事件驅動介面,在 C++Builder、Delphi、VB 中廣泛使用。本文系統整理屬性、事件、錯誤碼、常數,並對比**事件驅動**與**輪詢**兩種程式設計模式,給出完整設定流程與代碼範例。
| 屬性 | 用途 | 關鍵值/範例 |
|---|---|---|
CommPort | 通訊埠號 (1~16) | 預設 1,必在 PortOpen=true 前設定 |
Settings | 連線參數字串 | "9600,N,8,1" (Baud, Parity, Data, Stop) |
PortOpen | 開啟/關閉埠 | true/false |
RThreshold | 觸發 OnComm 的接收字元數 | 0=不觸發, 1=每字元觸發, N=累積 N 字元觸發 |
SThreshold | 觸發發送事件的緩衝區剩餘字元數 | 0=不觸發, 1=緩衝區空觸發 |
InputLen | Input 讀取字元數 | 0=讀取全部 |
InputMode | 讀取模式 | comInputModeText (0) / comInputModeBinary (1) |
Handshaking | 握手協定 | comNone(0), comXonXoff(1), comRTS(2), comRTSXOnXOff(3) |
CTSHolding | CTS 線狀態 (唯讀) | True/False |
DSRHolding | DSR 線狀態 (唯讀) | True/False |
CDHolding | CD 線狀態 (唯讀) | True/False |
EOFEnable | 是否檢查 EOF 字元 | True/False |
CommEvent 屬性)| 常數 | 值 | 觸發條件 |
|---|---|---|
comEvSend | 1 | 發送緩衝區低於 SThreshold |
comEvReceive | 2 | 接收緩衝區達到 RThreshold |
comEvCTS | 3 | CTS 線狀態變化 |
comEvDSR | 4 | DSR 線狀態變化 |
comEvCD | 5 | CD 線狀態變化 |
comEvRing | 6 | 偵測到振鈴 (RI) |
comEvEOF | 7 | 接收到 EOF 字元 |
CommEvent 為錯誤時)| 常數 | 值 | 意義 |
|---|---|---|
comEventBreak | 1001 | 收到中斷訊號 |
comEventCTSTO | 1002 | CTS 逾時 |
comEventDSRTO | 1003 | DSR 逾時 |
comEventFrame | 1004 | 幀錯誤 |
comEventOverrun | 1006 | 埠過載 (資料來不及讀) |
comEventCDTO | 1007 | CD 逾時 |
comEventRxOver | 1008 | 接收緩衝區溢位 |
comEventRxParity | 1009 | 奇偶校驗錯誤 |
comEventTxFull | 1010 | 發送緩衝區滿 |
comEventDCB | 1011 | DCB 取得失敗 |
void __fastcall TForm1::MSComm1OnComm(TObject *Sender) {
switch (MSComm1->CommEvent) {
case 2: // comEvReceive
AnsiString data = MSComm1->Input; // 讀取文字
Memo1->Lines->Add(data);
break;
case 1008: // comEventRxOver
// 處理緩衝區溢位
break;
// ... 其他事件
}
}
優點:即時響應、CPU 佔用低、適合高頻資料流。
缺點:需處理重入、執行緒安全(VCL 非執行緒安全,事件在主執行緒)。
void __fastcall TForm1::Timer1Timer(TObject *Sender) {
if (MSComm1->CommEvent == 2) { // 檢查是否有資料
AnsiString data = MSComm1->Input;
Memo1->Lines->Add(data);
}
// 定期檢查錯誤碼
if (MSComm1->CommEvent >= 1000) HandleError(MSComm1->CommEvent);
}
優點:邏輯線性、易除錯、適合簡單查詢-回應協定 (如 AT 指令)。
缺點:輪詢間隔權衡延遲與 CPU、易漏讀高速資料。
void __fastcall TForm1::FormCreate(TObject *Sender) {
MSComm1->CommPort = 1;
MSComm1->Settings = "9600,N,8,1";
MSComm1->RThreshold = 1; // 逐字元觸發
MSComm1->InputLen = 0; // 讀全部
MSComm1->InputMode = 0; // 文字模式
MSComm1->Handshaking = 0; // 無握手
MSComm1->PortOpen = true; // 開啟埠
}
void __fastcall TForm1::FormDestroy(TObject *Sender) {
if (MSComm1->PortOpen) MSComm1->PortOpen = false;
}
Settings 完全一致 (鮑率、奇偶、資料位、停止位)。RThreshold、改用二進制模式批次讀取、或啟用硬體流控 (RTS/CTS)。CreateFile, ReadFile, SetCommMask + WaitCommEvent) 或第三方元件 (如 TComPort)。「MSComm 適合快速原型、低速裝置、32 位元應用;高可靠、高速、64 位元、跨平台專案請直接使用 Win32 Serial API 或成熟開源元件。」