Forum: PC-Programmierung Warum Funktioniert dieser Quelltext nicht


von Philipp (Gast)


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.

von mar IO (Gast)


Lesenswert?

1
char Byte = 0, l = 0, h = 0;
2
...
3
return (h<<8) | l;

Bekommst Du vllt. immer als Ergebnis nur 'l'?
Was passiert mit 'h', das ein Byte groß ist und um 8 Stellen, ein Byte, 
verschoben wird?

von Philipp (Gast)


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;

von mar IO (Gast)


Lesenswert?

Okay, dann stimmt wohl meine Vermutung mit dem char-Shiften nicht. 
Schade eigentlich...

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


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.

von Philipp (Gast)


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.

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.