Forum: Mikrocontroller und Digitale Elektronik Fleury UART 1200 Baud


von Hans (Gast)


Lesenswert?

Ich habe einen ATmega8535l. Dieser wird mit 5 Volt versorgt und soll 
eine serielle Kommunikation bei 1200 Baud durchführen. Ich habe dazu die 
Library von Peter Fleury verwendet 
(http://homepage.hispeed.ch/peterfleury/doxygen/avr-gcc-libraries/group__pfleury__uart.html).
Nun funktioniert die Kommunikation auch in beiden Richtungen mit 9600 
Baud oder 2400 Baud. Kaum schalte ich jedoch auf 1200 Baud, kann ich 
keine Daten mehr senden oder empfangen. Mein Programm funktioniert also. 
Der Fehler muss irgendwo in der UART Initialisierung liegen. Hat jemand 
Erfahrung mit der Fleury Lib bei 1200 Baud?
1
#define F_CPU 8000000UL
2
#define UART_BAUD_RATE      9600
3
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));

von Hans (Gast)


Lesenswert?

Die Baudrate wird natürlich so definiert:
1
#define UART_BAUD_RATE      1200

von Christian S. (christian_s593)


Lesenswert?

probier mal:

#define F_CPU 8000000UL
#define UART_BAUD_RATE      1200
uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE,F_CPU));

von Hans (Gast)


Lesenswert?

Christian S. schrieb:
> uart_init( UART_BAUD_SELECT_DOUBLE_SPEED(UART_BAUD_RATE,F_CPU));

Das funktioniert leider auch nicht.

von Christian S. (christian_s593)


Lesenswert?

Hmm, also um das Problem auf dem Grund zu gehen, muss man erstmal sehen, 
ob der AVR nicht richtig sendet oder ob er nicht richtig verstanden 
wird. Anzahl Daten-bits, Stopp-bits und Handshake stimmen überein? Hast 
du ein USB-Seriell Wandler, mit dem du auf 1200baud kommunizieren 
kannst? Eventuell ein Oszilloskop zum vergleichen?

von Hans (Gast)


Lesenswert?

Christian S. schrieb:
> Hmm, also um das Problem auf dem Grund zu gehen, muss man erstmal sehen,
> ob der AVR nicht richtig sendet oder ob er nicht richtig verstanden
> wird. Anzahl Daten-bits, Stopp-bits und Handshake stimmen überein? Hast
> du ein USB-Seriell Wandler, mit dem du auf 1200baud kommunizieren
> kannst? Eventuell ein Oszilloskop zum vergleichen?

Das einzige, was ich verändert habe ist die Baudrate. Alle anderen 
Parameter sind gegenüber dem Test mit 9600 Baud auf beiden Seiten 
identisch geblieben. Ich habe jetzt auch zwei Rechner miteinander 
verbunden und sie miteinander bei 1200 Baud kommunizieren lassen. Das 
Problem muss damit beim AVR liegen. Bei beiden Rechnern ist eine 
Hardware Schnittstelle verbaut.
Ein Oszilloskop habe ich, allerdings ein analoges. Da stelle ich mir das 
Messen der seriellen Schnittstelle recht schwierig vor. Ich habe 
allerdings einen Logic Analyer (Saleae Klon).
Der integrierte Decoder spuckt einige framing error aus und eine Menge 
falscher Zeichen.

Ich habe auch mal versucht die Baudrate daraus zu ermitteln. Laut 
https://www.kumari.net/index.php/random/37-determing-unknown-baud-rate 
habe ich die Länge des kürzesten Pulses gesucht. Diese beträgt 65µS, 
womit ich eine Baudrate von 15384 Baud hätte. Diese in den Decoder 
eingeben gibt das richtige Wort "Booted" aus.

von S. Landolt (Gast)


Lesenswert?

Kommen die 1200 Bd mit
1
#define F_CPU 16000000UL
2
#define UART_BAUD_RATE      2400
?

von Christian S. (christian_s593)


Lesenswert?

Versuch mal bitte in der Laufzeit nach der Initialisierung die Werte 
von:
UBRRL = ?
UBRRH = ?

rauszubekommen.

Bei 1200 Baud müsste es:
UBRRL = 0xA0;
UBRRH = 0x01;

Oder eben bei deinem ermittelten 15384 Baud:
UBRRL = 0x20;
UBRRH = 0x00;

sein.

Eventuell mal Quick&Dirty nach der Initialisierung
UBRRH und UBRRL entsprechend setzen.
Dann wäre es schon mal sehr eingegrenzt, wenn es dann funktioniert.

: Bearbeitet durch User
von Hans (Gast)


Lesenswert?

S. Landolt schrieb:
> 2400

Dann kommen auch 2400. Das Problem beginnt erst bei 1200, geht dann aber 
auch bei 600 Baud weiter.

Christian S. schrieb:
> Bei 1200 Baud müsste es:
> UBRRL = 0xA0;
> UBRRH = 0x01;

Das wäre jetzt auch mein Ansatz gewesen. Danke für die Berechnung. Die 
Registereinträge manuell zu setzen funktioniert. Somit ist mein Problem 
schonmal gelöst. Fehlt noch die Ursachenforschung.

Mit
1
unsigned char low = UBRRL;
2
unsigned char high = UBRRH;
habe ich die Werte aus den Registern gesichert und nach dem manuellen 
Setzen von UBRRL und UBRRH über den UART ausgegeben.
1
low = 0xA0
2
high = 0x00

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Hans schrieb:
> Ein Oszilloskop habe ich, allerdings ein analoges.

Triggere es auf die fallende Flanke (Startbit) und stelle etwa 1ms/DIV 
auf der Zeitbasis ein. Ein Bit sollte dann etwas unter einer Teilung 
lang sein, genau 0,833ms, dann hast du die richtige Baudrate.

von Codeleser (Gast)


Lesenswert?

mal im Code nachschauen?

Früher stand mal in uart_init:

    #if defined(UART0_UBRRH)
    UART0_UBRRH = (unsigned char)((baudrate>>8)&0x80) ;
    #endif
    UART0_UBRRL = (unsigned char) (baudrate&0x00FF);

 baudrate ist der Parameter von uart_init, also hier die 0x1a0

 Da wundert mich nicht wirklich, dass die 1 weg ist.

von S. Landolt (Gast)


Lesenswert?

S. Landolt schrieb:
> Kommen die 1200 Bd mit#define F_CPU 16000000UL
> #define UART_BAUD_RATE      2400
> ?

Hans schrieb:
> Dann kommen auch 2400.

Tatsächlich? Das hatte ich nicht erwartet.

von Hans (Gast)


Lesenswert?

Codeleser schrieb:
> Da wundert mich nicht wirklich, dass die 1 weg ist.

Jetzt wäre es nur noch wichtig zu wissen, was ich machen kann, damit die 
1 wieder da ist. Vielleicht könnte man dann Peter Fleury auch einen Fix 
zukommen lassen.

S. Landolt schrieb:
> Tatsächlich? Das hatte ich nicht erwartet.

Ganz sicher. Ich hatte es nach deiner Nachfrage extra nochmal überprüft. 
Im Eingangsposting habe ich es ja auch schon geschrieben.

Ich will mich hier auch mal bei allen Postern bedanken. So viel 
konstruktive Hilfe sieht man hier im Forum leider selten.

von S. Landolt (Gast)


Lesenswert?

> Ganz sicher.
Mit
#define F_CPU 16000000UL  ?
Wie gesagt, hätte ich nicht erwartet. Woher bezieht diese "Fleury-Lib" 
die Systemtaktangabe?

von Christian S. (christian_s593)


Lesenswert?

Haben wir da tatsächlich ein Fehler in einer viel genutzten 
UART-Libraries gefunden? Wie kann es sein das der Fehler über 10 Jahre 
unentdeckt war. Kann ich mir fast nicht vorstellen.
1
 UART0_UBRRH = (unsigned char)((baudrate>>8)&0x80) ;

muss natürlich in:
1
 UART0_UBRRH = (unsigned char)((baudrate>>8)&(~0x80)) ;

geändert werden. Das 16te Bit in "baudrate" ist als Flag genutzt, um 
festzustellen, ob Double Rate aktiviert ist. Bei der Übertragung in das 
upper byte muss dieses Flag wieder gelöscht werden, jedoch wurde alles 
andere gelöscht.
Kann mir nur so erklären dass es nie auffiel, da nur langsame und selten 
genutzte Baudraten das upper byte benutzen.

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.