www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik XMega USART läuft nicht


Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe mir jetzt mal so zum Ausprobieren einen XMega32A4 geholt und 
bring es einfach nicht fertig, ein Zeichen per USART zu senden. Im 
Terminal empfange ich lediglich jede Sekunde den Wert 0xF8, auf dem Oszi 
sieht man am TxD-Ausgang des AVRs nur einen kurzen Wechsel 3V->0V->3V. 
Habe ich irgendeine Konfiguration falsch / vergessen?
Quarz: 16Mhz mit PLL auf 32Mhz
BSCALE = -4 , BSEL = 3332  => 9600,96 Baud (mit den Formeln aus dem 
Datenblatt)
#include <avr/io.h>
#include <util/delay.h>



void clk_config(void) {
  // 16Mhz crystal, 256CKL startup
  OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_256CLK_gc;
  // enable external oscillator
  OSC.CTRL = OSC_XOSCEN_bm;
  // PLL-Source = external crystal,  PLL Factor = 2
  OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 2;
  while(!(OSC.STATUS & OSC_XOSCRDY_bm)); //Crystal Ready
  // enable PLL
  OSC.CTRL |= OSC_PLLEN_bm;
  while(!(OSC.STATUS & OSC_PLLRDY_bm)); //PLL Ready
  CLK.PSCTRL = 0x00;  // No Prescalers
  CCP = 0xD8;
  // Clock Source = PLL
  CLK.CTRL = CLK_SCLKSEL_PLL_gc;
}


void usart_init(void) {
  
  USARTD1.CTRLB = 0x18;  // RXEN, TXEN
  USARTD1.CTRLC = 0x02;  // 8N1 Asynchron
  
  USARTD1.BAUDCTRLB = 205;
  USARTD1.BAUDCTRLA = 4;

}

void usartC0_putc(unsigned char chr) {

  while(!(USARTD1.STATUS & USART_DREIF_bm));
  USARTD1.DATA = chr;
}


int main(void) {

  PORTD.DIR |= (1<<PIN7);    // TXD output
  PORTD.DIR &= ~(1<<PIN6);  // RXD input
  
  clk_config();

  usart_init();
  
  PORTD.DIR |= (1<<PIN3);  // LED

  while(1) {
    PORTD.OUTTGL |= PIN3_bm;  // LED Toggle
    _delay_ms(1000);

    usartC0_putc('x');
  }



}


mfg Markus

Autor: Roland H. (batchman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe es mir nicht im Detail angesehen, ein paar Dinge sind mir 
aufgefallen:

Deine Funktion benennt C0, in der Funktion verwendest Du D1 ... wirklich 
richtig angeschlossen?

Läuft er wirklich mit 16 MHz? Im Zweifel erst Mal den clock Kram 
weglassen und mit dem internen Standard probieren.

Und dann vergiss mal die olle attiny/atmega Schreibweise, und verwende 
die xmega Notation für GPIO: Das sollte so aussehen (die |= und &= ~ 
sind nicht mehr "in"):
    /* Enable USARTD1, RX, PD6 */
    PORTD.DIRCLR = PIN6_bm;

    /* Enable USARTD1, TX, PD7 */
    PORTD.DIRSET = PIN7_bm;

    PORTD.OUTTGL = PIN3_bm;  // LED Toggle

|= mag bei DIR ja noch gehen, aber bei OUTTGL?

Stört Dein LED toggle durch das |= die USART-Einstelllungen? Lege es mal 
auf einen anderen Port. In meinem Beispiel gibt es KEIN |=, nur ein =. 
Nicht, dass das |= die USART Settings löscht.

Bitte die Konstanten in usart_init aufdröseln, das entziffer ich nicht. 
Bitte mal USART_CMODE_ASYNCHRONOUS_gc, USART_RXEN_bm und Konsorten 
verwenden. Deinen Kommentaren traue ich nicht :-)

Autor: XMEGA (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus,

Markus R. schrieb:
> Habe ich irgendeine Konfiguration falsch / vergessen?

so mach ich es, und es funktioniert.

void usart_init(void) {
  // Init USART 9600 bps  -> (F_CPU 32000000 0x7B/0xD6)
  // Init USART 9600 bps  -> (F_CPU 16000000 0xE5/0xBC)

  USARTD1.BAUDCTRLA = 0x7B;
  USARTD1.BAUDCTRLB = 0xD6;
  USARTD1.CTRLC = 0x03;  // Async, No Parity, 1 stop bit, 8 data bits
  USARTD1.CTRLB = 0x18;  // Enable RX and TX // kein CLK2X  !!!!!

}

Gruß XMEGA

Autor: Ansgar K. (paulderbademeister)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist die Optimierung an?
  CCP = 0xD8;
  // Clock Source = PLL
  CLK.CTRL = CLK_SCLKSEL_PLL_gc;
Sonst könnte es hier passieren, dass der write nicht innerhalb von vier 
Zyklen erfolgt und dein Controller immer noch auf 2 MHz läuft.

Du kannst dir auch die Periphal Clock auf einen Portpin ausgeben lassen. 
Diese würde ich erst einmal mit dem Oszi messen und gucken, ob sie 
tatsächlich 32MHz beträgt. Wäre blöd am Rest rumzudoktern, wenn der 
Fehler dort liegt.

Ansonsten hat Roland recht, was die neuen GPIO der xmega angeht - 
read-modify-write ist sooooo 2009 ;)

USARTD1.CTRLC = 0x02;  // 8N1 Asynchron
Das hier sind allerdings auch 7 Datenbit laut Datenblatt.

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ansgar K. schrieb:
>
USARTD1.CTRLC = 0x02;  // 8N1 Asynchron
> Das hier sind allerdings auch 7 Datenbit laut Datenblatt.

Thx, daran lag es. Jetzt funktionierts einwandfrei.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.