2013-10-26 88 views
0

我試圖從Windows中逐行讀取COM端口的數據。在PuTTY中,COM連接看起來很好 - 我的串行設備(MSP430 Launchpad)每秒輸出一次字符串「Data」。然而,當我用一個簡單的C程序來讀取COM端口,並打印出讀取字節數,然後是數據本身,它就會完全錯位:從COM端口讀取破壞行

0 
6 Data 

2 Data 

4 ta 


6 Data 

3 Data 

3 a 
a 

6 Data 

6 Data 

2 Data 

6 Data的線是正確的(4個字符,然後\r\n),但是那些不包含完整消息的行發生了什麼?根據the documentationReadFile應默認讀取整行。這是不正確的 - 我是否需要自己緩衝它並等待換行字符?

請注意,並非所有這些錯誤都會發生在代碼的每次運行中;我做了幾次運行,併爲您的觀看樂趣編譯了各種錯誤。下面是我使用的代碼:

#include <windows.h> 
#include <stdio.h> 

static DCB settings; 
static HANDLE serial; 
static char line[200]; 
static unsigned long read; 
static unsigned int lineLength = sizeof(line)/sizeof(char); 

int main(void) { 
    int i = 10; 

    serial = CreateFile("COM4", 
     GENERIC_READ | GENERIC_WRITE, 
     0, NULL, 
     OPEN_EXISTING, 
     0, NULL); 

    GetCommState(serial, &settings); 
    settings.BaudRate = CBR_9600; 
    settings.ByteSize = 8; 
    settings.Parity = NOPARITY; 
    settings.StopBits = ONESTOPBIT; 
    SetCommState(serial, &settings); 

    while(i) { 
     ReadFile(serial, &line, lineLength, &read, 0); 
     printf("%lu %s\n", read, line); 
     i--; 
    } 
    scanf("%c", &read); 

    return 0; 
} 

使用Windows 7編譯64位的Visual Studio Express的2012

回答

2

發生了什麼事是,ReadFile正在恢復它得到任何數據之後。由於數據可能會在未來的某個時間點出現在串行端口上,因此ReadFile將在串行端口上獲取一定數量的數據時返回。如果您嘗試從串行端口嘗試read,則Linux中也會發生同樣的情況。您獲取的數據可能是整行,也可能不是整行,具體取決於您的流程再次分派時緩衝區中的信息量。

如果你再看看文檔,發現它只會返回一個線的時候,HANDLE在控制檯模式:

字符可以從控制檯輸入緩衝區通過使用ReadFile的有柄閱讀到控制檯輸入。控制檯模式確定ReadFile函數的確切行爲。默認情況下,控制檯模式爲ENABLE_LINE_INPUT,表示ReadFile應該讀取直到達到回車。如果按Ctrl + C,則調用成功,但GetLastError返回ERROR_OPERATION_ABORTED。有關更多信息,請參閱CreateFile。

+0

對,但它說「默認情況下,控制檯模式是ENABLE_LINE_INPUT」...我讀錯了,或者我的串行手柄默認情況下是否處於控制檯模式? –

+1

我對Windows沒有足夠的瞭解可以肯定地說,但是我認爲該段落的意思是,當你打開一個控制檯(例如'stdin')時,除非得到'\ r',否則你不會得到任何東西。 。控制檯緩衝區與串行緩衝區不同,串行緩衝區是您讀取的位置。 – rm5248

+0

好的,所以我必須檢查我每次閱讀的數據並在PC上拼湊出一行。我可以做到這一點。 –