www.mikrocontroller.net

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


Autor: Sigi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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:
UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
Das ist eine ganz schlechte Idee.
Konkret steht da nämlich im Augenblick:
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 
:-)

Autor: Sigi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Sigi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: dummy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Sigi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.
UCSRC |= (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0);
ist also das gleiche wie:
UCSRC = UBRRH | ((1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0));

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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-Tutori...

MfG
Falk

Autor: Hans-jürgen Herbert (hjherbert) Benutzerseite
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.