Forum: Mikrocontroller und Digitale Elektronik USART Senden nur mit Verzögerungsschleife


von Sigi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe folgendes Problem. Das Senden von Daten vom AVR ATmega8 über 
die serielle Schnittstelle zum PC funktioniert nur wenn die eine 
zusätzliche Verzögerungsschleife einbaue.

AVR ATmega8
Takt: 8Mhz
Baud: 9600


Eigentlich sollte es aber mit

while( !(UCSRA & (1 << UDRE)));

auch funktionieren ? Da es aber ohne die Schleife nicht klappt liegt die 
Vermutung nahe, das es irgendwie Probleme bei der Erkennung, ob das 
Sendedatenregister leer ist oder nicht, gibt.

Die Schleife hilft erst ab ca 700 durchläufen, was ja ca. der 
Übertragungszeit der 8 Bit + Start, Stoppbit entspricht (9 Takte  700  
8e6)

im Anhang befindet sich noch der Quellcode aufs wesentliche beschränkt.

Danke schonmal im voraus.

MfG Sigi

von Sven (Gast)


Lesenswert?

Hallo,

habe mal eben schnell den Code durchgesehen, UBRRH ist nicht definiert - 
zur Definition der Baudrate gibt es ein High- und ein Lowregister. 
Ferner ist es wohl besser das Senden von Zeichen in Form einer Routine 
zu gestalten, und nicht in der "main".
Besser noch mal die Examples zum Thema USART im Manual nachlesen, den 
C-Code kann man 1:1 übernehmen.

von Stefan E. (sternst)


Lesenswert?

Es funktioniert also nur, wenn du zwischen den Zeichen eine kurze Pause 
erzwingst. Meine Schlussfolgerung: du hast am Empfänger 2 Stoppbits 
eingestellt.

So nebenbei:
1
UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
Das ist eine ganz schlechte Idee.
Konkret steht da nämlich im Augenblick:
1
UCSRC = UBRRH | ((1<<URSEL) | (1<<UCSZ1) | (1<<UCSZ0));
Gut, UBRRH ist bei dir im Augenblick 0, so dass es kein fehlerhaftes
Verhalten verursacht, trotzdem würde ich das "|=" schleunigst in ein "="
umwandeln.
(Ich glaube, ich muss mir mal diesen Text als Textbaustein hinterlegen 
:-)

von Sigi (Gast)


Lesenswert?

Hallo Sven,

das mit dem Baud Rate Register High hab ich so verstanden, das durch die 
Auswahl URSEL = 0 bzw 1 entweder der UBRRH angesprochen wird oder eben 
das Statusregister UCSRC, da sie eben auf der gleichen Addresse liegen ?
achja die Funktion hab ich einfach vor die main gepackt das es 
übersichtlich und aufs wesentliche beschränkt ist.

MfG Sigi

von Sigi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Stefan,

ich verstehe nicht ganz was an UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 
<< UCSZ0); ohne das "|=" besser sein soll ?
Achja ich habe festgestellt das es manchmal auch ohne die Warteschleife 
funktioniert. Sobald ich beim Terminalprogramm auf "Verbinden" klicke, 
kommen entweder die richtigen Zeichen an oder auch nicht .. scheint 
irgendwie ein Glückspiel zu sein.
Ich hab auch noch die Funktion mit Interrupt getestet (siehe Anhang), 
leider funktioniert die auch nicht besser wie die ohne Interrupt.

MfG Sigi

von STK500-Besitzer (Gast)


Lesenswert?

>ich verstehe nicht ganz was an UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1
><< UCSZ0); ohne das "|=" besser sein soll ?

das "|=" nimmt den Inhalt des davor stehenden Registers und verodert ihn 
mit der rechten Seite vom Gleichheitszeichen.
Das Ergebnis hat einen Bezug auf das, was vorher in dem Register stand.

Lässt man das Oder weg, hat der Inhalt nach der Zuweisung keinen Bezug 
mehr zum Inhalt vor der Zuweisung.
Wenn man das ("|=") bei Registern macht, die mehrere Bedeutungen haben, 
dann führt das zu Fehlern oder zumindest unerwartetem Verhalten...

von dummy (Gast)


Lesenswert?

>Sobald ich beim Terminalprogramm auf "Verbinden" klicke,
>kommen entweder die richtigen Zeichen an oder auch nicht .. scheint
>irgendwie ein Glückspiel zu sein.

Benutzt du einen Quarz oder den internen Oszi?

von Sigi (Gast)


Lesenswert?

ich habe jetzt einen ext. 8 Mhz Quarz, mehrere verschiedene Frequenzen 
des STK 500 Boards und einige interne Oszi-Frequenzen versucht. Immer 
mit dem gleichen Ergebnis: sobald ich "verbinde" kommt entweder das 
richtige Zeichen oder eben diese Quadrate(?). Das ändert sich auch nicht 
mehr bis ich erneut auf "verbinden" klicke.

zu dem "|=" Thema:
wenn ich das "oder" weglasse schreibt er in dem Bsp.
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
doch sowas wie 10000110 ins UCSRC.

Wenn ich aber
UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); schreibe setzt er 
nur die Bits an den entsprechenden Stellen und ignoriert die restliche 
Stellen.
also sowas wie verknüpfe 10000110 mit dem akt. UCSRC und schreibt das 
Ergebnis ins UCSRC.
Die Methode ohne das "oder" würde doch dann nur Sinn machen, wenn man 
wirklich die anderen Bit-Stellen löschen möchte ?

von Stefan E. (sternst)


Lesenswert?

Sigi wrote:

> UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); schreibe setzt er
> nur die Bits an den entsprechenden Stellen und ignoriert die restliche
> Stellen.
> also sowas wie verknüpfe 10000110 mit dem akt. UCSRC und schreibt das
> Ergebnis ins UCSRC.
> Die Methode ohne das "oder" würde doch dann nur Sinn machen, wenn man
> wirklich die anderen Bit-Stellen löschen möchte ?

Es geht darum, dass bei der Oder-Variante das Register UCSRC ja auch 
gelesen werden muss. Das Register teilt sich aber eine Adresse mit dem 
Register UBRRH und muss über eine bestimmte Prozedur gelesen werden. 
Beim "einfachen" Lesen bekommt man den Inhalt von UBRRH.
1
UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
ist also das gleiche wie:
1
UCSRC = UBRRH | ((1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0));

von Falk B. (falk)


Lesenswert?

@Sigi (Gast)

>mit dem gleichen Ergebnis: sobald ich "verbinde" kommt entweder das

Wie verbindest du? Stecker an den PC anstecken?

>richtige Zeichen oder eben diese Quadrate(?). Das ändert sich auch nicht
>mehr bis ich erneut auf "verbinden" klicke.

Wahrscheinlich liegt es daran.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART#Senden_von_Zeichen

MfG
Falk

von Hans-jürgen H. (hjherbert) Benutzerseite


Lesenswert?

Versuch es mal an COM1 anstatt am USB-Seriell-Umsetzer. Diese Dinger 
ärgern mich auch dauernd.

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.