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
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.
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 :-)
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
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
>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...
>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?
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 ?
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)); |
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.