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

RS-232 串口即時監控軟體設計:VC++ 多執行緒與中斷驅動架構

     編輯:VC 教學

系統需求與架構

實驗室/工業場景需後台即時接收串口資料、避免輪詢阻塞、支援命令下發控制外設。採用 多執行緒 + 串口中斷(事件驅動) + 定時器刷新 UI 架構。

關鍵技術點

1. 串口參數結構與開啟

typedef struct {
    int nPort;     // COM1~COM4
    int nBaud;     // CBR_1200 ~ CBR_57600
    int nData;     // 7/8
    int nStop;     // 1/1.5/2
    int nParity;   // NOPARITY/ODDPARITY/EVENPARITY
} COM_CONFIG;

// 開啟與設定
HANDLE hCom = CreateFile(portName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
DCB dcb = {0}; dcb.DCBlength = sizeof(dcb);
GetCommState(hCom, &dcb);
dcb.BaudRate = cfg.nBaud; dcb.ByteSize = cfg.nData; dcb.StopBits = cfg.nStop; dcb.Parity = cfg.nParity;
SetCommState(hCom, &dcb);
// 設定逾時:立即返回,配合事件驅動
COMMTIMEOUTS ct = {0,0,0,0,0}; SetCommTimeouts(hCom, &ct);

2. 事件驅動接收執行緒

UINT __cdecl RecvThread(LPVOID pParam) {
    CMyClass* pThis = (CMyClass*)pParam;
    OVERLAPPED ov = {0}; ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    SetCommMask(hCom, EV_RXCHAR); // 只關心接收字元事件
    DWORD dwEvtMask;
    while (pThis->m_bRunning) {
        if (WaitCommEvent(hCom, &dwEvtMask, &ov)) {
            if (dwEvtMask & EV_RXCHAR) {
                char buf[1024]; DWORD dwRead;
                ReadFile(hCom, buf, sizeof(buf), &dwRead, &ov); // 實際讀取
                if (dwRead) {
                    // 進入臨界區推入環形緩衝區
                    pThis->PushData(buf, dwRead);
                }
            }
        } else {
            DWORD err = GetLastError();
            if (err == ERROR_IO_PENDING) {
                WaitForSingleObject(ov.hEvent, 100); // 短暫等待
            }
        }
    }
    CloseHandle(ov.hEvent);
    return 0;
}

3. UI 定時器刷新

主執行緒設定 SetTimer(1, 100, NULL),OnTimer 中從緩衝區取出資料更新 ListView,避免接收執行緒直接操作 UI 造成死鎖。

4. 臨界區保護共享資料

CCriticalSection cs;
void PushData(const char* p, int len) {
    CSingleLock lock(&cs); lock.Lock();
    m_ringBuffer.Write(p, len);
    lock.Unlock();
}
void PopData(char* p, int& len) { /* 類似加鎖 */ }

介面風格建議

  • 工具列採用 IE 風格 ReBar / DialogBar,放置命令輸入框與發送按鈕。
  • 資料顯示區使用 CListCtrl (Report 模式) 記錄時間戳、方向、十六進位/ASCII 內容。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved