UART BSEL berechnen[ATxmega]

Gast #1604688
Guten Tag,

seit einigen Tagen beschäftige ich mich mit den ATxmegas. Habe ein 
bisschen mit dem UART herumgspielt und jetzt versucht ein Header File zu 
schreiben, dass ich immer als Debug-Ausgabe einsetzen kann.

Allerdings habe ich noch ein Problem bei der Initialisierung des BSEL 
Wertes. Ich benutze die interne Baudratenerzeugung, wobei der Bscale 
Wert auf 0 steht:
1
void InitDebug(uint32_t FPER)
2
{
3
PORTE.DIRSET = PIN3_bm;
4
PORTE.DIRCLR = PIN2_bm;
5

6
USARTE0.CTRLC = (USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc);
7

8
uint16_t BSELT;
9
BSELT = round(((FPER/(16*9600))-1));
10

11
USARTE0.BAUDCTRLA = BSELT;                                           
12
USARTE0.BAUDCTRLB =(0 << USART_BSCALE0_bp)|(BSELT >> 8);
13

14
USARTE0.CTRLB |= USART_RXEN_bm;
15
USARTE0.CTRLB |= USART_TXEN_bm;
16
}

Das Problem tritt bei der Berechnung des Wertes auf. FPER übergebe ich 
als 2.000.000, als Ergebnis müsste 12 herauskommen. Leider ist es so, 
dass wenn die Berechnung ablaufen müsste, im Debugger immer die 2 
nachfolgenden Anweisungen übersprungen werden. Wenn ich BSELT gleich 12 
setze, erhalte ich das korrekte Ergebnis (es funktioniert dann auch mit 
der Hardware).

Viele Grüße und vielen Dank im Vorraus,

jojo

PS: Ich weiß, dass es nicht sonderlich sinnvoll ist, das ganze ohne 
Fehlerbetrachtung zu machen, jedoch hält sich der prozentuale Fehler bei 
9600Baud im Allgemeinen (ganz krumme Werte habe ich jetzt noch nicht 
getestet) im Rahmen.
Persönliche Seite #1605390
Hier stört die funktion "round()", die es in der Library gibt, aber im 
Compiler möglicherweise nicht eingebaut ist. Diese Funktion will double 
und gibt double zurück.

Siehe: http://www.nongnu.org/avr-libc/user-manual/group__avr__math.html

Oder Google:"round libc"


Sieh zu, dass du eine Formel "erfindest", die nur Integer braucht. Für 
meinen ATMega8 / ATMega32 habe ich

#define UBRRinitval (((F_CPU+8L*BAUD)/(16L*BAUD))-1L)

Also
anstatt : round(((FPER/(16*9600))-1))
besser : (FPER+(16*9600)/2)/(16*9600))-1

Dabei wird dadurch gerundet, dass zum Zähler der halbe Nenner 
hinzuaddiert wird.
Gast #1606884
Hallo,

vielen Dank für die Antwort. Das mit dem round() war ein guter 
Hinweis...da wäre ich so schnell nicht draufgekommen.
Im Endeffekt funktioniert die Berechnung auch nur über ein Define, was 
mich letztendlich aber nicht stört, ist so viel ordentlicher^^

Viele Grüße

jojo

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.