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

RS-232-C 串口即時監控軟體設計與 VC++ 實戰實現

     編輯:VC 教學

專案背景

在實驗室與工控領域,受限於佈線成本,RS-232-C 串口長期作為電腦與串列設備通訊的首選通道。本文基於 Visual C++ 6.0 / Windows 9x 環境,構建一套支援後台非阻塞運行、即時接收處理數據、指令下發控制外設的監控軟體。

架構設計核心

挑戰解決方案關鍵技術
前後台並行不阻塞多執行緒分離 UI 與通訊AfxBeginThread、臨界區同步
數據即時捕獲不丟包中斷驅動異步讀取WaitCommEvent、OVERLAPPED 結構
即時介面刷新定時器輪詢顯示緩衝區SetTimer/WM_TIMER

核心模組實現

1. 串口參數配置結構

typedef struct tagCOM_CONFIG {
    int nPort;     // COM1~COM4
    int nBaud;     // 1200~57600 (CBR_1200~CBR_57600)
    int nData;     // 7/8 bits
    int nStop;     // 1/1.5/2 stop bits
    int nParity;   // NOPARITY/ODDPARITY/EVENPARITY
} COM_CONFIG;

2. 串口開啟與 DCB 設定(關鍵節錄)

// 以檔案方式開啟串口
idComDev = CreateFile(g_szCom_Port[g_com_config.nPort],
    GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL, NULL);

DCB dcb; dcb.DCBlength = sizeof(DCB);
GetCommState(idComDev, &dcb);

// 緩衝區 4KB
SetupComm(idComDev, 4096, 4096);
PurgeComm(idComDev, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

// 參數套用
dcb.BaudRate = g_Com_Baud[g_com_config.nBaud];
dcb.ByteSize = g_Com_ByteSize[g_com_config.nData];
dcb.Parity   = g_Com_Parity[g_com_config.nParity];
dcb.StopBits = g_Com_StopBits[g_com_config.nStop];

// 關閉硬/軟流控
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fOutxCtsFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fInX = dcb.fOutX = FALSE;

// 超時設定:讀無限等待,寫依波特率動態
COMMTIMEOUTS cto = {0};
cto.ReadIntervalTimeout = MAXDWORD;
cto.WriteTotalTimeoutMultiplier = 2*9600/dcb.BaudRate;
cto.WriteTotalTimeoutConstant = 25;
SetCommTimeouts(idComDev, &cto);

// 啟動讀取執行緒
if (SetCommState(idComDev, &dcb)) {
    m_bComPortOpen = TRUE;
    g_hCom = idComDev;
    AfxBeginThread(COMReadThreadProc, NULL, THREAD_PRIORITY_NORMAL);
}

3. 執行緒安全環狀緩衝區

BOOL CCOMReadBuf::GetOneByte(BYTE* cb) {
    m_Lock.Lock();
    if (m_nHead == m_nTail) { m_Lock.Unlock(); return FALSE; }
    *cb = m_readbuf[m_nTail];
    m_nTail = (m_nTail + 1) % m_nBufSize;
    m_Lock.Unlock(); return TRUE;
}

void CCOMReadBuf::Add(BYTE buf[], int nBytes) {
    m_Lock.Lock();
    for (int i=0; i

4. 指令下發(簡單同步寫入)

CString cmd; m_wndDlgBar.GetDlgItemText(IDC_EDIT_SEND, cmd);
if (!cmd.IsEmpty()) {
    cmd += '\r';
    DWORD dwWritten;
    WriteFile(g_hCom, cmd, cmd.GetLength(), &dwWritten, NULL);
}

5. 即時顯示:ListCtrl + 定時器

void CMyView::OnTimer(UINT nIDEvent) {
    CListCtrl& list = GetListCtrl();
    CTime t = CTime::GetCurrentTime();
    CString timeStr; timeStr.Format(_T("%02d:%02d:%02d"), t.GetHour(), t.GetMinute(), t.GetSecond());

    // 從緩衝區取數據填入 m_Buf...
    int idx = list.InsertItem(0, timeStr);
    if (idx != -1) list.SetItemText(idx, 1, m_Buf);
}

介面風格建議

  • 工具列採用 IE 風格 ReBar / DialogBar,內嵌指令輸入框;
  • 數據記錄採用報表模式 ListCtrl(時間 + 內容雙欄),支援大量歷史查閱。

測試驗證

  1. 先用 DOS Comdebug 驗證硬體串口正常;
  2. 雙機直連或單機 2/3 腳短接自收發測試;
  3. 接入實際設備(如高頻數傳電台)驗證指令控制與數據記錄。

總結

本方案結合多執行緒解耦、異步事件驅動、執行緒安全緩衝、定時器 UI 解耦四大支柱,構建出高可靠、低延遲的串口監控系統。同樣架構易擴展至其他串列協議(RS-485、USB 轉串口等),具備極強工程復用價值。

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