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
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
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
Was ist mit > USARTD0.BAUDCTRLA = 131; //115200 Baud @ 32 MHz > USARTD0.BAUDCTRLB = 0xD0; //-4
:
Bearbeitet durch User
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
Kein Wunder. Startbefehl nicht gegeben. Kannst im Dateregister rumschreiben wie du willst. Woher soll der xmega wissen, dass du "fertig" bist?
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
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
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.
Im richtigen E-Handbuch habe ich auch nichts weiter dazu gefunden. Es müsste also eigentlich gehen.
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!
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.
AAAH beim AU steht ein R unter DREIF. Die Dinger sind aber auch echt eigenwillig.
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
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.