UART String senden

Gast #2558792
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
#2558806
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.
Gast #2558831
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?
#2558855
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
Gast #2558877
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?
Gast #2558944
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.
#2559055
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.

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