ATxmega USART Hilfe

OP #2304307
Lesenswert?

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
#2304426
Lesenswert?

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 :-)
OP #2304517
Lesenswert?

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
#2304563
Lesenswert?

> 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.
OP #2304620
Lesenswert?

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
Gast #2304673
Lesenswert?

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
#2304697
Lesenswert?

>   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.
OP #2305468
Lesenswert?

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
Gast #2305614
Lesenswert?

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
OP #2305710
Lesenswert?

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
#2305805
Lesenswert?

> 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 :-)
OP #2305819
Lesenswert?

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
OP #2306000
Lesenswert?

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
#2306056
Lesenswert?

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
OP #2306308
Lesenswert?

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).

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