2013-03-04 30 views
5

Tôi có một dữ liệu gửi dữ liệu Mirocontroller Atmel mà tôi muốn nhận trên PC của mình qua COM1.Tôi nhận được thư rác trên cổng nối tiếp

Khi tôi đính kèm chương trình đầu cuối, dữ liệu được nhận chính xác (tất cả đều là ascii, tất cả có thể in ngoại trừ \ n).

Tuy nhiên, mã của tôi dường như đang nhận được thư rác (ký tự không phải ascii). Ai có thể nhìn thấy những gì tôi đang làm sai? Cảm ơn

Gửi mã, chỉ để biết

// USART options. 
static const usart_options_t USART_CONSOLE_OPTIONS = 
{ 
    .baudrate  = 115200, 
    .charlength = 8, 
    .paritytype = USART_NO_PARITY, 
    .stopbits  = USART_1_STOPBIT, 
    .channelmode = USART_NORMAL_CHMODE 
}; 

Tiếp nhận đang

E_boolean OpenCom1(void) 
{ 
    COMMTIMEOUTS timeouts; 

    comPortHandle = CreateFile("COM1", // Specify port device: default "COM1" 
    GENERIC_READ | GENERIC_WRITE,  // Specify mode that open device. 
    0,         // the device isn't shared. 
    NULL,        // the object gets a default security. 
    OPEN_EXISTING,      // Specify which action to take on file. 
    0,         // default (not overlapped i/o). 
    NULL);        // default (hTemplate must be NULL for COM devices). 

    if (comPortHandle == INVALID_HANDLE_VALUE) 
     return False; 

    deviceControlBlock.DCBlength = sizeof(deviceControlBlock); 

    if((GetCommState(comPortHandle, &deviceControlBlock) == 0)) 
    { 
     // CodeMe: do what? 
     return False; 
    } 

    deviceControlBlock.BaudRate = CBR_115200; 
    deviceControlBlock.StopBits = ONESTOPBIT; 
    deviceControlBlock.Parity = NOPARITY; 
    deviceControlBlock.ByteSize = DATABITS_8; 
    deviceControlBlock.fRtsControl = 0; 

    if (!SetCommState(comPortHandle, &deviceControlBlock)) 
    { 
     // CodeMe: do what? 
     return False; 
    } 

    // set short timeouts on the comm port. 
    timeouts.ReadIntervalTimeout = MAXDWORD; 
    timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; 
    timeouts.ReadTotalTimeoutConstant = 1000; // oen second 
    timeouts.WriteTotalTimeoutMultiplier = 1; 
    timeouts.WriteTotalTimeoutConstant = 1; 
    if (!SetCommTimeouts(comPortHandle, &timeouts)) 
    { 
     // CodeMe: do what? 
     return False; 
    } 

    FlushFileBuffers(comPortHandle); 

    PurgeComm (comPortHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR); 

    return True; 
}//OpenCom1() 

// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= 
void  ReadCharacterFromCom1(INPUT char *theCharacter) 
{ 
    DWORD numBytesRead; 

    numBytesRead = 0; 

    while (numBytesRead == 0) 
    { 
     ReadFile(comPortHandle,   // handle of file to read 
       theCharacter,   // store read data here 
       sizeof(char),   // number of bytes to read 
       &numBytesRead,   // pointer to number of bytes actually read 
       NULL); 
    } 

    return; 
}//ReadCharacterFromCom1() 
+1

Ý anh là gì bởi "rác"? Làm thế nào để bạn biết "rác" không phải là do tiếng ồn điện? –

+0

@HotLicks +1 Tôi có nghĩa là không phải ascii ký tự và kể từ khi một chương trình thiết bị đầu cuối nhận được một cách chính xác tôi nghiêng để đổ lỗi cho mã của riêng tôi. – Mawg

+2

Bạn đã thử in giá trị thập lục phân của mỗi byte nhận được thông qua 'theCharacter'? – Tuxdude

Trả lời

5

Hàm "ReadFile" được gọi với "sizeof (char)" để biết số byte cần đọc. Điều này sẽ được đánh giá là 1, có thể không phải là giá trị mà bạn dự định. Kết quả là mọi cuộc gọi đến ReadCharacterFromCom1 sẽ chỉ đọc 1 ký tự hợp lệ từ cổng và trả về, phần còn lại mà bạn thấy là các phần còn lại trong bộ đệm vì bộ đệm không được (thủ công) chấm dứt bằng một giá trị rỗng.

Đề nghị bạn nên thay đổi nó thành:

/* ============================================================ */ 
DWORD ReadCharacterFromCom1(char *pszBuffer, int nMaxCharToRead) 
{ 
    DWORD dwBytesRead = 0; 
    while (dwBytesRead == 0) 
    { ReadFile(comPortHandle, // handle of file to read 
      pszBuffer, // store read data here 
      nMaxCharToRead, // number of bytes to read 
      &dwBytesRead, // pointer to number of bytes actually read 
      NULL); 
    } 
    // terminate string with null 
    pszBuffer[dwBytesRead] = 0; 
    return dwBytesRead; 
} 

// test code ------------------------ 
char szBuffer[512]; 
DWORD dwCount = ReadCharacterFromCom1(szBuffer, sizeof(szBuffer)-1); 
printf(_T("Receive %d chars: <%s>"), nCount, szBuffer); 
2

Giả sử tốc độ truyền, số bit dữ liệu, tính chẵn lẻ và số bit dừng được thiết lập một cách chính xác bạn likley nhất thiếu thiết lập bất kỳ loại điều khiển luồng nào. Bạn không chỉ cho chúng tôi (đầy đủ) cách bạn khởi tạo DCB.

Kiểm soát luồng ức chế tràn bộ đệm trong người gửi/người nhận.

Tùy thuộc vào loại cáp nối tiếp bạn sử dụng và loại dữ liệu nào sẽ được chuyển giao điều khiển luồng phần mềm hoặc phần cứng có thể được sử dụng.

Điều khiển lưu lượng phần cứng là loại điều khiển luồng ưa thích vì nó hoạt động cho đồng bộ ASCII dữ liệu nhị phân cần chuyển. Requiers của nó một kết nối nối tiếp hoàn toàn có dây. Nó cũng được gọi là RTS và/hoặc kiểm soát dòng chảy DTR.

Nếu bạn chỉ có cáp ba chiều RS232/V.24 tối thiểu, bạn có thể muốn sử dụng điều khiển luồng phần mềm (cũng được gọi là bắt tay Xon/Xoff). Điều khiển lưu lượng Xon/Xoff-handshake chỉ hoạt động với dữ liệu ASCII. Để gửi dữ liệu nhị phân thông qua kết nối như vậy, nó cần được mã hóa thành ASCII thuần túy. Sử dụng mã hóa base64 để làm ví dụ.

Làm thế nào để thiết lập kiểm soát dòng chảy dưới cửa sổ bạn có thể muốn đọc ở đây: http://www.cplusplus.com/forum/windows/89698/

http://msdn.microsoft.com/en-us/library/ff802693.aspx này có thể đóng vai trò như một tài liệu tham khảo.

+1

Kiểm soát luồng không tốt sẽ không làm cho rác xuất hiện trên màn hình, nhưng sẽ có tốc độ truyền sai. sẽ tốt hơn là anh ta chỉ cố gắng gửi các ký tự đơn với một khoảng dừng khổng lồ giữa chúng, điều đó sẽ tách biệt ra vấn đề kiểm soát dòng chảy tiềm ẩn, và điều duy nhất có thể làm là vấn đề tốc độ truyền, hoặc vấn đề với cách anh ta vượt qua con trỏ của mình xung quanh trong mã. –

+1

@ c.fogelklou: Câu trả lời của tôi ngụ ý bốn thông số cơ bản đã được thiết lập chính xác. Nhưng bạn đúng, điều này không nhất thiết phải là trường hợp. Tôi đã cập nhật câu trả lời của mình cho phù hợp. – alk

Các vấn đề liên quan