2013-03-04 4 views
5

Ich habe einen Atmel mirocontroller Senden von Daten, die ich auf meinem PC über COM1 erhalten möchte.Ich empfange Junk auf der seriellen Schnittstelle

Wenn ich ein Terminal-Programm anschließe, werden die Daten korrekt empfangen (es ist alles ASCII, alles bedruckbar außer für \ n).

Mein Code scheint jedoch Junk (non-ASCII-Zeichen) zu empfangen. Kann jemand sehen, was ich falsch mache? Dank

Code gesendet, nur zur Info

// 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 
}; 

Empfangen Code

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

Was verstehen Sie unter "Junk" bedeuten? Woher weißt du, dass der "Müll" nicht auf elektrischen Lärm zurückzuführen ist? –

+0

@HotLicks +1 Ich meine nicht-ASCII-Zeichen und da ein Terminal-Programm korrekt empfängt, bin ich geneigt, meinen eigenen Code zu beschuldigen. – Mawg

+2

Haben Sie versucht, den hexadezimalen Wert jedes Bytes zu drucken, das über 'theCharacter' empfangen wurde? – Tuxdude

Antwort

5

Die Funktion "ReadFile" wird mit einer "sizeof (char)" für die Anzahl der zu lesenden Bytes aufgerufen. Dies wird immer als 1 bewertet, wahrscheinlich nicht der von Ihnen gewünschte Wert. Das Ergebnis ist, dass jeder Aufruf von ReadCharacterFromCom1 nur 1 gültiges Zeichen vom Port liest und zurückgibt. Der Rest, den Sie gesehen haben, sind die im Puffer verbliebenen Dschunken, da der Puffer nicht (manuell) mit einem NULL beendet wird.

Vorschlagen, dass Sie es zu ändern:

/* ============================================================ */ 
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

Baudrate Angenommen, die Anzahl der Datenbits, Parität und die Anzahl der Stop-Bits richtig Sie am meisten likley einrichten fehlen, um irgendeine Art von Flusskontrolle einzurichten. Sie zeigen uns (vollständig) nicht, wie Sie das DCB initialisieren.

Die Flusskontrolle verhindert Pufferüberläufe im Sender/Empfänger.

Je nachdem, welche Art von serieller Verkabelung Sie verwenden und welche Art von Daten übertragen werden soll, kann eine Soft- oder Hardware-Flusssteuerung verwendet werden.

Die Hardware-Flusssteuerung ist die bevorzugte Art der Flusssteuerung, da sie für reine ASCII-Daten und Binärdaten, die übertragen werden sollen, funktioniert. Es erfordert eine vollständig verkabelte serielle Verbindung. Es wird auch als RTS- und/oder DTR-Flusskontrolle bezeichnet.

Wenn Sie nur die 3-adrige RS232/V.24-Verkabelung haben, können Sie die Software-Flusskontrolle verwenden (auch als Xon/Xoff-Handshake bezeichnet). Xon/Xoff-Handshake-Flusskontrolle funktioniert nur für ASCII-Daten, die übertragen werden sollen. Um Binärdaten über eine solche Verbindung zu senden, muss sie in reines ASCII codiert werden. Verwenden Sie zum Beispiel die base64-Codierung.

Wie Flusssteuerung unter Windows einzurichten, Sie hier lesen mögen: http://www.cplusplus.com/forum/windows/89698/

dienen könnte Diese http://msdn.microsoft.com/en-us/library/ff802693.aspx als Referenz.

+1

Eine schlechte Flusskontrolle würde nicht dazu führen, dass Müll auf dem Bildschirm angezeigt wird, sondern die falsche Baudrate haben würde. es wäre besser, wenn er gerade versucht hätte, einzelne Zeichen mit einer riesigen Pause zwischen ihnen zu senden, die das potentielle Problem der Flusskontrolle isolieren würden, und das einzige, was übrig bleiben könnte, wäre ein Baud-Raten-Problem oder ein Problem mit seinem Weg seine Zeiger im Code. –

+1

@ c.fogelklou: Meine Antwort beinhaltete, dass die vier grundlegenden Parameter korrekt eingerichtet wurden. Aber Sie haben Recht, das muss nicht unbedingt der Fall sein. Ich habe meine Antwort entsprechend aktualisiert. – alk

Verwandte Themen