Forum: Mikrocontroller und Digitale Elektronik Hilfe zur Seriellen Schnittstelle Atmega128


von Hans K. (losti85)


Lesenswert?

Hallo habe da ein Problem. will die Serielle Schnittstelle für einen 
Gewissen Zeitraum Sperren. Ich benutze zum übertragen den Buffer Empty 
Interrupt des UDR Registers. Hier schriebe ich immer ein Byte in den 
Buffer.
Wenn ich nun Allerdings den Buffer Emtpy Interrupt speere gehen einige 
Bytes verloren :

Das ganze sieht so aus:

UCSR1B &= ~( 1 << UDRIE1 );

Also dachte ich mir warte ich bis das Register leer ist und speere es 
dann.

while(UDRE1 != 1);
UCSR1B &= ~( 1 << UDRIE1 );

Hier bei hängt sich aber manchmal der ganze mikrocontroller auf was ich 
nicht verstehe. Auch wenn er in der Entlosschleife ist müssten doch die 
Bytes übertragen werden oder nicht. Oder hat jemand noch eine andere 
idee zum speeren.

Auch bei der Möglichkeit die gesamte sendeübertragung zu speeren führt 
zu einem verlust der bytes.

UCSR1B &= ~(1<<TXEN1);

Helft mir bitte ich muss aber bei der Variante mit dem Buffer Empty 
Intterupt bleiben.

Liebe Grüße

Hans

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Häh?

Du hast einen "Atmega128" und einen "Irgendwas".

Atmega128 sendet über RS232 an Irgendwas.
Atmega128 empfängt über RS232 von Irgendwas. Es kommt beim Empfänger 
Irgendwas manchmal zu fehlenden Zeichen. Das Senden vom Atmega128 aus 
wird mit dem Buffer-Empty-Interupt Verfahren gemacht.

Wenn der Buffer-Empty-Interupt zeitweise gesperrt wird, kommt es zu 
Zeichenverlusten beim Senden (Erkennbar auf Irgendwas).

[X] logisch
[ ] unlogisch

> while(UDRE1 != 1);
> Hier bei hängt sich aber manchmal der ganze Mikrocontroller auf.

[ ] logisch
[X] unlogisch, wenn die mit UDRE1 definierte Bitnummer ungleich 1 ist 
(ist sie) müsste der µC sich immer "aufhängen"

Angenommen die Zeichenverluste entstehen beim Empfänger, weil der 
Atmega128 die Zeichen zu schnell hintereinander sendet.

Die Idee den Buffer-Empty-Interupt zu sperren und ein bisschen Zeit im 
Hauptprogramm zu vertrödeln bevor das nächste Zeichen gesendet wird, ist 
an sich schon machbar.

Es kommt darauf an, wo das Sperren gemacht wird (in der ISR) und wie der 
Restcode damit umgeht (Senderoutine muss manuell das erste Zeichen auf 
den Weg bringen und den Buffer-Empty-Interupt wieder zulassen).

Allein, ich sehe dann nicht mehr den Vorteil des Buffer-Empty-Interupt 
Verfahrens, wenn dieser Interrupt zu oft gesperrt/entsperrt wird. Dann 
könnte man genauso gut alles manuell machen. Normal sperrt man nur, wenn 
der programminterne Sendepuffer leer ist und entsperrt wenn wieder was 
drin ist.

Ich würde das Buffer-Empty-Interupt Verfahren nicht stören und 
stattdessen mit niedrigeren Baudraten und/oder einem kleineren 
Sendepuffer (Anzahl Bytes pro Sendevorgang, bzw. Pause nach x Bytes) 
experimentieren.

Langfristig könntest du mal über Handshake nachdenken, mit dem der 
empfänger von Irgendwas dem Sender Atmega128 mitteilen kann, dass er 
momentan "die Schnauze voll hat"

von Hans K. (losti85)


Lesenswert?

Hallo habe es denke ich etwas falsch ausgedrückt. Der Buffer Empty 
Interrupt eigentlich nur gespeert wenn mein Buffer leer ist ich will ihn 
nun an einer stelle im Programm besipielsweise für 45 ms (die feste 
eingehalten werden müssen) speeren weil in dieser zeit Daten über eine 
andere Schnittstelle verschickt werden und diese Zeit darf nicht durch 
einen Buffer Empty Interrupt unterbrochen werden der bei größeren Mengen 
zu oft aufgerufen wird und mein Zeitraster sprengt. Wie ist den das 
UDRE1 Register belegt wenn es leer ist. Sowie ich das aus dem Atmega 
abgelesen habe auf 1,.

von Jean P. (fubu1000)


Lesenswert?

Hoi,
probier mal while(!(UCSR1A & (1 << UDRE1)));
dann wirds schon gehen.

Gruß

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.