MSComm (Microsoft Communication Control) 是 Microsoft 提供的 ActiveX 控制元件,封裝 Windows 串口 API,支援 VB/VC/Delphi 等環境,提供事件驅動與輪詢兩種模式。本文以 VC++ 對話框專案為例,示範事件驅動模式下的 Modem 初始化、資料收發與常用 AT 指令。
IDC_MSCOMMMSComm m_comm
OnInitDialog()
BOOL CMyDlg::OnInitDialog() {
CDialog::OnInitDialog();
if (m_comm.GetPortOpen()) m_comm.SetPortOpen(FALSE);
m_comm.SetCommPort(1); // COM1
m_comm.SetSettings(_T("9600,n,8,1")); // 9600 無奇偶 8資料位 1停止位
m_comm.SetInputMode(1); // 二進位陣列模式
m_comm.SetRThreshold(1); // 收到 1 字節觸發 OnComm
m_comm.SetPortOpen(TRUE);
m_comm.GetInput(); // 清空輸入緩衝區
m_strSend = _T("ATZ\r\n"); // Modem 復位
m_comm.SetOutput(COleVariant(m_strSend));
return TRUE;
}
OnCommMscomm()
void CMyDlg::OnCommMscomm() {
Sleep(500); // 視 Modem 廠商調整,否則資料不全
VARIANT vt = m_comm.GetInput();
long nEvent = m_comm.GetCommEvent();
switch (nEvent) {
case 2: // 接收字元事件
{
long cnt = m_comm.GetInBufferCount();
if (cnt > 0) {
char* pData = (char*)vt.parray->pvData;
m_strRecv = CString(pData, cnt); // 直接轉字串
// 這裡解析回應:OK, ERROR, CONNECT, RING 等
}
}
break;
case 3: case 4: case 5: case 6: // CTS/DSR/CD/Ring 狀態變化
// 可記錄日誌或更新 UI 指示燈
break;
}
}
| 指令 | 功能 | 範例 |
|---|---|---|
| ATZ | 復位恢復出廠設定 | ATZ\r\n |
| ATD | 撥號 (音頻) | ATD0212345678\r\n |
| +++ | 切換到線上命令模式 | +++ (需前後各 1 秒靜默) |
| ATH | 掛機/摘機 | ATH0 掛機, ATH1 摘機 |
| S0=n | 自動應答響鈴次數 | S0=1 (1響應答), S0=0 關閉 |
| &F | 載入出廠預設設定檔 | &F\r\n |
| \N0 | 異步模式 | \N0\r\n |
| \Q0 | XON/XOFF 流控 | \Q0\r\n |
Sleep 延遲,建議改用 CAsyncSocket 或 Win32 API ReadFile 實現更穩定的串口通訊InBufferSize / OutBufferSizeSetPortOpen(FALSE)MSComm 為快速開發串口/Modem 應用提供了極佳的封裝層。事件驅動模式配合 RThreshold=1 可實現近乎即時的資料接收。若需跨平台或更高效能,可考慮直接呼叫 Win32 CreateFile/ReadFile/WriteFile/SetCommState 等 API。