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

Windows 平台 C++ 串口編程完整指南

     編輯:關於C語言

核心 API 函數總覽

Windows 串口操作基於核心 API,掌握以下 6 個函數即可覆蓋 90% 應用場景:

函數用途
CreateFile打開串口,獲取句柄
GetCommState獲取當前串口參數(波特率、數據位、校驗位等)
SetCommState設置串口參數
ReadFile讀取串口數據
WriteFile寫入串口數據
CloseHandle關閉串口句柄

關鍵代碼片段

1. 打開串口

HANDLE hCom; // 全局串口句柄

bool OpenPort(const char* portName = "COM1") {
    hCom = CreateFile(
        portName,                       // 串口名
        GENERIC_READ | GENERIC_WRITE,   // 讀寫權限
        0,                              // 獨佔模式
        NULL,                           // 安全屬性
        OPEN_EXISTING,                  // 打開現有設備
        0,                              // 同步方式(非重疊 I/O)
        NULL
    );
    
    if (hCom == INVALID_HANDLE_VALUE) {
        AfxMessageBox("打開串口失敗!");
        return false;
    }
    return true;
}

2. 設置串口參數 (DCB 結構體)

bool SetupPort(DWORD baudRate = CBR_9600, BYTE byteSize = 8, BYTE parity = NOPARITY, BYTE stopBits = ONESTOPBIT) {
    DCB dcb;
    if (!GetCommState(hCom, &dcb)) return false;
    
    dcb.BaudRate = baudRate;
    dcb.ByteSize = byteSize;
    dcb.Parity = parity;
    dcb.StopBits = stopBits;
    dcb.fBinary = TRUE;
    dcb.fParity = (parity != NOPARITY);
    
    return SetCommState(hCom, &dcb);
}

3. 寫入數據 (同步阻塞模式)

bool WritePort(const void* buffer, DWORD length, DWORD* bytesWritten = nullptr) {
    COMSTAT comStat;
    DWORD errors;
    ClearCommError(hCom, &errors, &comStat); // 清除錯誤狀態
    
    DWORD written = 0;
    BOOL result = WriteFile(hCom, buffer, length, &written, NULL);
    
    if (!result) {
        AfxMessageBox("寫入串口失敗!");
        return false;
    }
    if (bytesWritten) *bytesWritten = written;
    return true;
}

4. 讀取數據 (帶超時的重疊 I/O 模式)

DWORD ReadPort(void* buffer, DWORD maxLength, OVERLAPPED* overlapped = nullptr) {
    COMSTAT comStat;
    DWORD errors;
    ClearCommError(hCom, &errors, &comStat);
    
    if (comStat.cbInQue == 0) return 0; // 無數據可讀
    
    DWORD toRead = min(maxLength, comStat.cbInQue);
    DWORD read = 0;
    
    BOOL result = ReadFile(hCom, buffer, toRead, &read, overlapped);
    
    if (!result) {
        DWORD lastError = GetLastError();
        if (lastError == ERROR_IO_PENDING && overlapped) {
            // 等待重疊操作完成
            GetOverlappedResult(hCom, overlapped, &read, TRUE);
            return read;
        }
        return 0;
    }
    return read;
}

5. 關閉串口

void ClosePort() {
    if (hCom != INVALID_HANDLE_VALUE) {
        CloseHandle(hCom);
        hCom = INVALID_HANDLE_VALUE;
    }
}

工程實踐建議

  1. 錯誤處理:每次 API 調用後檢查返回值,配合 GetLastError() 定位問題
  2. 緩衝區管理:讀取前調用 ClearCommError 獲取 cbInQue 避免無效等待
  3. 線程安全:串口句柄若多線程共用,需加鎖保護
  4. 資源釋放:RAII 封裝類管理句柄生命週期,防止洩漏
  5. 超時設置:使用 SetCommTimeouts 配置讀寫超時,避免無限阻塞
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved