Forum: Mikrocontroller und Digitale Elektronik Höchst sonderbarer Fehler bei serieller Übertragung


von Tobi (Gast)


Lesenswert?

Hallo!

Ich kämpfe seit geraumer Zeit mit einem mir äußerst unverständlichen 
UART-Übertragungsfehler und wende mich jetzt an euch, in der Hoffnung 
auf Erleuchtung!

Es geht um einen ATMEGA8 der per UART mit PC-verbunden ist.
Baudrate ist richtig eingestellt, und ein Quarz mit 12.288MHz verbaut.

Auf dem mikrocontroller läuft ein Programm, das Bei Zeichenempfang einen 
Interrupt auslöst und in dieser Routine das Zeichen zurücksendet.

Da ich bei Tests mit minicom u.ä. manche Zeichen systematisch falsch 
zurückbekommen habe hab ich ein kleines Python-Skript geschrieben, das 
mal alle Zeichen durchprobiert und bei Fehlern etwas Info dazu 
augespuckt.

Folgendes ist die Ausgabe:
1
/dev/ttyUSB0 opened
2
 0 0b0     � 240 0b11110000   diff: -240  AND 0b0  XOR 0b11110000
3
 1 0b1     � 241 0b11110001   diff: -240  AND 0b1  XOR 0b11110000
4
 2 0b10     � 242 0b11110010   diff: -240  AND 0b10  XOR 0b11110000
5
 3 0b11     � 243 0b11110011   diff: -240  AND 0b11  XOR 0b11110000
6
 4 0b100     � 244 0b11110100   diff: -240  AND 0b100  XOR 0b11110000
7
 5 0b101     � 245 0b11110101   diff: -240  AND 0b101  XOR 0b11110000
8
 6 0b110     � 246 0b11110110   diff: -240  AND 0b110  XOR 0b11110000
9
 7 0b111     � 247 0b11110111   diff: -240  AND 0b111  XOR 0b11110000
10
 8 0b1000
11
        9 0b1001
12
13
10 0b1010
14
15
11 0b1011
16
17
12 0b1100
18
13 0b1101
19
 14 0b1110
20
 15 0b1111
21
 16 0b10000
22
 17 0b10001
23
 18 0b10010
24
 19 0b10011
25
 20 0b10100
26
 21 0b10101
27
 22 0b10110
28
  
29
 23 0b10111      31 0b11111   diff: -8  AND 0b10111  XOR 0b1000
30
▒ 24 0b11000
31
 25 0b11001
32
▒ 26 0b11010
33
27 0b11011
34
 28 0b11100
35
 29 0b11101
36
 30 0b11110
37
 31 0b11111
38
  
39
  32 0b100000     0 48 0b110000   diff: -16  AND 0b100000  XOR 0b10000
40
! 33 0b100001     1 49 0b110001   diff: -16  AND 0b100001  XOR 0b10000
41
" 34 0b100010     2 50 0b110010   diff: -16  AND 0b100010  XOR 0b10000
42
# 35 0b100011     3 51 0b110011   diff: -16  AND 0b100011  XOR 0b10000
43
$ 36 0b100100     4 52 0b110100   diff: -16  AND 0b100100  XOR 0b10000
44
% 37 0b100101     5 53 0b110101   diff: -16  AND 0b100101  XOR 0b10000
45
& 38 0b100110     6 54 0b110110   diff: -16  AND 0b100110  XOR 0b10000
46
' 39 0b100111     7 55 0b110111   diff: -16  AND 0b100111  XOR 0b10000
47
( 40 0b101000
48
) 41 0b101001
49
* 42 0b101010
50
+ 43 0b101011
51
, 44 0b101100
52
- 45 0b101101
53
. 46 0b101110
54
/ 47 0b101111
55
0 48 0b110000
56
1 49 0b110001
57
2 50 0b110010
58
3 51 0b110011
59
4 52 0b110100
60
5 53 0b110101
61
6 54 0b110110
62
7 55 0b110111
63
8 56 0b111000
64
9 57 0b111001
65
: 58 0b111010
66
; 59 0b111011
67
< 60 0b111100
68
= 61 0b111101
69
> 62 0b111110
70
? 63 0b111111
71
  
72
@ 64 0b1000000     p 112 0b1110000   diff: -48  AND 0b1000000  XOR 0b110000
73
A 65 0b1000001     q 113 0b1110001   diff: -48  AND 0b1000001  XOR 0b110000
74
B 66 0b1000010     r 114 0b1110010   diff: -48  AND 0b1000010  XOR 0b110000
75
C 67 0b1000011     s 115 0b1110011   diff: -48  AND 0b1000011  XOR 0b110000
76
D 68 0b1000100     t 116 0b1110100   diff: -48  AND 0b1000100  XOR 0b110000
77
E 69 0b1000101     u 117 0b1110101   diff: -48  AND 0b1000101  XOR 0b110000
78
F 70 0b1000110     v 118 0b1110110   diff: -48  AND 0b1000110  XOR 0b110000
79
G 71 0b1000111     w 119 0b1110111   diff: -48  AND 0b1000111  XOR 0b110000
80
H 72 0b1001000
81
I 73 0b1001001
82
J 74 0b1001010
83
K 75 0b1001011
84
L 76 0b1001100
85
M 77 0b1001101
86
N 78 0b1001110
87
O 79 0b1001111
88
P 80 0b1010000
89
Q 81 0b1010001
90
R 82 0b1010010
91
S 83 0b1010011
92
T 84 0b1010100
93
U 85 0b1010101
94
V 86 0b1010110
95
W 87 0b1010111
96
X 88 0b1011000
97
Y 89 0b1011001
98
Z 90 0b1011010
99
[ 91 0b1011011
100
\ 92 0b1011100
101
] 93 0b1011101
102
^ 94 0b1011110
103
_ 95 0b1011111
104
  
105
` 96 0b1100000     p 112 0b1110000   diff: -16  AND 0b1100000  XOR 0b10000
106
a 97 0b1100001     q 113 0b1110001   diff: -16  AND 0b1100001  XOR 0b10000
107
b 98 0b1100010     r 114 0b1110010   diff: -16  AND 0b1100010  XOR 0b10000
108
c 99 0b1100011     s 115 0b1110011   diff: -16  AND 0b1100011  XOR 0b10000
109
d 100 0b1100100     t 116 0b1110100   diff: -16  AND 0b1100100  XOR 0b10000
110
e 101 0b1100101     u 117 0b1110101   diff: -16  AND 0b1100101  XOR 0b10000
111
f 102 0b1100110     v 118 0b1110110   diff: -16  AND 0b1100110  XOR 0b10000
112
g 103 0b1100111     w 119 0b1110111   diff: -16  AND 0b1100111  XOR 0b10000
113
h 104 0b1101000
114
i 105 0b1101001
115
j 106 0b1101010
116
k 107 0b1101011
117
l 108 0b1101100
118
m 109 0b1101101
119
n 110 0b1101110
120
o 111 0b1101111
121
p 112 0b1110000
122
q 113 0b1110001
123
r 114 0b1110010
124
s 115 0b1110011
125
t 116 0b1110100
126
u 117 0b1110101
127
v 118 0b1110110
128
w 119 0b1110111
129
x 120 0b1111000
130
y 121 0b1111001
131
z 122 0b1111010
132
{ 123 0b1111011
133
| 124 0b1111100
134
} 125 0b1111101
135
~ 126 0b1111110
136
 127 0b1111111
137
  
138
� 128 0b10000000     � 240 0b11110000   diff: -112  AND 0b10000000  XOR 0b1110000
139
� 129 0b10000001     � 241 0b11110001   diff: -112  AND 0b10000001  XOR 0b1110000
140
� 130 0b10000010     � 242 0b11110010   diff: -112  AND 0b10000010  XOR 0b1110000
141
� 131 0b10000011     � 243 0b11110011   diff: -112  AND 0b10000011  XOR 0b1110000
142
� 132 0b10000100     � 244 0b11110100   diff: -112  AND 0b10000100  XOR 0b1110000
143
� 133 0b10000101     � 245 0b11110101   diff: -112  AND 0b10000101  XOR 0b1110000
144
� 134 0b10000110     � 246 0b11110110   diff: -112  AND 0b10000110  XOR 0b1110000
145
� 135 0b10000111     � 247 0b11110111   diff: -112  AND 0b10000111  XOR 0b1110000
146
� 136 0b10001000
147
� 137 0b10001001
148
� 138 0b10001010
149
� 139 0b10001011
150
� 140 0b10001100
151
� 141 0b10001101
152
� 142 0b10001110
153
� 143 0b10001111
154
� 144 0b10010000
155
� 145 0b10010001
156
� 146 0b10010010
157
� 147 0b10010011
158
� 148 0b10010100
159
� 149 0b10010101
160
� 150 0b10010110
161
� 151 0b10010111
162
� 152 0b10011000
163
� 153 0b10011001
164
� 154 0b10011010
165
� 155 0b10011011
166
� 156 0b10011100
167
� 157 0b10011101
168
� 158 0b10011110
169
� 159 0b10011111
170
  
171
� 160 0b10100000     � 176 0b10110000   diff: -16  AND 0b10100000  XOR 0b10000
172
� 161 0b10100001     � 177 0b10110001   diff: -16  AND 0b10100001  XOR 0b10000
173
� 162 0b10100010     � 178 0b10110010   diff: -16  AND 0b10100010  XOR 0b10000
174
� 163 0b10100011     � 179 0b10110011   diff: -16  AND 0b10100011  XOR 0b10000
175
� 164 0b10100100     � 180 0b10110100   diff: -16  AND 0b10100100  XOR 0b10000
176
� 165 0b10100101     � 181 0b10110101   diff: -16  AND 0b10100101  XOR 0b10000
177
� 166 0b10100110     � 182 0b10110110   diff: -16  AND 0b10100110  XOR 0b10000
178
� 167 0b10100111     � 183 0b10110111   diff: -16  AND 0b10100111  XOR 0b10000
179
� 168 0b10101000
180
� 169 0b10101001
181
� 170 0b10101010
182
� 171 0b10101011
183
� 172 0b10101100
184
� 173 0b10101101
185
� 174 0b10101110
186
� 175 0b10101111
187
� 176 0b10110000
188
  
189
� 177 0b10110001     � 185 0b10111001   diff: -8  AND 0b10110001  XOR 0b1000
190
� 178 0b10110010
191
� 179 0b10110011
192
� 180 0b10110100
193
� 181 0b10110101
194
� 182 0b10110110
195
� 183 0b10110111
196
� 184 0b10111000
197
� 185 0b10111001
198
� 186 0b10111010
199
� 187 0b10111011
200
� 188 0b10111100
201
� 189 0b10111101
202
� 190 0b10111110
203
� 191 0b10111111
204
  
205
� 192 0b11000000     � 240 0b11110000   diff: -48  AND 0b11000000  XOR 0b110000
206
� 193 0b11000001     � 241 0b11110001   diff: -48  AND 0b11000001  XOR 0b110000
207
� 194 0b11000010     � 242 0b11110010   diff: -48  AND 0b11000010  XOR 0b110000
208
� 195 0b11000011     � 243 0b11110011   diff: -48  AND 0b11000011  XOR 0b110000
209
� 196 0b11000100     � 244 0b11110100   diff: -48  AND 0b11000100  XOR 0b110000
210
� 197 0b11000101     � 245 0b11110101   diff: -48  AND 0b11000101  XOR 0b110000
211
� 198 0b11000110     � 246 0b11110110   diff: -48  AND 0b11000110  XOR 0b110000
212
� 199 0b11000111     � 247 0b11110111   diff: -48  AND 0b11000111  XOR 0b110000
213
� 200 0b11001000
214
� 201 0b11001001
215
� 202 0b11001010
216
� 203 0b11001011
217
� 204 0b11001100
218
� 205 0b11001101
219
� 206 0b11001110
220
� 207 0b11001111
221
� 208 0b11010000
222
� 209 0b11010001
223
� 210 0b11010010
224
� 211 0b11010011
225
� 212 0b11010100
226
� 213 0b11010101
227
� 214 0b11010110
228
� 215 0b11010111
229
� 216 0b11011000
230
� 217 0b11011001
231
� 218 0b11011010
232
� 219 0b11011011
233
� 220 0b11011100
234
� 221 0b11011101
235
� 222 0b11011110
236
� 223 0b11011111
237
  
238
� 224 0b11100000     � 240 0b11110000   diff: -16  AND 0b11100000  XOR 0b10000
239
� 225 0b11100001     � 241 0b11110001   diff: -16  AND 0b11100001  XOR 0b10000
240
� 226 0b11100010     � 242 0b11110010   diff: -16  AND 0b11100010  XOR 0b10000
241
� 227 0b11100011     � 243 0b11110011   diff: -16  AND 0b11100011  XOR 0b10000
242
� 228 0b11100100     � 244 0b11110100   diff: -16  AND 0b11100100  XOR 0b10000
243
� 229 0b11100101     � 245 0b11110101   diff: -16  AND 0b11100101  XOR 0b10000
244
� 230 0b11100110     � 246 0b11110110   diff: -16  AND 0b11100110  XOR 0b10000
245
� 231 0b11100111     � 247 0b11110111   diff: -16  AND 0b11100111  XOR 0b10000
246
� 232 0b11101000
247
� 233 0b11101001
248
� 234 0b11101010
249
� 235 0b11101011
250
� 236 0b11101100
251
� 237 0b11101101
252
� 238 0b11101110
253
� 239 0b11101111
254
� 240 0b11110000
255
� 241 0b11110001
256
� 242 0b11110010
257
� 243 0b11110011
258
� 244 0b11110100
259
� 245 0b11110101
260
� 246 0b11110110
261
� 247 0b11110111
262
� 248 0b11111000
263
� 249 0b11111001
264
� 250 0b11111010
265
� 251 0b11111011
266
� 252 0b11111100
267
� 253 0b11111101
268
� 254 0b11111110

Auffällig ist dabei, dass genau dann ein Fehler auftritt, wenn weder Bit 
4 noch Bit 5 gesetzt ist, also wenn  <zahl>&<0b11000> == 0 .

Ich hatte bereits die Vermutung, dass das UART-Datenregister beschädigt 
sein könnte, und hab den Mikrocontroller ausgetauscht. Selbes Ergebnis.

Da ich nun wirklich ratlos bin, hoffe ich dass jemand schonmal mit 
ähnlichen Problemen gekämpft hat und in deren Beseitigung erfolgreicher 
war als ich und mir behilflich sein kann und mag!

von Karl H. (kbuchegg)


Lesenswert?

> Auf dem mikrocontroller läuft ein Programm, das Bei Zeichenempfang
> einen Interrupt auslöst und in dieser Routine das Zeichen zurücksendet.

Und dieses Programm sieht wie aus?

von Purzel H. (hacky)


Lesenswert?

Ich wuerd mal die Baudrate ueberprufen. zB per interrupt repetitiv einen 
block mit 100bytes rausblasen und mit einem Zaehler und Scope die laenge 
der nachricht genau nachmessen. Auf die mikrosekunde genau.

von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Oh Verzeihung,
Hab vergessen den Code anzuhängen, hier ist er...
1
#include <inttypes.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
6
#ifndef F_CPU
7
#define F_CPU 12288000UL     /* Quarz mit 12,288 Mhz  */
8
#endif
9
10
#define BAUD 9600UL      // Baudrate
11
12
// Berechnungen von mikrocontroller.net
13
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
14
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
15
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
16
17
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
18
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
19
#endif
20
21
22
#define BLUE OCR1A    //Definition der TIMER-VERGLEICHS-REGISTER als Farbwerte der LEDs
23
#define GREEN OCR1B    // 8 bit je Farbe, also Werte von 0-255 , somit 24 bit Farbtiefe möglich
24
#define RED OCR2
25
26
uint8_t a=0 , color=0;
27
28
void USART_Init( unsigned int baud );
29
void USART_Transmit( unsigned char data );
30
31
32
void main(){
33
  sei(); //Interrupts aktivieren
34
  USART_Init(UBRR_VAL);
35
36
  DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2)|(1<<PB3);     //Pin B0 als ausgang
37
  DDRC &= ~((1 << PC0)|(1 << PC1)|(1 << PC2));   //Pin C0,... als Eingang
38
39
  TCCR1A = (1<<WGM10)|(1<<COM1A1)|(1<<COM1B1); // TIMER 1 für 8 BIT PWM
40
  TCCR1B = (1<<CS11);
41
42
  TCCR2 = (1<<WGM20)|(1<<COM21)|(1<<CS21); //TIMER 2 für 8 BIT Phasenkorrektes PWM
43
44
  RED = 0;
45
  BLUE = 0;
46
  GREEN = 0;
47
  while (1){
48
  }
49
50
}
51
52
ISR(USART_RXC_vect){
53
  //uint8_t tmp;
54
  //tmp = UDR;
55
  /*if (a == 0){
56
    RED = tmp;
57
    a=1;
58
  }else{
59
    RED = 0;
60
    a=0;
61
  }*/
62
  USART_Transmit(UDR);
63
}
64
65
void USART_Init( unsigned int baud ) //_Aus ATMega8 Datenblatt
66
{
67
  /* Set baud rate */
68
  UBRRH = (unsigned char)(baud>>8);
69
  UBRRL = (unsigned char)baud;
70
  /* Enable Receiver and Transmitter */
71
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
72
  // Set frame format: 8data, 1stop bit
73
  UCSRC = (1<<URSEL)|(3<<UCSZ0);
74
}
75
76
void USART_Transmit( uint8_t data )
77
{
78
  /* Wait for empty transmit buffer */
79
  while ( !( UCSRA & (1<<UDRE)) );
80
  /* Put data into buffer, sends the data */
81
  UDR = data;
82
}

von Sven (Gast)


Lesenswert?

Code?

von Reinhard Kern (Gast)


Lesenswert?

Tobi schrieb:
> Ich hatte bereits die Vermutung, dass das UART-Datenregister beschädigt
> sein könnte, und hab den Mikrocontroller ausgetauscht. Selbes Ergebnis.

Hallo,

was geht denn wirklich über die Leitung? Ich würde mir das mal mit dem 
Oszi oder einem Protokollanalysator anschauen, besonders die falschen 
Übertragungen, ob die Bitmuster auch so aussehen, ausserdem würde man 
dann einen Baudratenfehler sofort bemerken. Wenn ich serielle 
Übertragungen in Betrieb nehme, überprüfe ich das immer als erstes.

Gruss Reinhard

von Tobi (Gast)


Lesenswert?

Hey,
An Die Baudrate hab ich auch schon gedacht, schließ ich aber aus, denn 
egal was ich Sende, ob ich zwischendrin andere Zeichen sende und dann 
den Ganzen durchlauf nochmal starte, es sind immer genau die gleichen 
Zeichen die Probleme machen und es sind auch immer genau die gleichen 
falschen werte, die zurückgeliefert werden.
Und mit nem Quarz von 12,288MHz sollte ja eigentlich nicht viel 
schiefgehen, oder?

von Tobi (Gast)


Lesenswert?

Ein Oszi oder ähnliches besitze ich leider nicht, obwohls wohl schön 
langsam an der Zeit wäre. Werd versuchen in der Uni an eins zu kommen.
Werd vielleicht vorher noch die Idee von hacky ausprobieren mit der 
Zeitmessung...
Alles in Allem euch schonmal danke!

von R. F. (rfr)


Lesenswert?

Funktioniert die Schnittstelle am Rechner? Versuche das mal mit einer 
zweiten Schnittstelle und einem Nullkabel zu testen.

Gruss

Robert

von Tobi (Gast)


Lesenswert?

NullkabelTest erfolgreich.
die Schnittstelle scheint also auch nicht das Problem zu sein.

von Purzel H. (hacky)


Lesenswert?

Ein Baudratenquarz ist leider nicht genug. Wenn der falsche Wert im 
Register steht war's das. Da muss man nachmessen. Solche 
Integerberechnungen fuer die Baudrate koennen recht danebengehen...

von Michael M. (Gast)


Lesenswert?

das is ein typscher fehler von falschen baudraten.

von Tobi (Gast)


Lesenswert?

So, jetz hab ich mal testweise den Wert im UBRR-Register ein bisschen 
variiert und gemerkt, dass das das wohl tatsächlich der Fehler ist.

Ich werd versuchen an ein Oszi zu kommen und damit der Baudrate zu Leibe 
zu rücken.

Euch allen Vielen Dank,
ihr habt mir schon wesentlich weiter geholfen!

Schönen Gruß,
Tobi

von Tobi (Gast)


Lesenswert?

So, jetzt funktioniert's!
Scheinbar hat das Kompiler-Makro zur Baudratenberechnung irgend nen Mist 
gemacht, nachdem ich nämlich den Wert von Hand ausgerechnet hab und in 
UBRR eingetragen geht die ganze Übertragung fehlerfrei!

Danke nochmal für eure Tipps!

Gruß!
Tobi

von Daniel (Gast)


Lesenswert?

> nachdem ich nämlich den Wert von Hand ausgerechnet hab

Faustregel: Wenn man nicht alles selbst macht, geht's schief...

von Andreas F. (aferber)


Lesenswert?

Tobi schrieb:
> So, jetzt funktioniert's!
> Scheinbar hat das Kompiler-Makro zur Baudratenberechnung irgend nen Mist
> gemacht,

Vermutlich wird F_CPU bei dir bereits per "-DF_CPU=..."-Parameter beim 
Compileraufruf auf einen falschen Wert gesetzt. Der korrekte Wert in 
deinem Source kommt dann wegen dem #ifndef nicht mehr zum tragen.

Und wirf mal einen Blick auf <util/setbaud.h> aus der avr-libc.

Andreas

von Walter (Gast)


Lesenswert?

kleiner Nachtrag:
in Interruptroutinen auf ein Ereignis warten ist meistens eine schlechte 
Idee

von BaudRater (Gast)


Lesenswert?

Hi Walter,

wie sonst? Würdest Du das mal ein wenig beschreiben?

Danke und Grüße

von Tobi (Gast)


Lesenswert?

Andreas Ferber schrieb:
> Vermutlich wird F_CPU bei dir bereits per "-DF_CPU=..."-Parameter beim
> Compileraufruf auf einen falschen Wert gesetzt

Da hast du Recht, der CPU-Takt war in Eclipse noch für nen vorher 
verwendeten Quarz eingestellt:  "-DF_CPU=6144800UL"
Das ist wohl ein Nachteil an komfortablen Programmierumgebungen wie 
Eclipse, sie nehmen einen manchmal mehr Denkleistung ab als gesund ist 
;)

Gruß, Tobi

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.