Hallo Forum User,
ich bekomme jedesmal ein Timeout. Muss ich den Fehler hier suchen? Oder
müsste die Routine funktionieren? Mit dem Debugger sieht alles gut aus.
Holger P. schrieb:> Hallo Forum User,> ich bekomme jedesmal ein Timeout.
Dein Timeout ist selbst bei 'nur' 1Mhz Taktfrequenz des µC verdammt
kurz!
Timeouts bewegen sich normalerweise im knappen Sekundenbereich oder noch
höher. Aber ein paar µs? So schnell kann doch keine Gegenstation auf ein
empfangenes Byte reagieren und Antwort zurückschicken.
Du solltest mal den Sinn eines Timeouts an dieser Stelle hinterfragen.
Ein Timeout setzt man ein, wenn man eine Anforderung an die Gegenstelle
sende und diese innerhalb eines angemessenen Zeitfensters antworten
muss.
In einer reinen Empfangsroutine macht ein Timeout nicht viel Sinn. Wenn
du in der Hauptschleife pollst, dann lautet die erste Fragestellung:
* ist ein Zeichen da
-> wenn nein, dann beschäftige dich mit dem nächsten Teilproblem
-> wenn ja, dann hole das Zeichen und bearbeite es
Aber in einer reinen Lesefunktion, die nur den Zweck hat, die UART zu
pollen ist ein Timeout vollkommen sinnfrei. Timeout macht nur Sinn, wenn
man auf Antwort wartet. Und dann muss die Zeit auch angemessen sein.
Karl Heinz Buchegger schrieb:> Holger P. schrieb:>> Hallo Forum User,>> ich bekomme jedesmal ein Timeout.>> Dein Timeout ist selbst bei 'nur' 1Mhz Taktfrequenz des µC verdammt> kurz!>> Timeouts bewegen sich normalerweise im knappen Sekundenbereich oder noch> höher. Aber ein paar µs? So schnell kann doch keine Gegenstation auf ein> empfangenes Byte reagieren und Antwort zurückschicken.
Oh klar ich habe es ja selber geschrieben
0x40=55µS = 1Bit bei 19200Baud
Ich sollte schon mal 1Byte warten ;-)
Das mit dem Timout an dieser Stelle überdenke ich mir noch mal. Doch
sollte das schon so sein, wenn ich dort hin springe mus sofort das
zeichen kommen.
Holger P. schrieb:> Das mit dem Timout an dieser Stelle überdenke ich mir noch mal. Doch> sollte das schon so sein, wenn ich dort hin springe mus sofort das> zeichen kommen.
Wenn es schon da ist, dann kriegst du es auch sofort aus dem UDR
Register.
Wwnn es noch nicht da ist - dann kannst du höchstens sagen: gut ich
warte jetzt erst mal 0.5 Sekunden. Aber: dann sind wir wieder beim
allseitsbeliebten Thema: Warumn ist aktives Warten in einem µC Programm
Mist?
Und: definiere 'sofort'.
sofort geht nicht. Denn deine zuvor rausgegangene Anfrage an die
Gegenstelle muss von der Gegenstelle erst mal
komplett empfangen worden sein
bearbeitet worden sein
ausgewertet worden sein
die entsprechende Antwort zusammengestellt worden sein
die Antwort per USART auf den WEg gekommen sein
bei dir eingetroffen sein.
Du erwartest, dass du beim Briefschach deinen Zug in ein Kuvert steckst,
das in den Briefkasten wirfst und 2 Zehntelsekunden später soll die
Antwort deines Gegners per Post auch schon da sein. Ansonsten schreist
du Timeout.
Das ist nicht sinnvoll :-)
Wörter wie 'sofort', 'optimal', etc. haben in der Progammierung nichts
verloren. Ein 'sofort' existiert schlicht und ergreifend nicht. Du
kannst eine Grenze festlegen, bis zu der du bereit bist zu warten, mehr
aber auch nicht. Das ist aber nicht sofort ... und ... diese Grenze darf
nicht absurd niedrig sein. Du musst deiner Gegenstelle schon auch die
Zeit einräumen, die sie im Worst Case braucht, um zu antworten. Und dann
nimmt man diese Zeit zur Sicherheit noch mal 2 oder mal 3.
Ich klinken mich in einem Datenstrom ein. Ich fordere nich an sondern
möchte was aufschnappen was gerade vorbei läuft. Und auch nur das, nicht
ein Zeichen davor.
Wobei ich gerade gemerkt habe das er mir trotzdem die vorab empfangenen
Zeichen nicht verwirft. :-(
Dann schreibe dir einen Ringpuffer in den die Zeichen eingelesen werden.
Sobald ein Zeichen da ist sorgt die Interruptfunktion daß er im
Ringpuffer landet.
In deinem Hauptprogramm kannst du jetzt auf den Ringpuffer pollen und
wenn die Startbedingung da ist die Zeichen abholen sobald sie da sind.
Damit hast du dann sogar Zugriff auf die Zeichen vorher, falls das
notwendig ist.
Holger P. schrieb:> Ich klinken mich in einem Datenstrom ein.
Und woher weisst du daß der Sendende nicht mal ne kurze Pause macht weil
er gerade was anderes (Interrupt, bei PC andere Prozesse) zu tun hat?
Holger P. schrieb:
Genau darauf will ich dich die ganze Zeit sensibilisieren.
> Ich klinken mich in einem Datenstrom ein. Ich fordere nich an sondern> möchte was aufschnappen was gerade vorbei läuft.
Wozu dann ein Timeout?
Entweder ein Zeichen ist da, oder es ist kein Zeichen da.
Timeouts machen nur Sinn, wenn du auf ANTWORT WARTEST!
Hier
lds Dummy3, UCSR0A
xxxx Dummy3, RXC0
Ist RXC0 in UCSR0A nicht gesetzt, dann ist kein Zeichen da.
Raus aus der Routine und was anderes gemacht, bis man dann ein paar µs
später wieder neu nachsieht, ob was da ist. Kein Mensch braucht da ein
Timeout. Hier geht es nicht um die Frage "Ist zuviel Zeit vergangen".
Hier geht es einfach nur um die ganz banale Fragestellung "Zeichen da
oder Zeichen nicht da".
(Oder das ganze eben auf Interrupt Betrieb umstellen).
Nachdem ich ein Triggersignal bekommen habe muss das Zeichen sofort
(<52µs) da sein, ansonsten muss ich reagieren. Ist das Zeichen da so
muss ich es abspeichern.
Ich habe das nun so gemacht: