2011-05-17 67 views
6
//#include "StdAfx.h" 
#include <stdio.h> 
#include <windows.h> 
#include <winbase.h> 
#include <iostream> 
#include <tchar.h> 
using namespace std; 

int main() 
{ 

    int com = 'COM2'; 
    string data = "\n 010400 \n"; 
    char output[32]; 
    //unsigned int length = 0; 
    DCB config = {0}; 
    bool abContinue = true; 
    DWORD dwBytesWritten; 
    DWORD dwBytesRead; 
    int isRead = false; 

    HANDLE m_hCommPort = ::CreateFile(L"COM2", 
     GENERIC_READ|GENERIC_WRITE,//access (read and write) 

     0, //(share) 0:cannot share the COM port       

     0, //security (None)     

     OPEN_EXISTING,// creation : open_existing 

     0, // we dont want overlapped operation 

     0// no templates file for COM port... 

     ); 

    config.DCBlength = sizeof(config); 


    if((GetCommState(m_hCommPort, &config) == 0)) 
    { 
     printf("Get configuration port has a problem."); 
     return FALSE; 
    } 

    config.BaudRate = 9600; 
    config.StopBits = ONESTOPBIT; 
    config.Parity = PARITY_NONE; 
    config.ByteSize = DATABITS_8; 
    config.fDtrControl = 0; 
    config.fRtsControl = 0; 

    if (!SetCommState(m_hCommPort, &config)) 
    { 

     printf("Failed to Set Comm State Reason: %d\n",GetLastError()); 
     //return E_FAIL; 
    } 

    printf("Current Settings\n Baud Rate %d\n Parity %d\n Byte Size %d\n Stop Bits %d", config.BaudRate, 
     config.Parity, config.ByteSize, config.StopBits); 

    int isWritten = WriteFile(m_hCommPort, &data,(DWORD) sizeof(data), &dwBytesWritten, NULL); 


    //memset(output, 0, sizeof(output)); 
    while (abContinue) 
    { 

     isRead = ReadFile(m_hCommPort, output, sizeof(output), &dwBytesRead, NULL); 

     if(!isRead) 
     { 
      abContinue = false; 
      break; 
     } 

    } 

    cin.get(); 
} 

我無法從com端口讀取數據。如果我單步執行代碼,它將進入「isRead = ReadFile(m_hCommPort,output,sizeof(output),& dwBytesRead,NULL);」並不會回來....這是我第一次嘗試沒有成功。使用WriteFile/ReadFile的串行通信

+1

我的問題是完全相反的。 'ReadFile'不等待任何事情只是返回0字節讀取和返回值'TRUE' -.- – Bitterblue 2014-05-13 13:29:30

回答

12

你可以嘗試一些代碼,這樣的事情你已經打開了文件之後,但在此之前您嘗試使用它:

COMMTIMEOUTS timeouts; 

timeouts.ReadIntervalTimeout = 1; 
timeouts.ReadTotalTimeoutMultiplier = 1; 
timeouts.ReadTotalTimeoutConstant = 1; 
timeouts.WriteTotalTimeoutMultiplier = 1; 
timeouts.WriteTotalTimeoutConstant = 1; 
if (!SetCommTimeouts(m_hCommPort, &timeouts)) 
    // setting timeouts failed. 

編輯:也許這是更容易一些代碼,工程啓動,並它做你想做的,而不是試圖讓你的代碼工作。這是一個簡單的終端程序。它極簡主義,但確實有效(例如,至少足以讓我看到我的GPS輸出,例如)。從任何人(至少我所有人)都會稱之爲複雜的方法來說,這是一個很長的路要走,但至少應該給出一些關於如何開始的想法。

#include <stdio.h> 
#include <conio.h> 
#include <string.h> 

#define STRICT 
#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 

void system_error(char *name) { 
// Retrieve, format, and print out a message from the last error. The 
// `name' that's passed should be in the form of a present tense noun 
// (phrase) such as "opening file". 
// 
    char *ptr = NULL; 
    FormatMessage(
     FORMAT_MESSAGE_ALLOCATE_BUFFER | 
     FORMAT_MESSAGE_FROM_SYSTEM, 
     0, 
     GetLastError(), 
     0, 
     (char *)&ptr, 
     1024, 
     NULL); 

    fprintf(stderr, "\nError %s: %s\n", name, ptr); 
    LocalFree(ptr); 
} 

int main(int argc, char **argv) { 

    int ch; 
    char buffer[1]; 
    HANDLE file; 
    COMMTIMEOUTS timeouts; 
    DWORD read, written; 
    DCB port; 
    HANDLE keyboard = GetStdHandle(STD_INPUT_HANDLE); 
    HANDLE screen = GetStdHandle(STD_OUTPUT_HANDLE); 
    DWORD mode; 
    char port_name[128] = "\\\\.\\COM3"; 
    char init[] = ""; // e.g., "ATZ" to completely reset a modem. 

    if (argc > 2) 
     sprintf(port_name, "\\\\.\\COM%c", argv[1][0]); 

    // open the comm port. 
    file = CreateFile(port_name, 
     GENERIC_READ | GENERIC_WRITE, 
     0, 
     NULL, 
     OPEN_EXISTING, 
     0, 
     NULL); 

    if (INVALID_HANDLE_VALUE == file) { 
     system_error("opening file"); 
     return 1; 
    } 

    // get the current DCB, and adjust a few bits to our liking. 
    memset(&port, 0, sizeof(port)); 
    port.DCBlength = sizeof(port); 
    if (!GetCommState(file, &port)) 
     system_error("getting comm state"); 
    if (!BuildCommDCB("baud=19200 parity=n data=8 stop=1", &port)) 
     system_error("building comm DCB"); 
    if (!SetCommState(file, &port)) 
     system_error("adjusting port settings"); 

    // set short timeouts on the comm port. 
    timeouts.ReadIntervalTimeout = 1; 
    timeouts.ReadTotalTimeoutMultiplier = 1; 
    timeouts.ReadTotalTimeoutConstant = 1; 
    timeouts.WriteTotalTimeoutMultiplier = 1; 
    timeouts.WriteTotalTimeoutConstant = 1; 
    if (!SetCommTimeouts(file, &timeouts)) 
     system_error("setting port time-outs."); 

    // set keyboard to raw reading. 
    if (!GetConsoleMode(keyboard, &mode)) 
     system_error("getting keyboard mode"); 
    mode &= ~ ENABLE_PROCESSED_INPUT; 
    if (!SetConsoleMode(keyboard, mode)) 
     system_error("setting keyboard mode"); 

    if (!EscapeCommFunction(file, CLRDTR)) 
     system_error("clearing DTR"); 
    Sleep(200); 
    if (!EscapeCommFunction(file, SETDTR)) 
     system_error("setting DTR"); 

    if (!WriteFile(file, init, sizeof(init), &written, NULL)) 
     system_error("writing data to port"); 

    if (written != sizeof(init)) 
     system_error("not all data written to port"); 

    // basic terminal loop: 
    do { 
     // check for data on port and display it on screen. 
     ReadFile(file, buffer, sizeof(buffer), &read, NULL); 
     if (read) 
      WriteFile(screen, buffer, read, &written, NULL); 

     // check for keypress, and write any out the port. 
     if (kbhit()) { 
      ch = getch(); 
      WriteFile(file, &ch, 1, &written, NULL); 
     } 
    // until user hits ctrl-backspace. 
    } while (ch != 127); 

    // close up and go home. 
    CloseHandle(keyboard); 
    CloseHandle(file); 
    return 0; 
} 
+0

好吧,這似乎解決了線程問題,但我似乎無法得到ReadFile()來填充我的輸出數組。 – lYriCAlsSH 2011-05-17 22:30:10

+0

@lYriCAlsSH:見編輯答案。 – 2011-05-17 22:53:46

+0

我應該澄清,我試圖通過串行與嵌入式系統進行通信,並且其請求/響應協議基於字符串。我有它在超級終端上工作,但我試圖創建我自己的代碼,基本上是一樣的事情。 – lYriCAlsSH 2011-05-17 23:12:18

2

ReadFile函數可能會阻塞您的線程,如果是這樣,它將保持阻塞狀態,直到可以從串口讀取一些數據爲止。這裏有一個link看看是否有幫助。祝你好運。

1

我有一個讀取文件,超時設置這個問題。這讓我變得非常脆弱,所以我最終從網上獲得了一些代碼,然後逐行更改,以查看錯誤的來源。

原來他的readfile很好。我的問題是一個WaitCommEvent掛在端口斷開連接時,因爲沒有收到com事件...