mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Receive vom PC. Erstes Zeichen ist ständig 0


Autor: Andreas E. (everest_75)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend zusammen,

ich komm einfach nicht mehr weiter.
Die Situation: Ein PC Programm (C++) sendet seriell Daten raus.
Empfangsseite ist ein Nucleo Board mit STM32F103.
Er empfängt die Bytes alle korrekt bis auf das Erste. Das wird immer als 
Null empfangen.

Ausschnitt des  PC-Code:
while (sendBuffer[i] != 0)
 {
        printf("%d\n", sendBuffer[i]);  // hiermit prüfe ich dass 
        i++;                            // sendBuffer richtig belegt ist
 }
                  

                  
                      object.connect("COM4");
                      object.sendArray(sendBuffer, sizeof(sendBuffer));
                      object.disconnect();


Empfangsseite Mikrocontroller, im UART-receive-Interrupthandler:
if(USART_GetITStatus(USART2, USART_IT_RXNE))
{
  USART_ClearITPendingBit(USART2, USART_IT_RXNE);
  

  uint8_t data = (uint8_t) USART_ReceiveData(USART2);

  receivedString[counter] = data;
  counter++;
}
Jetzt lese ich im Debug Modus (CooCox CoIDE) receivedString aus. Und 
siehe: receivedString[0] ist immer Null, alle anderen Positionen ab 
receivedString[1] sind völlig korrekt empfangen.

Und ganz seltsam: Wenn ich statt aus dem PC Programm heraus über ein 
Terminalprogramm (HTerm) von Hand das Array byteweise an den 
Mikrocontroller sende, dann funktioniert alles, auch das erste Element 
hat dann seinen richtigen Wert. Also zumindest auf µC Seite dürfte das 
einen fehler im Code ausschliessen, oder?

Irgendjemand auch nur den kleinsten Anhaltspunkt?

Autor: Sascha W. (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

du solltest die Schnittstelle nicht immer am Ende der Übertragung 
schließen. Kann sein das dann beim öffnen der Schnittstelle auf der 
TX-Leitung ein Flanke auftritt die am Empfänger zu einem Nullbyte führt.
Ist das Nullbyte zusätzlich oder wird das erste Nutzbyte zu selbigem?

Sascha

Autor: Andreas E. (everest_75)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das erste Nutzbyte kommt als Nullbyte an, das echte Nutzbyte ist also 
nicht auswertbar.

Zum Schliessen der Verbindung:
das findet nur einmalig statt. Die PC Anwendung soll nur einmal pro 
Durchlauf einen Datensatz an den µC senden. Der komplette Datensatz ist 
in sendBuffer gespeichert. Dass die richtigen daten drin sind hab ich 
vorher nochmal mt printf nachgeprüft.
Also einmal soll der datensatz gesendet werden und fertig. nach dem 
Close des Ports ist das Programm fertig.

: Bearbeitet durch User
Autor: dummschwaetzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
counter volatile?

Autor: Sascha W. (sascha-w)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Andreas E. schrieb:
> Das erste Nutzbyte kommt als Nullbyte an, das echte Nutzbyte ist also
> nicht auswertbar.
ok, mit HTerm öffnen und dann Daten senden geht schreibst du. Da du in 
HTerm ja nicht sofort nach dem öffnen des Programms sendest, würd' ich 
mal testhalber zwischen öffnen der Schnittstelle und senden der Daten 
50ms Pause machen.
Was genau passiert müsste man sich mal mit einem Oszi oder LA anschauen. 
Kannst du mal am μC dafür sorgen das ein Frameerror angezeigt wird.

Sascha

Autor: R. M. (restmuell) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Benutzt du eventuell, außer den Datenleitungen (RxD und TxD) noch die 
Modemsteuerausgänge (DTR oder RTS) für irgendwelche 
Steuerungs/Stromversorgungszwecke? Die werden ja üblicherweise erst mit 
dem Öffnen der Schnittstelle aktiv. Nicht das hier eine Verzögerung rein 
kommt.

Autor: Andreas E. (everest_75)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie geht denn in C++ eine verzögerung?  ich kenns nur beim µC mit Timern 
und so.

Autor: Andreas E. (everest_75)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, leider hilfts auch nicht.
Hatte jetzt einmal Sleep(50) und einmal Sleep(200)

jeweils zwischen object.connect(); und  object.sendArray(sendBuffer, 
sizeof(sendBuffer));

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas E. schrieb:
> while (sendBuffer[i] != 0)
>  {
>         printf("%d\n", sendBuffer[i]);  // hiermit prüfe ich dass
>         i++;                            // sendBuffer richtig belegt ist
>  }

Und wie sieht i aus, bevor Du diesen Codeschnipsel aufrufst?

Was ist "objekt"?

Autor: Harry L. (mysth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas E. schrieb:
> Empfangsseite Mikrocontroller, im
> UART-receive-Interrupthandler:if(USART_GetITStatus(USART2,
> USART_IT_RXNE))
> {
>   USART_ClearITPendingBit(USART2, USART_IT_RXNE);
>
>
>   uint8_t data = (uint8_t) USART_ReceiveData(USART2);
>
>   receivedString[counter] = data;
>   counter++;
> }

Sollten nicht ZUERST die Daten abgeholt werden, und DANACH Das 
Pending-Bit gelöscht werden?

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas E. schrieb:
> Irgendjemand auch nur den kleinsten Anhaltspunkt?

Hänge einen Logikanalysator auf die Schnittstelle. Dann weisst du, was 
dort wirklich läuft und wo du den Fehler suchen musst.
So ein Ding kostet weniger als die Zeit, um hier den Thread zu öffenen 
und zu verfolgen (Ebay-Artikel Nr. 201541710029).

Autor: Jim M. (turboj)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Harry L. schrieb:
> Sollten nicht ZUERST die Daten abgeholt werden, und DANACH Das
> Pending-Bit gelöscht werden?

Nein. So herum ist richtig(er). Wenn verspätet noch ein Zeichen ankommt, 
dann möchte man das sofort via Tail-Chain abholen. Anderenfalls ist so 
das Pending Bit auf jeden Fall gelöscht vor dem Interrupt return.

Beitrag #5026136 wurde von einem Moderator gelöscht.
Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also nach dem power on in der Init würde ich ja sagen:

counter=0;
while(USART_GetITStatus(USART2, USART_IT_RXNE))
  uint8_t data = (uint8_t) USART_ReceiveData(USART2);

um Reste zu leeren.

und dann erst in die endlos loop gehen.

: Bearbeitet durch User
Autor: Andreas E. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, Leute .
Danke für die vielen Tipps. Aber wahrscheinlich muss ich doch meine 
hardware überprüfen, im mom. hab ich da kein Werkzeug für da. Irgendwas 
stimmt einfach nicht an der seriellen Schnittstelle.

Seit heute morgen ging es nicht mal mehr über HTerm, was gestern noch 
ging.

Deshalb machen die Vermutungen, im µC Code stimme was nicht, wie ob erst 
Interrupt Flag zurücksetzen und dann lesen oder umgekehrt, eher wenig 
Sinn.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.