Xmega: utoa/itoa/ltoa funktioniert nicht

OP #2061075
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
OP #2061128
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
}
#2061130
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 !

.

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