Forum: Mikrocontroller und Digitale Elektronik Mein AVR glaubt, (x == x) = 0!


von Julian E. (Gast)


Lesenswert?

Hallo zusammen,

kann mir vielleicht jemand verraten, was an folgenden Zeilen schief 
gehen könnte?
( System: AVR ATMega8515 auf STK500 mit 16x2-Pollin-LCD an PORTA )
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "lcd.h"
4
5
typedef struct {
6
  uint8_t size;
7
  uint8_t data[10];
8
} buffer_t;
9
10
volatile buffer_t buffer;
11
12
int main( void ) {
13
   ...
14
}
15
16
ISR ( USART_RX_vect ) {
17
  ...
18
  lcd_command( 0b11000101 );   // Cursor Zeile 2, Zeichen 5
19
  print_hex( c );
20
  print_ascii( ' ' );
21
  print_hex( (SB0+SB1+buffer.size) );
22
  print_ascii( ' ' );
23
  print_ascii( '0' + (c == (SB0+SB1+buffer.size)) );
24
  if ( c == (SB0+SB1+buffer.size) )
25
    state = 4;
26
  ...
27
}

Das LCD zeigt mir dann z.B. |   34 34 0    | an und state=4 wird nicht 
erreicht. Nur warum ist
   ( c == (SB0+SB1+buffer.size) ) = 0
wenn offensichtlich gilt:
   c = (SB0+SB1+buffer.size) = 0x34
Was kann da schief laufen?

vielen Dank
lg Julian

von Karl H. (kbuchegg)


Lesenswert?

Julian E. schrieb:

> wenn offensichtlich gilt:
>    c = (SB0+SB1+buffer.size) = 0x34

erklär mir bitte mal nur mit obigem Codeschnipsel, warum das 
offensichtlich sein soll!

Offensichtlich ist, dass das Low-Byte des Additionsergebnisses 34 
ergibt. Aber das sagt ja nichts darüber aus, was das Highbyte ergibt.


Wie groß ist SB0?
Wie groß ist SB1?
Wie gross ist buffer.size?

von Matthias L. (Gast)


Lesenswert?

Wo kommt den c her? Und woher willst du wissen, dass state=4 nicht 
erreicht wird?

von Julian E. (Gast)


Lesenswert?

Sorry, in der Eile und Aufregung hab ich glaub ich einiges vergessen, 
ich probiers nochmal:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "lcd.h"
4
5
#define SB0 'S'
6
#define SB1 'Ü'
7
8
typedef struct {
9
  uint8_t size;
10
  uint8_t data[10];
11
} buffer_t;
12
13
volatile buffer_t buffer;
14
15
int main( void ) {
16
   ...
17
}
18
19
ISR ( USART_RX_vect ) {
20
  uint8_t c = UDR;
21
  ...
22
  lcd_command( 0b11000101 );   // Cursor Zeile 2, Zeichen 5
23
  print_hex( c );
24
  print_ascii( ' ' );
25
  print_hex( (SB0+SB1+buffer.size) );
26
  print_ascii( ' ' );
27
  print_ascii( '0' + (c == (SB0+SB1+buffer.size)) );
28
  if ( c == (SB0+SB1+buffer.size) )
29
    state = 4;
30
  ...
31
}

ich weiß dass, das Programm nicht weiter läuft an genau dieser stelle wo 
state=4 gesetzt wird. Das hab ich mit Displayausgaben nach und nach so 
ausgelotet^^ aber da ist ja eindeutig ein Fehler oder nicht?

von Klaus (Gast)


Lesenswert?

Wie man anhand deines Codeschnipsels klar erkennen kann liegt es daran, 
dass c, SB0 und SB1 definiert sind als
1
crazy int c, SB0, SB1;
Dadurch ist der Compiler nicht länger an die klassische Mathematik 
gebunden und kann Operationen zu Gunsten undefinierter Ergebnisse 
optimieren.

von MaWin (Gast)


Lesenswert?

Da du NATÜRLICH aus grenzenloser Faulheit nicht hinschreibst,
wie SB0 und SB1 definiert sind, kann man nur raten,
und macht sich als Antowrtender vermutlich die Arbeit umsonst.

Das kommt davon wenn man Antowrten kostenlos gibt,
du solltest zahlen, dann werden vielleicht deine Fragen besser.

Vermutlich ist SB0+SB1+buffer.size irgendwas wie 0x134,
also 0x134 <> 0x34.

Da du aber mit nur PrintHex die unteren 8 bits ausgibst,
bekommst du 0x34 und 0x34 angezeigt.

von Klaus (Gast)


Lesenswert?

Aha! Also doch...

von Karl H. (kbuchegg)


Lesenswert?

1
#define SB0 'S'
2
#define SB1 'Ü'

da brauch ich gar nicht mehr länger nachsehen.
Die ASCII COdes von 'S' und 'Ü' zusammengezählt ergeben nie und nimmer 
0x34

von Julian E. (Gast)


Lesenswert?

MaWin schrieb:
> Vermutlich ist SB0+SB1+buffer.size irgendwas wie 0x134,
> also 0x134 <> 0x34.

ich habs grad mit folgendermaßen probiert und es läuft:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "lcd.h"
4
5
#define SB0 'S'
6
#define SB1 'Ü'
7
8
typedef struct {
9
  uint8_t size;
10
  uint8_t data[10];
11
} buffer_t;
12
13
volatile buffer_t buffer;
14
15
int main( void ) {
16
   ...
17
}
18
19
ISR ( USART_RX_vect ) {
20
  uint8_t c = UDR;
21
  ...
22
  if ( c == (uint8_t)(SB0+SB1+buffer.size) )
23
    state = 4;
24
  ...
25
}
ich frage mich nur, warum mein Compiler da plötzlich etwas anderes als 
ein uint8_t draus macht... ich dachte er rechnet automatisch mit dem 
kleinst möglichen Datentyp und das ist in dem Fall (SB0,SB1,buffer.size 
sind alle uint8_t) ein uint8_t...

trotzdem DANKE ihr rettet meine Laune und meinen Abend ;)
1000 DANK

von Andreas B. (Gast)


Lesenswert?

Tatsächlich kann SB0+SB1 (ergibt 303) alleine schon gar nicht mit 
uint8_t repräsentiert werden und dann wird ja dazu noch buffer.size 
aufaddiert…
1
c == (SB0+SB1+buffer.size)

ist also konstant false und der AVR hat (natürlich) recht.

von Karl H. (kbuchegg)


Lesenswert?

Julian E. schrieb:

> ich frage mich nur, warum mein Compiler da plötzlich etwas anderes als
> ein uint8_t draus macht...

Weil er im Gegensatz zu dir die C-Regeln kennt.

In a nutshell:
Gerechnet wird immer mindestens im Zahlenbereich int


> ich dachte er rechnet automatisch mit dem kleinst möglichen Datentyp

Wenn schon, dann mit dem größeren der beiden an der Operation 
beteiligten. Und deine rechte Seite des Vergleichs hat nun mal Datentyp 
int.

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.