Mein AVR glaubt, (x == x) = 0!

Gast #2122650
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
#2122660
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?
Gast #2122665
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?
Gast #2122667
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.
Gast #2122668
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.
Gast #2122687
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
Gast #2122689
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.
#2122691
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.

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