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


von Markus R. (maggus)


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.
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include <avr/interrupt.h>
4
#include <util/delay.h>
5
#include "usart.h"
6
#include "sd_card.h"
7
#include "lcd_n6100.h"
8
#include "adc.h"
9
10
11
void clk_config(void) {
12
  PORTE.DIRCLR = PIN1_bm;  // Layout Fehler!!!
13
  PORTE.OUTCLR = PIN1_bm;  // PE1 fest auf GND!!!
14
  // 16Mhz crystal, 256CKL startup
15
  OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_256CLK_gc;
16
  // enable external oscillator
17
  OSC.CTRL = OSC_XOSCEN_bm;
18
  // PLL-Source = external crystal,  PLL Factor = 2
19
  OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | 2;
20
  while(!(OSC.STATUS & OSC_XOSCRDY_bm)); //Crystal Ready
21
  // enable PLL
22
  OSC.CTRL |= OSC_PLLEN_bm;
23
  while(!(OSC.STATUS & OSC_PLLRDY_bm)); //PLL Ready
24
  CLK.PSCTRL = 0x00;  // No Prescalers
25
  CCP = 0xD8;
26
  // Clock Source = PLL
27
  CLK.CTRL = CLK_SCLKSEL_PLL_gc;
28
}
29
30
31
32
int main(void) {
33
34
  clk_config();
35
36
  sei();
37
  PMIC.CTRL |= PMIC_HILVLEN_bm;  // enable high level interrupts
38
  
39
  usartC0_init();
40
41
  _delay_ms(500);
42
43
  unsigned int wert = 0;
44
  char s[5];
45
46
47
  while(1) {
48
49
    wert = adc_getchan();
50
    usartC0_putc(wert);
51
    usartC0_puts(utoa(wert, s, 10));
52
    usartC0_putc(' ');
53
54
    _delay_ms(1000);
55
  }
56
}
57
58
59
ISR(USARTC0_RXC_vect) {
60
  unsigned char tmp = USARTC0.DATA;
61
  usartC0_putc(tmp);
62
63
  lcd_shutdown();
64
}

mfg Markus

von Sauger (Gast)


Lesenswert?

Moin,

leg mal deine usartC0_XYZ offen

MfG

von Markus R. (maggus)


Lesenswert?

Hier die usart.c:
1
#include <avr/io.h>
2
3
4
void usartC0_init(void) {
5
  PORTC.DIRSET = PIN3_bm;  // TxD
6
  PORTC.DIRCLR = PIN2_bm;  // RxD
7
  
8
  USARTC0.CTRLA = USART_RXCINTLVL_HI_gc;
9
  USARTC0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
10
  USARTC0.CTRLC = USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc;
11
  
12
  // 9600 Baud @ 32Mhz
13
  USARTC0.BAUDCTRLB = 205;
14
  USARTC0.BAUDCTRLA = 4;
15
16
}
17
18
void usartC0_putc(unsigned char chr) {
19
  // wait for data register empty, then send new data
20
  while(!(USARTC0.STATUS & USART_DREIF_bm));
21
  USARTC0.DATA = chr;
22
}
23
24
25
void usartC0_puts(char *chr) {
26
  while(*chr);
27
  usartC0_putc(*chr);
28
}

und noch die adc.c:
1
#include <avr/io.h>
2
3
unsigned int adc_getchan(void) {
4
5
  PORTA.DIRCLR = PIN1_bm | PIN0_bm;
6
7
  ADCA.CTRLA = ADC_ENABLE_bm;  // ADC enable
8
  ADCA.CTRLB = 0x04;        // unsigned mode und 8Bit
9
  ADCA.REFCTRL = 0x20;    // REFA
10
  ADCA.PRESCALER = 0x04;    // 32Mhz/64
11
  ADCA.CH0.MUXCTRL = (1<<0x03);  // INPUT = PIN1
12
  
13
14
  unsigned int tmp = 0;
15
  unsigned int value = 0;
16
17
  // Dummy
18
  ADCA.CH0.CTRL = 0x81;  // Start Conversion, Input = Single Ended
19
  tmp = ADCA.CH0RES;
20
  
21
22
  for(unsigned char i=0; i<10; i++) {
23
    ADCA.CH0.CTRL = 0x81;  // Start Conversion, Input = Single Ended
24
    tmp = ADCA.CH0RES;
25
    value += tmp;
26
  }
27
28
  value /= 10;
29
30
  return value;
31
}

von Uwe S. (de0508)


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 !

.

von Markus R. (maggus)


Lesenswert?

Oh mann, ich habs grad selber gesehen:
1
void usartC0_puts(char *chr) {
2
  while(*chr);
3
  usartC0_putc(*chr);
4
}

das kann natürlich nicht funktionieren...

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
Noch kein Account? Hier anmelden.