Forum: Mikrocontroller und Digitale Elektronik ATXMEGA16E5, Uart will einfach nicht


von Alexander H. (ill_son)


Lesenswert?

Hallo,

ich bin gerade dabei eine Hardware mit ATXMEGA16E5 in Betrieb zu nehmen 
und verzweifele mittler Weile an der UART. Vielleicht weiß jemand Rat. 
Habe es inzwischen auf ein Minimum an Code reduziert -> will nicht.

Folgendes Minimalbeispiel bekomme ich nicht zum laufen (nur irgend etwas 
senden):

int main( void )
{

  //32MHz
  OSC.CTRL = OSC_RC32MEN_bm | OSC_RC32KEN_bm;
  while(!((OSC.STATUS & OSC_RC32MRDY_bm) && (OSC.STATUS &
  OSC_RC32KRDY_bm)));
  CCP = CCP_IOREG_gc;
  CLK.CTRL =CLK_SCLKSEL_RC32M_gc;
  DFLLRC32M_CTRL = DFLL_ENABLE_bm;
  OSC.PLLCTRL = OSC_PLLSRC1_bm | OSC_PLLFAC2_bm;

  //Uart
  PORTD.DIRSET = PIN3_bm;

  USARTD0.BAUDCTRLA = (uint8_t)1049;
  USARTD0.BAUDCTRLB = ((1049 >> 8) & 0b00001111) | 0b10100000;

  USARTD0.CTRLB |= USART_TXEN_bm | USART_RXEN_bm;
  USARTD0.CTRLC |= USART_CHSIZE_8BIT_gc;

  while(1)
  {
    _delay_ms(500);
    USARTD0.DATA = 0x55;
  }
}

Mit dem Oszi sehe ich nichts, Pin ist verbunden (Togglen geht).

Grüße, Alex

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

I/O Prescaler vergessen?
1
  /* Enable prescaler B div 1 and C to div by 2 */
2
  CCP = CCP_IOREG_gc;
3
  CLK.PSCTRL = (CLK_PSADIV_1_gc | CLK_PSBCDIV_1_2_gc);

Mit einer wie im o.a. Beispiel benutzten Teilerrate von 2 sieht die UART 
dann noch 16Mhz.

Dein Baudratenwert kommt mir auch viel zu hoch vor. Für 19200 Baud habe 
ich hier 51 stehen.

: Bearbeitet durch User
von Alexander H. (ill_son)


Lesenswert?

Hallo Mattias,

danke für deine Antwort.

An den Werten für die Baudrate-Register würde ich jetzt mal nicht 
zweifeln. Zum einen, weil ich sie mit Hilfe verschiedener Online-Qellen 
so ermittelt habe, eine wäre diese:

http://www.avrcalc.elektronik-projekt.de/xmega/baud_rate_calculator

Zum anderren, weil genau diese Uart-Initialisierung bei einem anderen 
Projekt mit einem ATXMEGA128A1 läuft. Baudrate ist hier 115000.

Grüße, Alex

von Timmo H. (masterfx)


Lesenswert?

Was ist mit
>  USARTD0.BAUDCTRLA = 131; //115200 Baud @ 32 MHz
>  USARTD0.BAUDCTRLB = 0xD0; //-4

: Bearbeitet durch User
von Alexander H. (ill_son)


Lesenswert?

Laut dem Link oben wäre es 131 und -3. Das würde genauso gehen wie die 
von mir verwendeten 1047 und -6. Wobei bei der zweiten Kombination der 
Fehler geringer ist. Mein Problem ist abe nicht die falsche Baudrate, 
sondern dass am Tx-Pin gar nichts passiert. Das liegt auf H-Pegel und 
rührt sich nicht.

Grüße, Alex

von Hannes (Gast)


Lesenswert?

Kein Wunder. Startbefehl nicht gegeben. Kannst im Dateregister 
rumschreiben wie du willst. Woher soll der xmega wissen, dass du 
"fertig" bist?

von Alexander H. (ill_son)


Lesenswert?

Hallo Hannes,

kannst Du das mal bitte konkretisieren? Meines Erachtens nach legt doch 
die Uart los mit senden, wenn ich das Datenregister beschrieben habe. Wo 
soll ich da was starten? Das ist mir neu.

Grüße, Alex

von Hannes (Gast)


Lesenswert?

Wenn dem nicht so wäre, wie soll er denn dann eine 0x00 senden? Er weiss 
ja nicht, ob die 0x00, die jetzt drin steht heisst, dass nichts zu 
senden da ist, oder ob es ein valider Datenwert ist.

Ist DREIF gesetzt? Kann ich in deinem Code nicht finden.
Siehe AU-Handbuch §23.6.1

von Hannes (Gast)


Lesenswert?

Sorry, war falsch. DREIF ist nur lesbar. Und wenn du nicht gerade ein 
REMAP gemacht hast und der Pin auf D7 ist, weiss ich leider auch nicht 
weiter.

von Hannes (Gast)


Lesenswert?

Im richtigen E-Handbuch habe ich auch nichts weiter dazu gefunden. Es 
müsste also eigentlich gehen.

von Moby A. (moby-project) Benutzerseite


Lesenswert?

Hannes schrieb:
> Ist DREIF gesetzt?

Genau. Das ist der springende Punkt, siehe E-Manual S. 296:

"The transmit buffer can only be written if the DREIF Flag in the STATUS 
Register is set "

DREIF wird mit dem Schreiben neuer Daten in DATA aber resettet.

Eine Besonderheit hat der E5 noch beim ReceiveComplete-Interrupt:
RXCIF wird hier mit der Interrupt-Ausführung nicht automatisch 
zurückgesetzt, das muß manuell erfolgen!

von Hannes (Gast)


Lesenswert?

Hmm komisch. Vorhin stand da noch ein "R" unter DREIF. Da bin ich wohl 
beim rumgucken irgendwann mal mit den Augen verrutscht. Na dann stimmt 
doch die erste Aussage.

von Hannes (Gast)


Lesenswert?

AAAH beim AU steht ein R unter DREIF. Die Dinger sind aber auch echt 
eigenwillig.

von Alexander H. (ill_son)


Lesenswert?

Hallo,

erstmal vielen Dank an euch für die Tipps. Wenn ich das richtig 
verstehe, muss ich also vor erstmaligem Beschreiben des DATA-Registers 
im STATUS-Register das DREIF-Flag setzten? Da steht aber auch, dass das 
Bit nach einem Reset (des Controllers?) auf 1 steht, man also senden 
kann. Beim Schreiben wird es 0 und wenn die Daten draußen sind wieder 1. 
Bei anderen Besielen zur UART hab ich auch nie gesehn, dass da einer 
vorher manuell das DREIF-Bit setzt. Aber ich kann's ja mal ausprobieren 
am Montag.

Grüße, Alex

von Halodri (Gast)


Lesenswert?

Was wird hier für ein Quatsch verzapft - Jey.
Ein INTERRUPTFLAG zum senden setzen? Was ist das für Logik?
U.a. beim Xmega setzt man Interrupt-Flags mit dem Beschreiben einer "1" 
ZURÜCK! Wenigstens das sollte bekannt sein.
Mit einer "1" setzen geht also prinzipiell nicht.

Leider weis ich auch nicht wo's bei dir hängt - jedefalls nicht am IF.

Tipp: Checke mit dem Debugger-IO-View nochmal Alles von Takterzeugung
bis natürlich sämtliche Register der USART - hier wird es in Klartext 
angezeigt.
Beobachte, ob "TXCIF" einige Zeit nach dem Beschreiben des 
Data-Registers gesetzt wird.

von Halodri (Gast)


Lesenswert?

Nachtrag:
Zwar warscheinlich auch nicht der Fehler, aber..

>>   USARTD0.CTRLB |= USART_TXEN_bm | USART_RXEN_bm;
>>  USARTD0.CTRLC |= USART_CHSIZE_8BIT_gc;

ist unnötig gefährlich, da die Register nur mit dem bestehenden Inhalt 
verodert werden. Richtig ist Zuweisung

Noch ´ne blöde Frage: Wieso machst du mit der PLL ´rum

>> OSC.PLLCTRL = OSC_PLLSRC1_bm | OSC_PLLFAC2_bm;

wenn du schon den RC32MHz-Oszillator an hast? 32MHz ist die höchste 
Frequenz. Entweder PLL ODER RC32M...
Die Prescaler stehen nach dem Reset auf 1 : 1 : 1 - siehe Debugger.

von Alexander H. (ill_son)


Lesenswert?

Ich wollte nur fix sagen, dass es läuft. Ich habe, statt alles 
auszukommentieren, nun ein ganz neues rudimentäres Projekt aufgesetzt, 
nun klappt's.


Danke nochmal & Grüße,

Alex

: Bearbeitet durch User
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.