mikrocontroller.net

Forum: Compiler & IDEs Xmega: utoa/itoa/ltoa funktioniert nicht


Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich habe die Funktionen aus der stdlib.h wie z.B. utoa(), itoa() oder 
ltoa() auf verschienenen Megas immer ohne Probleme anwenden können. Beim 
Xmega32A4 funktioniert es aber überhaupt nicht.
Der Controller gibt mit angehängtem Code überhaupt nichts aus, reagiert 
aber auf einen USART-Interrupt (sendet das empfangene Zeichen zurück, 
siehe ISR).
Wenn ich den Code im Simulator laufen lasse und die Funktion utoa() 
aufgerufen wird, springt er zu einer völlig anderen Stelle im Code (und 
zwar ans Ende der adc_getchan() Funktion).
Wo liegt hier das Problem? Und warum geht es mit den Megas, mit dem 
Xmega aber nicht?
Noch ne andere Frage: wo kann ich mir den Code der Funktion utoa() 
ansehen? In stdlib.h steht ja nur der Prototyp.
#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "usart.h"
#include "sd_card.h"
#include "lcd_n6100.h"
#include "adc.h"


void clk_config(void) {
  PORTE.DIRCLR = PIN1_bm;  // Layout Fehler!!!
  PORTE.OUTCLR = PIN1_bm;  // PE1 fest auf GND!!!
  // 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;
}



int main(void) {

  clk_config();

  sei();
  PMIC.CTRL |= PMIC_HILVLEN_bm;  // enable high level interrupts
  
  usartC0_init();

  _delay_ms(500);

  unsigned int wert = 0;
  char s[5];


  while(1) {

    wert = adc_getchan();
    usartC0_putc(wert);
    usartC0_puts(utoa(wert, s, 10));
    usartC0_putc(' ');

    _delay_ms(1000);
  }
}


ISR(USARTC0_RXC_vect) {
  unsigned char tmp = USARTC0.DATA;
  usartC0_putc(tmp);

  lcd_shutdown();
}

mfg Markus

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

leg mal deine usartC0_XYZ offen

MfG

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier die usart.c:
#include <avr/io.h>


void usartC0_init(void) {
  PORTC.DIRSET = PIN3_bm;  // TxD
  PORTC.DIRCLR = PIN2_bm;  // RxD
  
  USARTC0.CTRLA = USART_RXCINTLVL_HI_gc;
  USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
  USARTC0.CTRLC = USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc;
  
  // 9600 Baud @ 32Mhz
  USARTC0.BAUDCTRLB = 205;
  USARTC0.BAUDCTRLA = 4;

}

void usartC0_putc(unsigned char chr) {
  // wait for data register empty, then send new data
  while(!(USARTC0.STATUS & USART_DREIF_bm));
  USARTC0.DATA = chr;
}


void usartC0_puts(char *chr) {
  while(*chr);
  usartC0_putc(*chr);
}

und noch die adc.c:
#include <avr/io.h>

unsigned int adc_getchan(void) {

  PORTA.DIRCLR = PIN1_bm | PIN0_bm;

  ADCA.CTRLA = ADC_ENABLE_bm;  // ADC enable
  ADCA.CTRLB = 0x04;        // unsigned mode und 8Bit
  ADCA.REFCTRL = 0x20;    // REFA
  ADCA.PRESCALER = 0x04;    // 32Mhz/64
  ADCA.CH0.MUXCTRL = (1<<0x03);  // INPUT = PIN1
  

  unsigned int tmp = 0;
  unsigned int value = 0;

  // Dummy
  ADCA.CH0.CTRL = 0x81;  // Start Conversion, Input = Single Ended
  tmp = ADCA.CH0RES;
  

  for(unsigned char i=0; i<10; i++) {
    ADCA.CH0.CTRL = 0x81;  // Start Conversion, Input = Single Ended
    tmp = ADCA.CH0RES;
    value += tmp;
  }

  value /= 10;

  return value;
}

Autor: Uwe S. (de0508)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mein Tipp ist, vergössere mal

char s[5];


bei 16000 ist das Feld um 1 Zeichen zu klein !

Warum ? jeder String hat 1 Zechen mehr Länge für das Abschliessende 
'\0'.

mit len = strlen(s) kannst Du das nach dem utoa mal testen, ist len == 
4, dann werden 5 Byte benötigt !

.

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh mann, ich habs grad selber gesehen:
void usartC0_puts(char *chr) {
  while(*chr);
  usartC0_putc(*chr);
}

das kann natürlich nicht funktionieren...

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.