UART gibt zu viele Zeichen aus

Gast #756301
Lesenswert?
• ▲
▼
Hallo,
Ich bin gerade dabei ein kleines Programm zu schreiben welches einfach 
nur das über UART empfangene Byte wieder zurückschickt. Das ist mein 
erstes C Projekt, hab davor aber schon in ASM programmiert und versteh 
eig alles. Das Problem ist jetzt, wenn ich eine "1" sende, bekomm ich 
eine "1" zurück, hintendran aber noch 5-10 andere Zeichen, die immer 
anders sind und keinen Sinn ergeben. Z.B. sende ich "1" und bekomme 
"1MÞÞß" zurück.. was läuft da falsch?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4
#include <string.h>
5

6
#define F_CPU 16000000L
7
#define BAUD 9600L
8
#define UBRR_VAL ((F_CPU/(BAUD*16))-1)
9

10
void UART_init()
11
{
12
   UBRRH = UBRR_VAL >> 8;
13
    UBRRL = UBRR_VAL & 0xFF;
14
    UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
15
   UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
16
}
17
   
18
int main (void) {
19
      
20
    DDRC = 0xFF;
21
   
22
   UART_init();   
23

24
    sei();
25

26
   bytecount=1;
27

28

29
   while(1)
30
   ;
31
}
32

33
SIGNAL(SIG_UART_RECV)
34
{
35
    unsigned char buffer;
36

37
    buffer = UDR;
38

39
    while ( !( UCSRA & (1<<UDRE)) )
40
        ;
41
    UDR = buffer;
42
}
Gast #756779
Lesenswert?
• ▲
▼
Hallo,
mein Ziel ist nicht dass das programm später mal ein Byte empfängt und 
wieder zurückschickt.. Ich hab das nur als Test geplant und wie ich sehe 
funtkioniert das nicht. Ich hab den Code schon fast 1:1 aus dem Inet 
übernommen, mit dem selben ergebnis. Hat jemand ne Idee?
Gast #757059
Lesenswert?
• ▲
▼
Soo.. ich war mal wieder etwas dumm.. passiert mir irgwie öfters.. Ich 
hatte vergessen die 5V vom Max232 anzuschließen. Jetzt kommt genau das 
zum PC zurück was kommen soll.. Nächstes Problem ist aber schon da. Ich 
hab eine variable, die bis 80 zählen muss, aber komischerweiße bricht 
sie bei 75 ab und fängt bei 0 oder irgendeiner anderen Zahl an. Ich find 
den Fehler aber irgendwie nicht. Kann mir einer von euch helfen?
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include <stdint.h>
4

5
//#define F_CPU 16000000
6
#define BAUD 19200L
7
#define UBRR_VAL ((F_CPU/(BAUD*16))-1)
8

9
uint8_t spalten[16][5];
10
uint8_t bytecount;
11

12
void schieb ()
13
{  
14
  PORTC|=(1<<PC2);
15
  PORTC&=~(1<<PC2);
16
  return;
17
}
18
void setdata ()
19
{
20
  PORTC|=(1<<PC1);
21
  PORTC&=~(1<<PC1);
22
  return;
23
}
24
void clrreg()
25
{
26
  PORTC = 0x00;
27

28
  
29
  uint8_t i;
30
  for (i=1; i <= 56; ++i)
31
  {
32
    schieb();
33
  }
34
  setdata();
35
  return;
36
}
37
void UART_init()
38
{
39
  UBRRH = UBRR_VAL >> 8;
40
    UBRRL = UBRR_VAL & 0xFF;
41
    UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);
42
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
43
}
44
void UART_send(unsigned char c)
45
{
46
  while ( !( UCSRA & (1<<UDRE)) )
47
        ;
48
  UDR = c;
49
  return;
50
}  
51
int main (void) {
52
      
53
    DDRC = 0xFF;
54
  
55
  UART_init();
56
  clrreg();   
57

58
    sei();
59

60
  bytecount=1;
61

62

63
  while(1)
64
  ;
65
}
66

67
ISR(USART_RXC_vect)
68
{
69
    uint8_t data;
70

71
    data = UDR;
72

73
  if(bytecount<=5)
74
  {
75
    spalten[1][bytecount] = data;
76
  }
77
  else if((bytecount>5) && (bytecount<=10))
78
  {
79
    spalten[2][bytecount-5] = data;
80
  }
81
  else if((bytecount>10) && (bytecount<=15))
82
  {
83
    spalten[3][bytecount-10] = data;
84
  }
85
  else if((bytecount>15) && (bytecount<=20))
86
  {
87
    spalten[4][bytecount-15] = data;
88
  }
89
  else if((bytecount>20) && (bytecount<=25))
90
  {
91
    spalten[5][bytecount-20] = data;
92
  }
93
  else if((bytecount>25) && (bytecount<=30))
94
  {
95
    spalten[6][bytecount-25] = data;
96
  }
97
  else if((bytecount>30) && (bytecount<=35))
98
  {
99
    spalten[7][bytecount-30] = data;
100
  }
101
  else if((bytecount>35) && (bytecount<=40))
102
  {
103
    spalten[8][bytecount-35] = data;
104
  }
105
  else if((bytecount>40) && (bytecount<=45))
106
  {
107
    spalten[9][bytecount-40] = data;
108
  }
109
  else if((bytecount>45) && (bytecount<=50))
110
  {
111
    spalten[10][bytecount-45] = data;
112
  }
113
  else if((bytecount>50) && (bytecount<=55))
114
  {
115
    spalten[11][bytecount-50] = data;
116
  }
117
  else if((bytecount>55) && (bytecount<=60))
118
  {
119
    spalten[12][bytecount-55] = data;
120
  }
121
  else if((bytecount>60) && (bytecount<=65))
122
  {
123
    spalten[13][bytecount-60] = data;
124
  }
125
  else if((bytecount>65) && (bytecount<=70))
126
  {
127
    spalten[14][bytecount-65] = data;
128
  }
129
  else if((bytecount>70) && (bytecount<=75))
130
  {
131
    spalten[15][bytecount-70] = data;
132
  }
133
  else if((bytecount>75) && (bytecount<=80))
134
  {
135
    spalten[16][bytecount-75] = data;
136
  }
137
  
138
  if (bytecount>=80)
139
  {                          
140
    bytecount = 0;
141
    UART_send('F');
142
  }
143
  UART_send(bytecount);
144
  bytecount++;
145
  return;
146
}
Gast #757082
Lesenswert?
• ▲
▼
Soo.. hab auch den Fehler gefunden.. eher gesagt mein Vater.. Problem 
war ein Speicherüberlauf.. Spalte ist als Array [16][5] definiert und da 
das ja bei 0 anfängt bin ich eins zu weit und der hat dafür mein 
bytecount gekillt.. Jetzt funktioniert das.. Danke an alle!
#757124
Lesenswert?
• ▲
▼
das, was du in der ISR machst, lässt sich wesentlich eleganter lösen. 
Ein Beispiel:
1
ISR(USART_RXC_vect)
2
{
3
  uint8_t data = UDR;
4

5
  spalten[bytecount / 5][bytecount % 5] = data;
6
  
7
  if (bytecount >= 79)
8
  {                          
9
    bytecount = 0;
10
    UART_send('F');
11
  }
12
  UART_send(bytecount);
13
  bytecount++;
14
  return;
15
}

ACHTUNG: Dein bytecount beginnt ebenfalls bei 0! Wenn du bis 80 zählen 
willst, muss die Bedingung im if so sein, wie ich das da oben 
geschrieben habe.

Und noch was:
1
if(bytecount<=5)
2
  {
3
    spalten[1][bytecount] = data;
4
  }

Hierbei kann auch versucht werden, auf spalten[1][5] zuzugreifen, was zu 
einem Speicherzugriffsfehler führen wird, den du nicht einmal merkst - 
erst, wenn das Programm sporadisch komische Sachen macht.


EDIT: bytecount sollte bei 0 beginnen mein ich :o)

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.