mikrocontroller.net

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


Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
/dev/ttyUSB0 opened
 0 0b0     � 240 0b11110000   diff: -240  AND 0b0  XOR 0b11110000
 1 0b1     � 241 0b11110001   diff: -240  AND 0b1  XOR 0b11110000
 2 0b10     � 242 0b11110010   diff: -240  AND 0b10  XOR 0b11110000
 3 0b11     � 243 0b11110011   diff: -240  AND 0b11  XOR 0b11110000
 4 0b100     � 244 0b11110100   diff: -240  AND 0b100  XOR 0b11110000
 5 0b101     � 245 0b11110101   diff: -240  AND 0b101  XOR 0b11110000
 6 0b110     � 246 0b11110110   diff: -240  AND 0b110  XOR 0b11110000
 7 0b111     � 247 0b11110111   diff: -240  AND 0b111  XOR 0b11110000
 8 0b1000
        9 0b1001

10 0b1010

11 0b1011

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Tobi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Oh Verzeihung,
Hab vergessen den Code anzuhängen, hier ist er...
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>


#ifndef F_CPU
#define F_CPU 12288000UL     /* Quarz mit 12,288 Mhz  */
#endif

#define BAUD 9600UL      // Baudrate

// Berechnungen von mikrocontroller.net
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.

#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif


#define BLUE OCR1A    //Definition der TIMER-VERGLEICHS-REGISTER als Farbwerte der LEDs
#define GREEN OCR1B    // 8 bit je Farbe, also Werte von 0-255 , somit 24 bit Farbtiefe möglich
#define RED OCR2

uint8_t a=0 , color=0;

void USART_Init( unsigned int baud );
void USART_Transmit( unsigned char data );


void main(){
  sei(); //Interrupts aktivieren
  USART_Init(UBRR_VAL);

  DDRB = (1 << PB0)|(1 << PB1)|(1 << PB2)|(1<<PB3);     //Pin B0 als ausgang
  DDRC &= ~((1 << PC0)|(1 << PC1)|(1 << PC2));   //Pin C0,... als Eingang

  TCCR1A = (1<<WGM10)|(1<<COM1A1)|(1<<COM1B1); // TIMER 1 für 8 BIT PWM
  TCCR1B = (1<<CS11);

  TCCR2 = (1<<WGM20)|(1<<COM21)|(1<<CS21); //TIMER 2 für 8 BIT Phasenkorrektes PWM

  RED = 0;
  BLUE = 0;
  GREEN = 0;
  while (1){
  }

}

ISR(USART_RXC_vect){
  //uint8_t tmp;
  //tmp = UDR;
  /*if (a == 0){
    RED = tmp;
    a=1;
  }else{
    RED = 0;
    a=0;
  }*/
  USART_Transmit(UDR);
}

void USART_Init( unsigned int baud ) //_Aus ATMega8 Datenblatt
{
  /* Set baud rate */
  UBRRH = (unsigned char)(baud>>8);
  UBRRL = (unsigned char)baud;
  /* Enable Receiver and Transmitter */
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
  // Set frame format: 8data, 1stop bit
  UCSRC = (1<<URSEL)|(3<<UCSZ0);
}

void USART_Transmit( uint8_t data )
{
  /* Wait for empty transmit buffer */
  while ( !( UCSRA & (1<<UDRE)) );
  /* Put data into buffer, sends the data */
  UDR = data;
}

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Code?

Autor: Reinhard Kern (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: R. Freitag (rfr)
Datum:

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

Gruss

Robert

Autor: Tobi (Gast)
Datum:

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

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Michael M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das is ein typscher fehler von falschen baudraten.

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> nachdem ich nämlich den Wert von Hand ausgerechnet hab

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

Autor: Andreas Ferber (aferber)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kleiner Nachtrag:
in Interruptroutinen auf ein Ereignis warten ist meistens eine schlechte 
Idee

Autor: BaudRater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Walter,

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

Danke und Grüße

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.