Forum: Mikrocontroller und Digitale Elektronik UBRR-Registerinhalt für UART über Formel berechnen!


von matthias (Gast)


Lesenswert?

Guten Tag alle zusammen,

ich sitze hier gerade bei der Inbetriebnahme eines Atmega644P. Nun 
wollte ich die UART0-Schnittstelle in Betrieb nehmen. Anfangs habe ich 
einen fixen Wert (0x33) in das UBRR0-Register geschrieben, um bei 8MHz 
CPU-Clock eine Baudrate von 9,6k zu bekommen. Damit funktionierte die 
Schnittstelle wunderbar. Nun wollte ich den Registerinhalt wie üblich 
über gewisse define-Werte (F_CPU, BAUD) abhängigmachen. Aber dabei wird 
mir irgentein falscher Wert in das Register geschrieben und es kommen 
nur noch komische Zeichen am Rechner an.

Ich hab die optimierte Formel genommen, bei der der Wert gleich gerundet 
wird.

Tippe ich die Formel selbst mit dem Taschenrechner durch, komme ich 
wieder auf 0x33.

Danke für eure Hilfe
Matthias

von Stefan E. (sternst)


Lesenswert?

Und jetzt möchtest du, dass wir dir sagen, was bei deinen Defines schief 
läuft, ohne sie jemals zu Gesicht bekommen zu haben?

von matthias (Gast)


Lesenswert?

Hast ja recht ;-)


Hier die Definitionen in der Header:
1
#ifndef F_CPU
2
#define F_CPU 8000000
3
#endif
4
5
#define BAUD_UART0 9600
6
#define UBRR0_VAL  ((F_CPU + BAUD_UART0 * 8) / (BAUD_UART0 * 16)-1)

Die Initialisierungsfunktion sieht wie folgt aus:
1
void uart0_init()
2
{
3
 UBRR0 = UBRR0_VAL;                           //0x33
4
 UCSR0B = (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0);
5
 UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
6
}

Hinter der UBRR0-Zeile hab ich den auskommentierten Fixwert für das 
Register stehen. Mit dem funktionierts wunderbar.

Danke

von Stefan E. (sternst)


Lesenswert?

1
#define BAUD_UART0 9600
ändere das in
1
#define BAUD_UART0 9600UL

von matthias (Gast)


Lesenswert?

Vielen Dank,
so funktionierts. Könntest du mir vielleicht auch in 1 oder 2 Sätzen 
sagen, was das "UL" bewirkt?

Dankende Grüsse
Matthias

von Hc Z. (mizch)


Lesenswert?

matthias schrieb:
> #define BAUD_UART0 9600
> ...
> #define UBRR0_VAL  ((F_CPU + BAUD_UART0 * 8) / (BAUD_UART0 * 16)-1)

Fällt Dir beim manuellen Nachrechnen am Zwischenwert „BAUD_UART * 8“ was 
auf?  Nein?  Sollte aber.  Du hast 2 Integer hingeschrieben.  Somit wird 
16 Bit signed gerechnet.  Das überschreitet den Wert einer Integer aber 
bei Weitem.

Mach aus den 8 8UL und dito mit den 16.

Edit:  zulange für die Antwort gebraucht.

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.