ATXMEGA16E5, Uart will einfach nicht

OP #4446509
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
(Firma: matzetronics) #4446671
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.
OP #4446919
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
OP #4446954
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
Gast #4447641
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
Persönliche Seite #4447668
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!
OP #4448109
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
Gast #4448184
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.
Gast #4448205
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren