Nabend zusammen,
ich habe heute den ganzen Tag damit verbracht mit einem ATMega644 ein
paar Zeichen an die serielle Schnittstelle zu senden.
Ich benutze die lib von Peter Fleury.
Atmega läuft, nein, lief mit 12MHz. Dann mal mit 8MHz und jetzt wieder
12.
Terminalprogramm war TeraTerm. Mit dem habe ich bislang immer gute
Erfahrungen gemacht.
Naja jedenfalls wollte ich einen String ("Hallo") und ein Zeichen ('C')
senden.
Der PC hat immer etwas empfangen. Im Atmega war als Baudrate 9600
eingestellt. Im Terminal auch aber da kamen nur wirre Zeichen.
Stelle ich nun im Terminal auf 14400 baud dann kam etwas in dieser Art
an: H#--*C
Fast richtig! :)
Nunja, ich habe wie gesagt den ganzen Tag rumprobiert. Einen 8MHz Quarz
genommen, Fuses tausendmal gecheckt. Nichts!!
Eben lud ich mir dann mal ein anderes Terminalprogramm runter und siehe
da: Mein String und mein Zeichen kommen in Klartext an!!! JUHU
Aber: Atmega=9600 Baud, Terminal=14400 Baud
Frage: Warum bekomme ich bei gleicher Baudrate nur Müll angezeigt? Ich
habe wie gesagt mehrere Frequenzen schon durch, mehrere Baud
Berechnungen und nie hat es geklappt.
Frage 2: Trotz ungleicher Baudraten sehe ich meine gesendeten Sachen
nicht mit TeraTerm sondern nur mit Putty oder HTerm. Warum??
Einstellungen sind die gleichen!
Und ja,
https://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
kenne ich.
Und nein, CKDIV8 ist nicht gesetzt.
Ne... Platine.
Naja hab 22pF. Konnte zwar nicht mit einem Oszi messen aber Quarz sollte
laufen.
Da hängt noch ein LCD dran und 2 serielle ICs. Also das läuft alles
soweit.
Mich wundert es halt nur, dass der String korrekt gesendet wird aber mit
unterschiedlichen Baudraten und mit ausgewählten Terminal Programmen.
Zeig doch bitte mal deinen Code - zumindest mal das USART Init. Da HTerm
auch unter Win10 völlig problemlos funktioniert, kann ich dir das nur
ans Herz legen.
Ist für Entwickler, die irgendwas mit UART oder USB Serial zu tun haben,
m.M.n. das universellste, was es gibt.
Jürgen schrieb:> 9600:8MHzx12MHz=14400> Du hast nicht zufällig die Baudrate für 8MHz betechnet und mit 12MHz> laufen lassen?
Mh... eigentlich nicht.
Hatte vorher ja alles auf 12MHz laufen und beim 8MHz die Berechnung neu
gemacht.
Jetzt läuft er wieder mit 12MHz.
9600 im Atmeg und 14400 im Terminal
Max B. schrieb:> Hatte vorher ja alles auf 12MHz laufen und beim 8MHz die Berechnung neu> gemacht.> Jetzt läuft er wieder mit 12MHz.
Da frage ich mich doch wie du die Änderungen auf die jeweils
andere Frequenz bewirkt hast. Denn so wie du dich gibst hast
du da womöglich Fehler gemacht.
Max B. schrieb:> 9600 im Atmeg und 14400 im Terminal> Jetzt läuft er wieder mit 12MHz.
14400B / 9600B = 1,5
12Mhz / 8Mhz = 1.5
Komisch, nicht wahr?
Kaum zu fassen...
und jetzt läuft es mit gleicher Baudrate und auch mit TeraTerm.
Kann mir einer sagen warum?
Ich habe jetzt ganz oft beide Möglichkeiten gesehen aber mir nichts
dabei gedacht das mal auszuprobieren.
Beo Bachta schrieb:> Max B. schrieb:>> Kann mir einer sagen warum?>> Du redest nicht mit jedem der dir helfen will ...> ... heute keine Bauernsprechstunde, wa?>> Nur weiter so!
Doch, schon.
Aber ich habe mir meine Frage gerade schon selber beantwortet.
Bei den 12MHz sollte das UL hinter die Baudrate um den Überlauf zu
umgehen.
Warum das aber bei 8MHz nicht geklappt hat weiß icj nicht.
Und die MHz hab ich auch schön in Hz angegeben.
Max B. schrieb:> Doch, schon.> Aber ich habe mir meine Frage gerade schon selber beantwortet.> Bei den 12MHz sollte das UL hinter die Baudrate um den Überlauf zu> umgehen.
Damit steht fest dass du nichts von dem verstanden hast was
ich gefragt habe.
Beo Bachta schrieb:> Max B. schrieb:>> Doch, schon.>> Aber ich habe mir meine Frage gerade schon selber beantwortet.>> Bei den 12MHz sollte das UL hinter die Baudrate um den Überlauf zu>> umgehen.>> Damit steht fest dass du nichts von dem verstanden hast was> ich gefragt habe.
Okay...
Einige "Wenns"
Wenn Du den Quarz richtig zappeln lässt - also den richtigen Quarz
und die richtigen Kondensatoren verwendest.
Wenn Du die Fuses (Quarztyp) richtig eingestellt hast.
Auch der DIV8 sollte stimmen!
Wenn Du die Teilerfaktoren passend zum Quarz richtig eingestellt hast.
Wenn die zur seriellen Schnittstelle gehörigen Register richtig
initialisiert wurden. Das ist ein ganzer Haufen.
Es kann natürlich nicht schaden, wenn der Quarz nach dem 3-ten Mal
herunterfallen auf die Fliesen noch lebt und der Prozessor den
Überschlag beim letzten Anfassen überlebt hat.
Eins ist nämlich sicher: Hätte der Chip einen internen Fehler, so hätte
sich das längst herumgesprochen. Ist nämlich schon etliche Jahre auf dem
Markt.
Wenn ich so ein Problem habe (lange nicht mehr passiert), dann lasse ich
im Sekundentakt einen Piezo piepsen und hole mir eine Uhr mit
Sekundenzeiger auf den Bildschirm. Wenn synchron, dann gut.
https://www.uhrzeit.org/atomuhr.php
Max B. schrieb:> So, danke... ich hab's!>> Aus:>> #define baudrate 9600>> mach:>> #define baudrate 9600UL>> und jetzt läuft es mit gleicher Baudrate und auch mit TeraTerm.> Kann mir einer sagen warum?
Das UL ist hier nicht erforderlich, da die Makros UART_BAUD_SELECT und
UART_BAUD_SELECT_DOUBLE_SPEED bereits dafür sorgen, dass die Berechnung
der Baudrate in long erfolgt.
Vermutlich hat aber erst diese Änderung bewirkt, dass das Programm neu
kompiliert wurde. Die Änderung von F_CPU im Makefile führt nur dann zur
Neukompilierung, wenn nicht nur die C-Quelldateien, sondern auch das
Makefile selbst in den Make-Regeln berücksichtigt wird.
Mach im Zweifelsfall einfach
1
make clean
2
make
(wenn dein Makefile ein clean-Target hat) oder lösche alle kompilierten
Dateien, um eine vollständige Neukompilierung zu erzwingen.
Noch etwas:
1
UBRRH=((unsignedchar)(baudrate>>8))&0x80;
2
...
3
UBRR0H=((unsignedchar)(baudrate>>8))&0x80;
4
...
5
UBRRHI=((unsignedchar)(baudrate>>8))&0x80;
Das ist ein Bug. Da müsste statt 0x80 jeweils ~0x80 oder besser 0x0f
stehen. Da der Fehler nur bei niedrigen Baudraten in Erscheinung tritt,
ist wohl noch kaum jemand darüber gestolpert.
Das von Stefan vorgeschlagene setbaud.h aus der AVR-Libc funktioniert
auch mit niedrigen Baudraten. Zudem wird dort eine Warnung ausgegeben,
wenn eine bestimmte Baudrate nicht oder nur mit unzureichender
Genauigkeit umgesetzt werden kann.
Edit:
Ich sehe gerade, dass der o.g. Bug auch schon anderen aufgefallen ist:
Beitrag "Fehler in uart-lib von Peter Fleury?"
Yalu X. schrieb:> Das ist ein Bug. Da müsste statt 0x80 jeweils ~0x80 oder besser 0x0f> stehen.
Sehr guter Hinweis! Müsste es aber dann nicht "besser 0x7f" heißen?
Okay, es könnte sein, dass die 3 Bits im oberen Nibble keine Bewandnis
haben, da müsste ich das Datenblatt mal heranziehen...
Yalu X. schrieb:> Das UL ist hier nicht erforderlich, da die Makros UART_BAUD_SELECT und> UART_BAUD_SELECT_DOUBLE_SPEED bereits dafür sorgen, dass die Berechnung> der Baudrate in long erfolgt.
Da bin ich aber erleichtert. Ich habe nämlich gestern eine halbe Stunde
darüber gegrübelt und konnte mir nicht erklären, warum das "UL" nötig
sein sollte.
Ja ich hatte gestern noch testweise eine andere UART Init im Programm.
Deswegen habe ich mir die von Peter nicht mehr angeguckt.
Es läuft aber jetzt. Habe auch den Bug behoben in der Init. Läuft jetzt
einwandfrei!
Danke nochmal an Alle!
Frank M. schrieb:> Okay, es könnte sein, dass die 3 Bits im oberen Nibble keine Bewandnis> haben, da müsste ich das Datenblatt mal heranziehen...
Diese Bits sind "reserved" und sollten nur mit 0 beschrieben werden.
Yalu X. schrieb:> Frank M. schrieb:> Okay, es könnte sein, dass die 3 Bits im oberen Nibble keine Bewandnis> haben, da müsste ich das Datenblatt mal heranziehen...>> Diese Bits sind "reserved" und sollten nur mit 0 beschrieben werden.
Okay, dann wäre ~0x80 sogar falsch. Danke fürs Nachschauen :-)