Warum Funktioniert dieser Quelltext nicht

Gast #3172768
Lesenswert?
• ▲
▼
Hallo,
ich habe hier 3 Varianten eines Quelltextes:

Variante 1:
1
    unsigned char l, h;
2

3
    getValue(0x3E, &l, &h);
4
    unsigned short s = (h<<8) | l;
5
    ui->spinBoxTemp->setValue(s);
6

7
    getValue(0x42, &l, &h);
8
    s = (h<<8) | l;
9
    ui->spinBoxHumi->setValue(s);
10

11
    getValue(0x40, &l, &h);
12
    s = (h<<8) | l;
13
    ui->spinBoxPres->setValue(s);
1
void PTHS::getValue(char c, unsigned char *l, unsigned char *h)
2
{
3
    char Byte = 0;
4

5
    *l = 0;
6
    *h = 0;
7

8
    port->putChar(0x12);
9
    while(port->bytesAvailable() == 1);
10
    port->getChar(&Byte);
11
    port->putChar(c);
12
    while(port->bytesAvailable() == 1);
13
    port->getChar(&Byte);
14
    port->putChar(0x00);
15
    while(port->bytesAvailable() == 1);
16
    port->getChar(&Byte);
17
    port->putChar(0x02);
18
    while(port->bytesAvailable() == 1);
19
    port->getChar(&Byte);
20
    while(port->bytesAvailable() == 1);
21
    port->getChar(&Byte);
22

23
    *l = Byte;
24

25
    port->putChar(Byte);
26
    while(port->bytesAvailable() == 1);
27
    port->getChar(&Byte);
28

29
    *h = Byte;
30

31
    port->putChar(Byte);
32
}

Dieser Quelltext funktioniert problemlos. in den beiden folgenden 
Varianten, wo ich die beiden eingelesenen Bytes in der Methode zu einem 
Word zusammen setze, erhalte ich nicht immer die korrekten Daten. es 
kommt mir so vor, als ob sie nur in mehreren bestimmten Zahlenbereichen 
korrekt ausgegeben werden.

Variante 2:
1
    unsigned int s;
2

3
    getValue(0x3E, &s);
4
    ui->spinBoxTemp->setValue(s);
5

6
    getValue(0x42, &s);
7
    ui->spinBoxHumi->setValue(s);
8

9
    getValue(0x40, &s);
10
    ui->spinBoxPres->setValue(s);
1
void PTHS::getValue(char c, unsigned int *i)
2
{
3
    char Byte = 0, l = 0, h = 0;
4

5
    port->putChar(0x12);
6
    while(port->bytesAvailable() == 1);
7
    port->getChar(&Byte);
8
    port->putChar(c);
9
    while(port->bytesAvailable() == 1);
10
    port->getChar(&Byte);
11
    port->putChar(0x00);
12
    while(port->bytesAvailable() == 1);
13
    port->getChar(&Byte);
14
    port->putChar(0x02);
15
    while(port->bytesAvailable() == 1);
16
    port->getChar(&Byte);
17
    while(port->bytesAvailable() == 1);
18
    port->getChar(&Byte);
19

20
    l = Byte;
21

22
    port->putChar(Byte);
23
    while(port->bytesAvailable() == 1);
24
    port->getChar(&Byte);
25

26
    h = Byte;
27

28
    port->putChar(Byte);
29

30
    *i = (h<<8) | l;
31
}

Variante 3:
1
    unsigned int s;
2

3
    s = getValue(0x3E);
4
    ui->spinBoxTemp->setValue(s);
5

6
    s = getValue(0x42);
7
    ui->spinBoxHumi->setValue(s);
8

9
    s = getValue(0x40);
10
    ui->spinBoxPres->setValue(s);
1
unsigned int PTHS::getValue(char c)
2
{
3
    char Byte = 0, l = 0, h = 0;
4

5
    port->putChar(0x12);
6
    while(port->bytesAvailable() == 1);
7
    port->getChar(&Byte);
8
    port->putChar(c);
9
    while(port->bytesAvailable() == 1);
10
    port->getChar(&Byte);
11
    port->putChar(0x00);
12
    while(port->bytesAvailable() == 1);
13
    port->getChar(&Byte);
14
    port->putChar(0x02);
15
    while(port->bytesAvailable() == 1);
16
    port->getChar(&Byte);
17
    while(port->bytesAvailable() == 1);
18
    port->getChar(&Byte);
19

20
    l = Byte;
21

22
    port->putChar(Byte);
23
    while(port->bytesAvailable() == 1);
24
    port->getChar(&Byte);
25

26
    h = Byte;
27

28
    port->putChar(Byte);
29

30
    return (h<<8) | l;
31
}

ich verwende den GCC 4.7.3 und bekomme so langsam das gefühl, dass der 
etwas verbuggt ist. Kann mir das Phänomen nähmlich absolut nicht 
erklären.
Gast #3172871
Lesenswert?
• ▲
▼
>Bekommst Du vllt. immer als Ergebnis nur 'l'?

nein, zurzeit ist der erste messwert bei 226. erhalten tu ich 0.
der zweite liegt bei 553, welchen ich auch erhalte.
der dritte ist bei 10029, welchen ich auch erhalte.
beim zweiten messwert kann ich sagen, das er bei ca. 640 nich mehr 
korrekt ausgegeben wird, bei 770 dann aber wider schon.
der erste messwert wird meistens erst ab 256 korrekt ausgegeben.

>Was passiert mit 'h', das ein Byte groß ist und um 8 Stellen, ein Byte,
>verschoben wird?

Okay, habs mal so geändert, bringt im Programm aber keine Änderung.
1
return ((int)h<<8) | (int)l;
#3172922
Lesenswert?
• ▲
▼
Philipp schrieb:

> [c]
> void PTHS::getValue(char c, unsigned char *l, unsigned char *h)
> {
>     char Byte = 0;
>
>     *l = 0;
>     *h = 0;
>
>     port->putChar(0x12);
>     while(port->bytesAvailable() == 1);
>     port->getChar(&Byte);

Aha.
Solange also am Port 1 Byte verfügbar ist, machst du nichts und 
wiederholst die Schleife wieder und immer wieder. Sondern erst dann, 
wenn nicht 1 Byte verfügbar ist, gehts aus der Schleife raus. Zum 
Beispiel auch dann, wenn gar kein Byte verfügbar ist (denn 0 verfügbare 
Bytes sind ja nicht 1 verfügbares Byte). Dieses nicht verfügbare Byte 
liest du dann aus.

Hmm. Was könnte wohl an dieser Logik nicht stimmen?

> ich verwende den GCC 4.7.3 und bekomme so langsam das gefühl,
> dass der etwas verbuggt ist.

Das der noch Bugs enthält ist sogar sehr wahrscheinlich. Allerdings sind 
das keine Bugs die du aufspüren könntest. Auf deinem Niveau kann man 
sagen, dass das Problem zu 99% vor dem Bildschirm sitzt.
#3172941
Lesenswert?
• ▲
▼
>    char Byte = 0, l = 0, h = 0;


char ist eine gaaaaaanz schlechte Idee, solange du mit Bytes hantierst. 
Bytes immer als unsigned char machen!


   char             für alles was im weitesten Sinne Text ist.

   signed char      fürs rechnen mit kleinen Integer, die ein
                    Vorzeichen brauchen

   unsigned char    fürs rechnen mit kleinen Integern, die KEIN
                    Vorzeichen haben. Genau das ist das, was man
                    gemeinhin als 'Byte' bezeichnet.


Orientier dich bei der Wahl der Datentypen an dieser 'Tabelle' und du 
hast weniger Probleme. Insbesondere überlässt man dem Compiler niemals 
die Wahl, ob er einen char als 'signed' oder 'unsigned' auffassen will. 
Denn was bei Textverarbeitung noch keine Rolle spielt, kann sich beim 
rechnen auswirken!
Daher ist man an diesen Stellen immer explizit und überlässt sein 
Schicksal nicht dem Compilerbauer, wie er char implementiert hat.

Aber bring erst mal dein Empfangsfunktion in Ordnung.
Gast #3172951
Lesenswert?
• ▲
▼
@Karl Heinz Buchegger
Oh ha!! Ich saß heute wohl doch ein wenig zu lange davor.
Hab ich natürlich gleich geändert, auch wenn das seltsamerweise gar 
keine probleme verursacht hat.
Um das eigentlich Problem zu lösen, hab ich l und h jetzt als unsigned 
char definiert und nun läuft alles, wie es soll.

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.