Forum: Mikrocontroller und Digitale Elektronik UART Daten empfangen


von Heiß Michael (Gast)


Angehängte Dateien:

Lesenswert?

Zervas

Also folgendes Problem:
Ich verwende in meinem Programm alle drei Timer.
(der Timer 0 verursacht einen Interrupt)

Und wenn ich jetzt Daten über den UART empfangen will dann bekommt der
µP teilweise gar nicht mit das Daten ankekommen sind. Ich vermute weil
er gerade in einer Interrupt Routine ist und deshalb nichts anderes
machen kann.
(UART Polling verfahren in main )

Wenn ich die Daten interruptgesteuert Empfange (mit Empfangspuffer)
hilft das auch nichts. Die meisten Daten werden nicht empfangen
sobald die Interrupts per TIMSK=0xFF freigegeben werden.

Ich verwende den ATMEGA 163, Takt 3.68Mhz und UART 115200 Bps

Das Programm habe ich mittels Code Vision CAvr erstellt.
(mittels Wizard die UART Routine für den Interrupt)

Was kann ich machen das ALLE Daten garantiert empfangen werden?

Anhang: Source Code.

von Kay (Gast)


Lesenswert?

hi,

ich kenn mich in c zwar nicht aus, aber haste mal ne geringere Baudrate
probiert. nur mal testweise ?

mfg Kay

von Heiß Michael (Gast)


Lesenswert?

hab ich getestet hat aber auch nichts gebracht.

von thkais (Gast)


Lesenswert?

Der µC bekommts garantiert mit, denn der UART-Empfang ist völlig
unabhängig von irgendwelchen Interrupts. Das Problem liegt
wahrscheinlich irgendwo in den Tiefen des Compilers begraben, evtl.
Timing-Probleme mit den anderen Interrupts (evtl. kommen die öfters,
als das Programm sie verarbeiten kann).

von crazy horse (Gast)


Lesenswert?

das Problem wird in deiner timer0-ISR liegen, die Laufzeit ist viel zu
hoch, noch dazu mit printf() drin. Ist der Tx-Buffer wenigstens gross
genug, die max. Anzahl der zu sendenden Bytes aufzunehmen? Wenn nicht,
gehst du in einer ISR quasi in den Polling-Betrieb der Uart.
Aber der Gesamtansatz der ISR ist falsch.
Setze in der Timer0-ISR nur ein flag, welches anzeigt, dass der Timer
übergelaufen ist. Im Hauptprogramm fragst du das flag ab - wenn es
gesetzt ist, rufst du eine Funktion auf, die all das erledigt, was du
jetzt direkt in der ISR machen willst. Damit bleiben dir andere Ints
erhalten.

von Heiß Michael (Gast)


Lesenswert?

Der Empfangspuffer ist groß genung gewählt.

Das mit dem Verlagern der Routinen in das Hauptprogramm ist eine gute
Idee.
Die printf Befehle sind nur zum testen und kommen später wieder raus.

Werde mal versuchen alle nicht zeitkritischen Sachen im Hauptprogramm
unterzubringen.

Thx

von crazy horse (Gast)


Lesenswert?

noch was: CV geht nicht gerade sparsam mit der Rettung der Register um,
das ist zwar bei dir kein RAM-Problem, aber es kostet völlig unnötig
Zeit

bit timer0_ready;

#pragma savereg-
interrupt [TIM0_OVF] regler(void)
{#asm
  push r30
  in sreg, r30
#endasm
timer0_ready=1;
#asm
  out sreg, r30
  pop r30
#endasm
}
#pragma savereg+

Beschränkt die Laufzeit fast auf das mögliche Minimum.

von crazy horse (Gast)


Lesenswert?

der in-Befehl ist natürlich falsch herum :-)

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.