Forum: Mikrocontroller und Digitale Elektronik Baudraten-Diskrepanz zwischen PC und uC


von Christoph R. (chris232)


Lesenswert?

Hallo,
ich habe ein Problem mit der Zeichen-Übertragung via UART von uC zum PC.
Wenn ich eine Baudrate von z.B. 4800 im Controller einstelle, muss ich 
im Terminalprogramm des PCs 600 einstellen, damit er die Zeichen 
empfängt. Ich habe einen externen 16Mhz Quarz und das UBBR auch richtig 
berechnet. Der Quarz ist i.O. Der Baudraten-Fehler liegt in der 
Toleranz.

Die Funktion zum Senden eines Zeichens ist die wohl bekannte aus 
RN-wissen.de

//---------------------------------------------------------------------- 
-

#define BAUDRATE 4800UL
#define F_CPU 16000000

void uart_init()
{
 uint16_t ubrr = (uint16_t) ((uint32_t) (F_CPU+BAUDRATE*8)/(16*BAUDRATE) 
- 1);

UBRRH = (uint8_t) (ubrr>>8);
UBRRL = (uint8_t) (ubrr);

...

}
//---------------------------------------------------------------------- 
-


static inline int
uart_putc (const uint8_t c)
{
    // Warten, bis UDR bereit ist für einen neuen Wert
    while (!(UCSRA & (1 << UDRE)))
        ;

    // UDR Schreiben startet die Übertragung
    UDR = c;

    return 1;
}
//---------------------------------------------------------------------- 
-

Hat jemand eine Vermutung?

Gruß,
Christoph

von Karl H. (kbuchegg)


Lesenswert?

Christoph R. schrieb:

> Wenn ich eine Baudrate von z.B. 4800 im Controller einstelle, muss ich
> im Terminalprogramm des PCs 600 einstellen,

Das ist ein Faktor 8

> Hat jemand eine Vermutung?

Du hast die CLKDIV8 Fuse nicht deaktiviert.
Dein µC läuft nicht mit 16Mhz sondern mit 2Mhz

von Falk B. (falk)


Lesenswert?


von Christoph R. (chris232)


Lesenswert?

Der Faktor 8 hat mich auch stutzig gemacht. Der Quarz ist richtig 
eingestellt, da ich mit einem Timer-Overflowinterrupt einen Ausgang 
getoggelt habe und die Änderung über ein Oszilloskop gemessen habe.

Wenn ich nun PC-seitig 1200 einstelle und im Controller 9600, klappt es 
wiederum nicht.

Ich benutze ACV Studio und der SUT_CKSEL ist auf Extern und High 
Frequenz gestellt - daher habe ich keine Möglichkeit CKDIV8-Fuse 
einzustellen, oder?

Die Kondensatoren des Max232 sind laut AVR-GCC Tutorial noch in der 
Toleranz.

von Karl H. (kbuchegg)


Lesenswert?

Christoph R. schrieb:

> Ich benutze ACV Studio und der SUT_CKSEL ist auf Extern und High
> Frequenz gestellt - daher habe ich keine Möglichkeit CKDIV8-Fuse
> einzustellen, oder?

Welcher Prozessor?


Hast du eine LED an einem Ausgang?
In
http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART
ist ein Testprogramm angegeben. Probiers mal aus.

von Christoph R. (chris232)


Lesenswert?

Habe einen Atmega8..

Subjektiv blinkt die LED mit 1Hz - Aber ich hatte ja schon im 
Millisekundenbereich einen Ausgang getoggelt --> 8bit Timer mit 1024 
PreScaler und alle 16,4ms Overflow: ging.

Trotzdem schonmal Danke für die Tipps!

von Christoph R. (chris232)


Lesenswert?

Es lag an folgender Einstellung:

UCSRC = (1 << UCSZ1) | (1 << UCSZ0);

Nachdem ich diese Funktion rausgenommen habe, lief die Übertragung.
Weiß jemand was diese Einstellung aussagt? Ich verstehe die Beschreibung 
im Tutorial nicht:

Diese Bits setzten in Verbindung mit UCSZ2 aus dem UCSRB Register die 
Anzahl der Datenbits eines Frames. Diese Bits setzten den entsprechenden 
Paritätsmodus.

von Karl H. (kbuchegg)


Lesenswert?

Christoph R. schrieb:
> Es lag an folgender Einstellung:
>
> UCSRC = (1 << UCSZ1) | (1 << UCSZ0);
>
> Nachdem ich diese Funktion rausgenommen habe, lief die Übertragung.


Schau mal im Datenblatt deines Prozessors nach, ob es im Register UCSRC 
ein Bit namens URSEL gibt.

Wenn es eines gibt, dann zieh dir selbst die Ohren lang, dass du die 
Beschreibung bzw. das Tutorial nicht aufmerksam genug gelesen hast. Denn 
dann hast du nicht das UCSRC Register manipuliert sondern UBRRH

PS: Der Mega8 hat besagtes URSEL Bit.

Und es unterstreicht wieder einmal das, was hier jeden Tag zig mal 
gepredigt wird: Poste kompletten Code!
Oft genug steckt das Problem nicht in den geposteten Teilen. Wenn es 
dort wäre, würdest du es wahrscheinlich selber sehen. Da du es aber 
nicht gesehen hast, sind die Chancen gar nicht so schlecht, dass du an 
der falschen Stelle suchst.

von spess53 (Gast)


Lesenswert?

Hi

>Nachdem ich diese Funktion rausgenommen habe, lief die Übertragung.

?????????

>Weiß jemand was diese Einstellung aussagt?

Ja. Das Datenblatt.

Wenn die Bits beide 0 sind läuft die UART mit 5 Datenbits. Und richtig 
laufen kann es damit auch nur, wenn das PC-Programm auch auf 5 Datenbits 
eingestellt ist.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Nachdem ich diese Funktion rausgenommen habe, lief die Übertragung.
>
> ?????????
>
>>Weiß jemand was diese Einstellung aussagt?
>
> Ja. Das Datenblatt.
>
> Wenn die Bits beide 0 sind läuft die UART mit 5 Datenbits. Und richtig
> laufen kann es damit auch nur, wenn das PC-Programm auch auf 5 Datenbits
> eingestellt ist.

8N1 ist der Default solange er an USCRC nicht dreht.
Aber: Solange er beim setzen das URSEL Bit weglässt, überschreibt er 
sich UBRRH und nicht UCSRA

von Christoph R. (chris232)


Lesenswert?

Bekenne mich schuldig, danke. Werde es das nächste mal beherzigen.

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.