Guten Abend, ich bin ein wenig am verzweifeln. Will als erstes mit meinem neuen xmega-Board USART zum laufen bringen. Der USB-USART-Wandler ist auf dem Board mit PF2(RX) und PF3(TX) verbunden. Aber es funktioniert einfach nicht. Hier der code: int main(void) { OSC.CTRL = 0b00000010; // oszillator auf 32Mhz einstellen while((OSC.STATUS & 0b000000010) == 0b00000000) // warten bis der oszillator stabil ist { } CCP = 0b11011000; // CLK.CTRL = 0b00000001; // clock auf 32Mhz einstellen PORTF.OUT = 0b00001000; PORTF.DIR = 0b00001000; // TX-port aus ausgang USARTF0.BAUDCTRLB = 0b00000000; // baudraten-skalierungsfaktor: keinen, also 0 USARTF0.BAUDCTRLA = USART_VAL; // baudrateneinstellung nach #defines oben USARTF0.CTRLA = 0b00000000; // keine interrupts aktivieren, keine extras USARTF0.CTRLC = 0b01000011; // synchroner USART, parity: keine, stop-bits: 1, character-size: 8bit USARTF0.CTRLB = 0b00011000; // sender und empfaenger aktivieren, sonst nichts while(1) { while ((USARTF0.STATUS & 0b00100000) == 0b00000000) { } USARTF0.DATA = 'c'; } return(0); } Danke im vorraus
Achja noch die Berechnungen: #define F_CPU 32000000 #define USART_BAUD 115200 // baudrate fuer usart #define USART_VAL ((F_CPU/(2*USART_BAUD))-1) // register-wert berechnen mit baudrate und CPU-frequenz
Ja, aber wenn der Wert schon in in ein Register passt (8bit), braucht man das andere nicht.
Ich würde mir ja die Mühe machen, den Source anzusehen. Allein mir fällt der Vergleich mit meinem Referenz-Source arg schwer, da ich dort nur die "offiziellen" Konstanten einsetze: Beispiel:
1 | USARTF0.CTRLC = |
2 | USART_CMODE_ASYNCHRONOUS_gc | |
3 | USART_CHSIZE_8BIT_gc | |
4 | USART_PMODE_DISABLED_gc; |
In Deinem Kommentar steht "synchron". Ist es das, was Du willst? Deinen Kommentaren wird der Compiler auch nicht trauen :-)
1) Synchron geht nicht. 2) Was geht konkret nicht? Wird z.B. ein Zeichen gesendet und es kommt "durcheinander" an?
Es kommt gar nichts. Ich bevorzuge ehrlichgesagt jetzt mehr die Bitschreibweise, einfach viel weniger Schreibarbeit, Registerbeschreibungen kann ich in den Kommentaren ja immer noch ergänzen.
OK, danke schonmal, synchron war auf jeden Fall das Falsche. Allerdings empfange ich jetzt nur Nullen statt den 'c's.
Fabian K. schrieb: > Es kommt gar nichts. Ich bevorzuge ehrlichgesagt jetzt mehr die > Bitschreibweise, einfach viel weniger Schreibarbeit, Bedeutet aber viel mehr Lesearbeit für den Rest der Welt > Registerbeschreibungen kann ich in den Kommentaren ja immer noch > ergänzen. Du bist nicht verzweifelt genug :-)
Das versteh ich natürlich. Einfach den Code vergessen. Was können mögliche Fehlerursachen für die Nullen sein? Baudratenberechnung? ((F_CPU/(16*USART_BAUD))-1) ist meine Berechnungsformel da mein Skalierungsfaktor 0 ist. Stimmt das? (Hab schon 1000mal alles kontrolliert, aber ich kann mich ja täuschen) Danke im vorraus
1) Liegt tatsächlich der gewünschte CPU Takt an (z.B. mit blinkender LED prüfen, wenn Led 1Hz blinken soll, macht sie das auch? ) 2) Empfängerseite richtig eingestellt? 3) Stimmt das Frameformat
> Einfach den Code vergessen. Der war gut ;-) > Was können > mögliche Fehlerursachen für die Nullen sein? Baudratenberechnung? > > ((F_CPU/(16*USART_BAUD))-1) ist meine Berechnungsformel da mein > Skalierungsfaktor 0 ist. Was ist ein Skalierungsfaktor? Zur Baudratenberechnung: Die sollte korrekt sein, ich verwende allerdings immer eine optimierte Formel, die findest Du hier im Tutorial. Weiterhin füge ich der F_CPU ein "ul" an, und an die 16 würde ich ein "l" anhängen. Kann aber gut sein, dass der Compiler das dennoch korrekt macht. Die Nullen können ein Indiz für einen "falschen" Takt sein. Entweder läuft der xmega nicht mit 32 MHz (mir ist Deine Initialsierung der Clock viel zu kurz, ich vermisse die Kalibierung) oder aber ist der Takt für die USART nicht gleich dem Takt der CPU. Ich setzte explizit "F_CPU" = "T_TIMER". Es kann z. B. sein, dass Dein USART mit F_CPU / 2 läuft.
Hallo nochmal, Empfängerseite ist sicher richtig eingestellt. Skalierungsfaktor ist zum skalieren der Baudrate, versteh ich auch nicht ganz, näheres steht im Datenblatt, brauch ich aber nicht. Ich vermute die Clock-Init funktioniert nicht richtig, da die delay-Funktion gar nicht funktioniert und den Programmcode stoppt. Hier nochmal der Codeausschnitt: OSC.CTRL = 0b00000010; // 7:reserved | 6:reserved | 5:reserved | 4:PLLEN | 3:XOSCEN | 2:RC32KEN | 1:RC32MEN | 0:RC2MEN while((OSC.STATUS & 0b000000010) == 0b00000000) // warten bis der oszillator stabil ist { } CCP = 0b11011000; // schutz CLK.CTRL = 0b00000001; // 7:reserved | 6:reserved | 5:reserved | 4:reserved | 3: reserved | 2:SCLKSEL2 | 1:SCLKSEL1 | 0:SCLKSEL0 DFLLRC32M.CTRL = DFLL_ENABLE_bm; // kalibrierung ? Kann vielleicht irgendwer einen funktionierenden Code für die Initialisierung des Clock posten? Danke im vorraus
Hallo Fabian, soweit sieht deine Initialisierung OK aus, richtige Bits werden gesetzt und abgefragt (allerdings ist es wirklich einfacher die neue Schreibweise zu benutzen). Eine Sache ist mir allerdings aufgefallen: Willst du den USART wirklich synchron benutzen? Wenn ja ist deine Formel richtig, andernfalls gelten die im Datenblatt obendrüber. Für asynchronen Modus bekäme ich das raus: BSEL: 2094 BSCALE: -7 Error: 0.010001 (ohne Garantie) Hast du mal den Fehler überprüft, den du mit der obigen Baudratenberechnung hast? Hier mal noch meine Clock-Init: /*Oscillator auf 32Mhz einstellen PIN1 = OSC_RC32MEN wird gesetzt */ OSC.CTRL |= OSC_RC32MEN_bm; /*Wenn Oscillator stabil wird das Flag RC32MRDY * gesetzt und 32Mhz können benutzt werden*/ while(!(OSC.STATUS & OSC_RC32MRDY_bm)); /*I/O Protection*/ CCP = CCP_IOREG_gc; /*Clock auf 32Mhz einstellen*/ CLK.CTRL |= CLK_SCLKSEL_RC32M_gc; Ist glaube ich auch zusammenkopiert, hat aber funktioniert. Viele Grüße Jojo
> CCP = 0b11011000; // schutz > CLK.CTRL = 0b00000001; // 7:reserved | 6:reserved | 5:reserved | > 4:reserved | 3: reserved | 2:SCLKSEL2 | 1:SCLKSEL1 | 0:SCLKSEL0 Clock source erst nach der Kalibierung > DFLLRC32M.CTRL = DFLL_ENABLE_bm; // kalibrierung ? Zu spät und unvollständig. Aber immerhin die erste Konstante. Geht doch :-) > Kann vielleicht irgendwer einen funktionierenden Code für die > Initialisierung des Clock posten? So und jetzt suchst Du nach "DFLLRC32M.CTRL = DFLL_ENABLE_bm" in diesem Forum. Dann findest Du einen Thread "xmega interner 32 MhZ Takt geht nicht". Dann nimmst Du den Code von Simon K. Mit den Konstanten. Und spätestens jetzt sollte ein Licht aufgehen, warum das mit den Konstanten sinnvoll ist.
Diesen Thread finde ich leider nicht. Diese Konstanten machen aber keinen Unterschied zu der Bitschreibweise, außer dass man ohne Kommentierung gleich erkennt was man setzt. Diese Group-Configurations sind schon was annderes, die machen einiges leichter.
So, jetzt bin ich aber endgültig am verzweifeln. Code, wie von Roland vorgeschlagen aus dem Thread kopiert. Dazu hab ich ein Soft-PWM mit der _delay-Funktion gemacht. Port wird auf High gesetzt und das Programm hängt in der _delay-Funktion. Ich will wieder Fuse-Bits /:
> Ich will wieder Fuse-Bits /:
Nun, dann wäre Dein xmega inzwischen ziemlich "verfused" ;-)
Zeig mal den ganzen neuen Code, meine Glaskugel ist gerade kaputt.
Ich hab inzwischen den ganzen code nochmal neu geschrieben, die entsprechenden Kapitel im Datenblatt durchgelesen, diesmal in der neuen Schreibweise ( Roland wird sich freuen (: ). Ich hab den c-Code angehängt.
Achja, code geht trotz allem immer noch nicht. Hoffe irgendwer findet was (:
Servus, Fabian K. schrieb: > Hoffe irgendwer findet sich was das wollen wir doch hoffen! Ich habe mal vor einiger Zeit eine Anwendung für deine Probleme geschrieben. Siehe: http://www.basteln-mit-avr.de/atxmega128a3.html#anfaenger Gruß XMEGA
Hey Danke (: dein Code funktioniert, jetzt muss ich nur noch herausfinden, warum meiner nicht funktioniert. Vielen Dank
Wenn ich den Code allerdings in ein neues Projekt packe und neu kompiliere, funkt es auch nicht.
Das Ding will meine Clock nicht einstellen. Wie kann es sein, dass es bei allen in 4 Zeilen super funktioniert (was es ja auch sollte lt. Datenblatt), und bei mir nicht? OSC.CTRL = OSC_RC32MEN_bm; // internen oszillator (32Mhz) aktivieren while(!(OSC.STATUS & OSC_RC32MRDY_bm)) { } DFLLRC32M.CTRL = DFLL_ENABLE_bm; // autokalibrierung aktivieren CCP = CCP_IOREG_gc; // schutz deaktivieren, zum aendern der mpu-clock CLK.CTRL = CLK_SCLKSEL_RC32M_gc; // mpu-clock kann jetzt geaendert werden, 32Mhz als MPU-clock nutzen CCP = CCP_IOREG_gc; // schutz deaktivieren, zum aendern des LOCK-registers CLK.LOCK = CLK_LOCK_bm; // ab hier kann die MPU-clock bis zum naechsten RESET nicht geaendert werden! Schutz hab ich deaktiviert, alles so wie es sein sollte. Hab dann mit einer LED abgefragt, ob die Bits richtig gesetzt wurden: NEIN. Geht einfach nicht
Hallo, Fabian K. schrieb: > Geht einfach nicht ist auf dem Board ein Quarz vorhanden, gelötet/gesteckt ? Bei einigen Atxmega128.. ist es schon öfters vorgekommen, dass der nicht gebrauchte Takt explizit deaktiviert werden musste. Bei dem Internen Takt von 2 Mhz // Disable the unused oscillators: 32 MHz, 32 kHz OSC.CTRL&= ~(OSC_RC32MEN_bm | OSC_RC32KEN_bm | OSC_XOSCEN_bm | OSC_PLLEN_bm); Oder halt umgekehrt- bei dem Internen Takt von 32 Mhz // Disable the unused oscillators: 2 MHz, internal 32 kHz OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_RC32KEN_bm | OSC_XOSCEN_bm | OSC_PLLEN_bm); Gruß Xmega
Wo genau muss ich die unbenutzen Oszillatoren ausschalten? Bevor ich den anderen setze, nach der Kalibrierung, ...? Hier nochmal die Init: OSC.CTRL = OSC_RC32MEN_bm; // internen oszillator (32Mhz) aktivieren while(!(OSC.STATUS & OSC_RC32MRDY_bm)) { } DFLLRC32M.CTRL = DFLL_ENABLE_bm; // autokalibrierung aktivieren CCP = CCP_IOREG_gc; // schutz deaktivieren, zum aendern der mpu-clock CLK.CTRL = CLK_SCLKSEL_RC32M_gc; // mpu-clock kann jetzt geaendert werden, 32Mhz als MPU-clock nutzen CCP = CCP_IOREG_gc; // schutz deaktivieren, zum aendern des LOCK-registers CLK.LOCK = CLK_LOCK_bm; // ab hier kann die MPU-clock bis zum naechsten RESET nicht geaendert werden! Es ist übrigens ein externer Quarz von 32kHz am TOSC1 und 2 PIN. Ich bin wirklich kurz davor das Teil wieder zurückzuschicken. Danke im vorraus
> Ich bin wirklich kurz davor das Teil wieder zurückzuschicken. Stellt Dich diese Art von Problemlösung zufrieden? Du hast geschrieben, dass es 1x funktioniert hat. Wo ist nun das Problem? Bei den Code-Stücken, welche Du nach dieser Meldung gepostet hast, fehlt konsequent die Einstellung des Taktes für den USART - siehe Code von xmega. Ohne das wird es vermutlich nicht gehen. Die Kalibrierung ist ebenso m. E. immer noch unvollständig, m. E. macht das nur Sinn, wenn z. B. gegen den internen 32kHz Oszillator kalibiert wird - siehe Code von Simon. K. Diese Kalibirierung ist vermutlich nicht einmal nötig, siehe Code von xmega. Schaden tut sie nicht, empfehlen würde ich es allemal. Lass es ein paar Tage ruhen. Dann nochmals den ganzen Thread hier durchlesen, hier steht m. E. nach alles drin. Den funktionierenden Code als Ausgangsbasis nehmen. Und dann insbesondere die Behandlung des CLK.PSCTRL verstehen. Dazu muss man das "Clock system" des xmega verstehen. Ja, es ist komplizierter als ein attiny/atmega. Aber es ist immer noch weit einfacher als z. B. das gleiche Setup eines ARMs, insbesondere wenn noch ein "fractional baud rate generator" ins Spiel kommt. Also, wo bleibt Dein Ehrgeiz ? :-) Ich bin raus hier, weiteres Consulting nur gegen harte (oder inzwischen weiche) Euros :-)
Ehrlichgesagt stellt mich das nich zufrieden, wenn ich das Teil zurückschicke. Es hat einmal funktioniert ja, mit einem fertigem hex-File, dann wollte ich es neu kompilieren, geht nicht. Ich hab die Kapitel im Datenblatt jetzt sicher schon 10x gelesen: Kalibrierung braucht man gar nicht, da werksseitig schon vorkalibriert ist. Die Kalibrierung findet standardmäßig mit dem 32khz-Quarz statt, außer man ändert das entsprechende Bit auf 1, dann wird der externe verwendet, also nicht unvollständig. Ich finde es nur merkwürdig, dass der funktionierende Code auch nicht funktioniert, deswegen das mit dem zurückschicken. Trotzdem Danke Fabian
Ich bins nochmal, gibt es noch einen anderen Grund dafür, dass ich nicht in das CLK.CTRL Register schreiben kann, außer dass der Oszillator instabil ist und der Schutz noch aktiviert ist? (d.h. mein Oszillator ist stabil und der Schutz deaktiviert, ich kann aber dennoch nicht schreiben) Danke im vorraus
> Die Kalibrierung findet standardmäßig mit dem 32khz-Quarz statt, > außer man ändert das entsprechende Bit auf 1. Es gibt keinen internen Quarz nur einen internen RC-Oszillator.
Hallo, also ich habe deinen Code usart_tests.c mal eingespielt- und er ist absolut stabil und lauffähig. Vergiss das mal mit der Kalibrierung. Die ist eher für Langzeitstabilität interessant. Für kurze Tests klappt's auch so! Es dürfte dann doch noch irgendwo ein Problem sein. Board, Terminalprogramm,FTDI-USB RS232 oder seriell Kannst du deine eigenen Eingaben sehen, wenn du rxt mit txt brückst. Noch ein Tipp: CodeWizardAVR V2.05.3 Evaluation http://www.hpinfotech.ro/ CodeWizardAVR ist ein echt geniales Tool. Etwas eingeschränkt aber trotzdem für Clock, USART, SPI, Ports usw. Ins besonders für die Clock-Einstellung unverzichtbar!!! Gruß xmega
Na super, das lässt mich nur noch mehr verzweifeln, dass ich weiß, dass mein Code nur bei mir nicht funktioniert (: Nein egal, Danke fürs Testen. Hab übrigens auch noch den Code vom Codewizard getestet (zum setzen der Clock), funkt aber auch nicht. (Aber super Programm (; ,danke für den Tipp ) Ich glaube ich wende mich an den Hersteller (mikroe).
Danke an alle, die sich hier beteiligt haben. Ich habs jetzt hinbekommen. Die ganaue Ursache weiß ich auch nicht, ich habs über die Konsole kompiliert und es ging (: Vielleicht hat mein AVR-Studio ja was. MfG Fabian
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.