Forum: Mikrocontroller und Digitale Elektronik UART String senden


von Martin (Gast)


Lesenswert?

Guten Abend,

Ich versuche gerade vergebens eine Zeichenkette mithilfe eines Atmega8 
an meinen Computer zu schicken. Scheinbar sind meine C Kenntnisse etwas 
eingerostet da einzelne Zeichen mit der Funktion "uart_putc" einwandfrei 
übertragen werden, innerhalb einer Schleife erhalte ich aber nur Müll.
Möglicherweise liegt ein Compilerfehler vor?

Code:
1
#include <avr/io.h>
2
#include <string.h>
3
4
#define OSCSPEED 8000000    /*OSC in Hz*/
5
6
7
void InitUART(uint32_t baud)
8
{
9
  uint16_t baudrate=(OSCSPEED/(16*baud))-1;
10
  /*Set baud rate*/
11
  UBRRH = (unsigned char)(baudrate>>8);
12
  UBRRL = (unsigned char)baudrate;
13
  /* Enable Receiver and Transmitter */
14
  UCSRB = (1<<RXEN)|(1<<TXEN);
15
  /* Set frame format: 8data, 1stop bit */
16
  UCSRC = (1<<URSEL)|(3<<UCSZ0); 
17
}
18
19
unsigned char UARTReceive(void)
20
{
21
  if (UCSRA & (1<<RXC))
22
    return UDR;
23
  else  /* no data pending */
24
    return 0;
25
}
26
27
int uart_putc(unsigned char c)
28
{
29
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
30
    {
31
    }                             
32
 
33
    UDR = c;                      /* sende Zeichen */
34
    return 0;
35
}
36
 
37
/* puts ist unabhaengig vom Controllertyp */
38
void uart_puts (const char *s)
39
{
40
  while (*s) {     
41
    uart_putc(*s);
42
    s++;
43
  }
44
}
45
46
int main()
47
{
48
  char *str = "TEST";
49
  unsigned char c;
50
51
  InitUART(9600);
52
53
  while(1){
54
   
55
    c=UARTReceive();
56
    
57
    if (c){
58
      if(c=='p') {
59
  uart_putc('S');
60
  uart_putc('T');
61
  uart_putc('R');
62
  uart_putc('I');
63
  uart_putc('N');
64
  uart_putc('G');
65
  uart_putc(':');
66
67
  while (*str) {     
68
    uart_putc(*str);
69
    str++;
70
  }
71
      }      
72
    }
73
    
74
  }
75
  
76
  return 0;
77
}

Ausgabe am Terminalprogramm:
1
53 54 52 49 4E 47FFFFFFFFFFFFFF- FFFFFFFFFFFFFF      STRING:.      .
2
FF

Compiler/programer Anweisungen:
1
avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -Os -fsigned-char -I./ -o uart.out rs.c
2
avr-objcopy -j .text -O ihex uart.out uart.hex
3
4
avrdude -p m8 -P usb -c avrispv2 -U flash:w:uart.hex

Bin für jeden Hinweis dankbar!

beste Grüße
Martin

von Karl H. (kbuchegg)


Lesenswert?

Martin schrieb:

> Ich versuche gerade vergebens eine Zeichenkette mithilfe eines Atmega8
> an meinen Computer zu schicken. Scheinbar sind meine C Kenntnisse etwas
> eingerostet da einzelne Zeichen mit der Funktion "uart_putc" einwandfrei
> übertragen werden, innerhalb einer Schleife erhalte ich aber nur Müll.

Lass mich raten:
Bei der ersten Antwort, die du auf einen Tastendruck hin erhältst, 
funktioniert noch alles. Bei den darauffolgenden Antworten kommt dann 
der 'Müll':

> Möglicherweise liegt ein Compilerfehler vor?

In 99% aller Fälle sitzt das Problem vor dem Bildschirm

> int main()
> {
>   char *str = "TEST";
>   unsigned char c;
>
>   InitUART(9600);
>
>   while(1){
>
>     c=UARTReceive();
>
>     if (c){
>       if(c=='p') {
>   uart_putc('S');
>   uart_putc('T');
>   uart_putc('R');
>   uart_putc('I');
>   uart_putc('N');
>   uart_putc('G');
>   uart_putc(':');
>
>   while (*str) {
>     uart_putc(*str);
>     str++;

Gratuliere.
Du hast dir soeben den einzigen Pointer den du zum konstanten String 
"TEST" hast, zerstört.

Warum benutzt du nicht die Funktion uart_puts? Dazu ist sie da.

von Martin (Gast)


Lesenswert?

Ich verwende die Schleife zu Testzwecken, da der Funktionsaufruf mit
1
   uart_puts(str);
genau das gleiche Ergebnis liefert.

Bei der geposteten Ausgabe handelt es sich um den ERSTEN Aufruf der 
Schleife, sprich eigentlich (nach meinen Programmierkenntnissen) müsste 
der String korrekt gesendet werden.

Hast du sonst noch eine Idee?

von Karl H. (kbuchegg)


Lesenswert?

Martin schrieb:

> Hast du sonst noch eine Idee?

Nicht wirklich.
Bis auf das Problem in main() sieht alles richtig aus.

von Tobias W. (hacker-tobi)


Lesenswert?

Hi,

nimm mal die Optimierung -0s raus,evtl. hilfts.

Der C-Code sieht (abgesehen vom Problem im Main) gut aus, da geb ich dem 
Vorposter recht. Ergo sollte der erste Versand klappen.

Oder verschluckt hier irgendwas den ersten Versand? Was passiert denn, 
wenn du das Program so änderst, dass der Pointer nicht mehr ruiniert 
wird, also z.B. eine temp-variable einsetzt?



gruß

tobi

von Martin (Gast)


Lesenswert?

1
int main()
2
{
3
  char *str = "TEST";
4
  char *p = str;
5
6
  unsigned char c;
7
8
  InitUART(9600);
9
10
  while(1){
11
   
12
    c=UARTReceive();
13
    
14
    if (c){
15
      if(c=='p') {
16
  uart_putc('S');
17
  uart_putc('T');
18
  uart_putc('R');
19
  uart_putc('I');
20
  uart_putc('N');
21
  uart_putc('G');
22
  uart_putc(':');
23
24
  while (*str) {     
25
    uart_putc(*str);
26
    str++;
27
  }
28
  str = p;
29
      }      
30
    }
31
    
32
  }
33
  
34
  return 0;
35
}

Code Änderung + Default Optimierung, ändert nichts.
Auch bei mehrfachem Aufruf, selbes Ergebnis.
1
53 54 52 49 4E 47 3A FF - FF FF FF FF FF FF FF FF - FF FF FF FF FF FF FF FF    ........  ........
2
FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
3
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
4
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
5
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
6
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
7
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
8
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
9
FF FF FF FF FF FF FF FF FF - FF 53 54 52 49 4E 47 3A - FF FF FF FF FF FF FF FF    .STRING:  ........
10
FF FF FF FF FF FF FF FF FF - FF

Seltsamerweise gibt es nicht bloss 4 Zeichen aus, sondern mehr.
Muss man vielleicht dem Compiler noch ein Keyword mitgeben damit er den 
String sauber im SRAM ablegt?

von Egberto (Gast)


Lesenswert?

Quartz oder int. Oszillator ? Fuses richtig?

von Karl H. (kbuchegg)


Lesenswert?

Nimm mal den Teil raus oder verkürz ihn (besser)

  uart_putc('S');
  uart_putc('T');
  uart_putc('R');
  uart_putc('I');
  uart_putc('N');
  uart_putc('G');
  uart_putc(':');

vielleicht bricht dir am MAX die Spannung zusammen.

von Martin (Gast)


Lesenswert?

Egberto schrieb:
> Quartz oder int. Oszillator ? Fuses richtig?

Habe das Makefile von einem Beispielprogramm für UART genommen.
Sollte 8MHz intern sein. Fuses habe ich noch nicht überprüft sollten 
aber stimmen:
1
  avrdude -p m8 -P usb -c avrispv2 -U lfuse:w:0xe4:m -U hfuse:w:0xd9:m
 Außerdem würden ja dann die einzelnen Zeichen nicht korrekt übertragen 
werden, oder?


Karl Heinz Buchegger schrieb:
> Nimm mal den Teil raus oder verkürz ihn (besser)
>
>   uart_putc('S');
>   uart_putc('T');
>   uart_putc('R');
>   uart_putc('I');
>   uart_putc('N');
>   uart_putc('G');
>   uart_putc(':');
>
> vielleicht bricht dir am MAX die Spannung zusammen.
>

Habe ich versucht ebenfalls nur FF empfangen
1
FF FF FF FF FF FF                                    ......

Seltsam finde ich außerdem das strlen() für den String "TEST" den Wert 6 
zurückgibt:
1
 4C 45 4E 47 54 48 3A 06 -                            LENGTH:.

Habe leider kaum Erfahrung mit µC deshalb kann ich mir darauf einfach 
keinen Reim machen.

von Felix N. (time2ride)


Lesenswert?

>> Quartz oder int. Oszillator ? Fuses richtig?
>
> Habe das Makefile von einem Beispielprogramm für UART genommen.
> Sollte 8MHz intern sein. Fuses habe ich noch nicht überprüft sollten
> aber stimmen:

UART und interner Osc. geht in den meisten Fällen schief. Probier mal 
einen externen.

von Stefan E. (sternst)


Lesenswert?

Die Ursache deines Problems liegt in dieser Zeile:
1
avr-objcopy -j .text -O ihex uart.out uart.hex
Du musst auch die .data Section in das HEX-File exportieren.

von Martin (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Die Ursache deines Problems liegt in dieser Zeile:avr-objcopy -j .text -O ihex 
uart.out uart.hexDu musst auch die .data Section in das HEX-File exportieren.


Danke!
Das war der Fehler, es funktioniert jetzt einwandfrei.

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.