Forum: Mikrocontroller und Digitale Elektronik Timing - Problem beim UART


von Christoph R. (Gast)


Lesenswert?

Hallo zusammen,
ich habe ein Problem mit dem Timing, das denke ich zumindest.
Also ich habe folgendes gemacht:
Wenn keine Daten mehr verfügbar, also alles abgehandelt wurde, dann soll 
das Programm die while()- Schleife verlassen, aber da ja am Ende der 
while die bedingung für das verlassen abgefragt wird,und knapp davor die 
daten abgeholt wurden, ist anscheinen noch kein neues Zeichen 
nachgerückt...
ich arbeite dabei mit einer baudrate von 4800.


so ungefähr könnte das meiner meinung nach ablaufen
Es liegen Daten vor
[ H ]allo
Daten abrufen (H wird gelesen, Empfangsbuffer leer)
[   ]allo
Abfrage zum verlassen der while-schleife (buffer = leer, also alle daten 
abgeholt)
[ a ]llo (jetzt erst rückt das next zeichen nach, aber schleife wurde 
bereits verlassen)

läuft das wirklich so ab? oder liegt mein Problem woanders ?
Das ganze funktioniert ebenso wenig mit dem RX-Complete Interrupt, da 
passiert das gleiche....
Ich denke da muss ich mit einer kurzen verzögerung arbeiten und zwar an 
der stelle // ## ### ## //
oder kennt jemand eine andere Lösung ??

////////////////////////////////////////////////////
while(1)
{
if((UCSRA & (1<<RXC)))   // wenn Zeichen verfuegbar
{
  while((UCSRA & (1<<RXC)))
  {
    uart_putc(Usart_Rx());
    // ## ### ## //
  }
  freshdata=1;
}
else
{
  if(freshdata==1)
  {
    uart_putc('N');
    freshdata=0;
  }
  else
  {

  }

}
}
////////////////////////////////////////////////////

von Karl H. (kbuchegg)


Lesenswert?

> Ich denke da muss ich mit einer kurzen verzögerung arbeiten und zwar an
> der stelle // ## ### ## //

Verzögerungen sind selten eine gute Idee.
Was, wenn der Sender einmal ein kleines bischen länger
braucht als deine Verzögerungszeit eingestellt ist.

> oder kennt jemand eine andere Lösung ??

Normalerweise macht man das so, dass man sich in der
Übertragung spezielle Zeichen definiert, die ein
Ende der Übertragung signalisieren. Sowas nennt man
dann Protokoll. Neben den reinen Nutzdaten, werden noch
Steuerdaten übertragen, die den Datenverkehr regeln.

zb. könntest du vereinbaren, dass am Ende eines Textes
immer ein ';' kommen muss. An diesem ';' erkennt dann
der Empfänger, dass der Text vollständig ist. Im ASCII
Code gibt es auch bei den Steuerzeichen (die mit den
kleinen Codes) spezielle Zeichen, die extra dafür vorgesehen
sind:  <STX> (Start of Text) und <ETX> (End of Text).

Eine zeitliche Steuerung benutzt man dann nur mehr um grobe
Fehler zu finden: Wenn nach Beginn einer Übertragung nach
zb. 5 Sekunden nicht das Ende Zeichen empfangen wurde, dann
wird die Übertragung komplett als gescheitert erklärt und
das bisher Emfangene verworfen.

von Christoph R. (Gast)


Lesenswert?

Bei den zu empfangenen Daten handelt es sich um NMEA-Daten aus einem 
GPS-Empfänger, da kann ich nix am Protokoll oder an den Daten ändern....
das Gert läuft mit 4800 BAUD kann man da nicht drüber ausrechnen, wie 
lange die Daten brauchen, also wann alle xsekunden ein neues zeichen bei 
4800 baud und 8MHZ kommt???
Dann könnte ich dementsprechend meine Wartezeit einrichten...

von Christoph R. (Gast)


Lesenswert?

Schade, noch keine neuen Vorschläge

von Karl H. (kbuchegg)


Lesenswert?

Christoph R. wrote:
> Bei den zu empfangenen Daten handelt es sich um NMEA-Daten aus einem
> GPS-Empfänger, da kann ich nix am Protokoll

macht ja nichts.,
Schau dir doch mal die Daten genauer an.
In den NMEA Daten ist bereits ein verwertbares Protokoll enthalten.
Jede Zeile beginnt mit ....
Jede Zeile endet mit ...


> das Gert läuft mit 4800 BAUD kann man da nicht drüber ausrechnen, wie
> lange die Daten brauchen, also wann alle xsekunden ein neues zeichen bei
> 4800 baud und 8MHZ kommt???

Vergiss die Idee mit Warten. Das ist Schrott.

Wenn du im Datenstrom das Startzeichen entdeckst, dann zeichnest
du Zeichen für Zeichen auf und sammelst die Zeichen in einem
String.
Wenn im Datenstrom das Endezeichen kommt (aber nur wenn vorher
ein Startzeichen gesehen wurde), dann beendest du die Zeichen-
sammlerei und erklärst den empfangenen String als gültig und
bearbeitest ihn.

Sinnvollerweise wird man das Empfangen eines Zeichens im
Uart Receive Interrupt machen. Dadurch ist sichergestellt, dass
kein Zeichen verloren geht.

> Dann könnte ich dementsprechend meine Wartezeit einrichten...
Wie gesagt: Leg die Idee mit der Warterei ad acta. Das führt dich
nicht zu einer Lösung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.