mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART BSEL berechnen[ATxmega]


Autor: jojo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
void InitDebug(uint32_t FPER)
{
PORTE.DIRSET = PIN3_bm;
PORTE.DIRCLR = PIN2_bm;

USARTE0.CTRLC = (USART_CHSIZE_8BIT_gc | USART_PMODE_DISABLED_gc);

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

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

USARTE0.CTRLB |= USART_RXEN_bm;
USARTE0.CTRLB |= USART_TXEN_bm;
}

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.

Autor: Hans-jürgen Herbert (hjherbert) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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__...

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.

Autor: jojo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.