Hallo Community,
ich programmiere gerade an einem DS1621 und möchte gerne negative
Temperaturen lesen. Das ganze funktioniert mit dem Zweierkomplement.
Bisher habe ich folgenden Code geschrieben, doch leider funktioniert er
nicht wie erwünscht.
Ich erreiche damit schonmal einen Minusvorzeichen, allerdings gibt er
mir immer noch für Werte unter 0: 255 und abwärts aus..
Auch stimmt die Abfrage im If-Block wohl nicht ganz.
Nicht wundern, ich habe beim Auskommentieren Block bisschen rumprobiert.
Anbei der Code:
1
if(temp&&0x01==0x00)
2
{
3
printf(" Temperatur: %d [C]\r",temp);
4
delayMs(0,500);
5
6
7
}
8
else
9
{
10
temp=~temp;//Wert negieren
11
temp_low=temp+0x01;//eins dazuzählen
12
//temp_low = temp_low + 0x01; //temp_low &
13
//temp &= ~(1>>7);
14
printf("%d",temp_low);
15
delayMs(0,500);
16
}
Kann mir da jmd weiterhelfen? Steh echt auf dem Schlauch...
Danke!
Florian Müller schrieb:> if(temp&&0x01 == 0x00)
Ohne jetzt deine Variablendeklaration zu kennen und zu wissen was in
temp steht, solltest du vielleicht ein C-Buch konsultieren.
Was soll dieses Konstrukt bewirken. "&&" ist der Operator für logisches
UND und nicht für Bitweises UND. Und was verleitet dich zu der Annahme,
dass das Vorzeichenbit ausgerechnet im untersten Bit von temp steht?
[quote]Ohne jetzt deine Variablendeklaration zu kennen und zu wissen was
in
temp steht, solltest du vielleicht ein C-Buch konsultieren.[/quote]
Ja du hast vielleicht Recht :P
Schande über mein Haupt!
[quote]Was soll dieses Konstrukt bewirken. "&&" ist der Operator für
logisches
UND und nicht für Bitweises UND. Und was verleitet dich zu der Annahme,
dass das Vorzeichenbit ausgerechnet im untersten Bit von temp
steht?[/quote]
Eigentlich wollte ich die Bedingung stellen, dass wenn Temp kleiner 0
ist, er die Anweisung befolgt.
Eigentlich sitzt das Vorzeichenbit an vorderster Front (MSBfirst)
Florian Müller schrieb:>> Eigentlich wollte ich die Bedingung stellen, dass wenn Temp kleiner 0> ist, er die Anweisung befolgt.
Warum dann nicht einfach so hinschreiben?
Im übrigen kommen die Werte vom DS1621 bereits im Zweierkomplement.
Ich denke dein Problem liegt im zweiten Byte das da noch daher kommt und
die halben Grad darstellt (über das msb).
Kuckst du hier http://www.mikrocontroller.net/part/DS1621 auf Seite 4.
> Auch stimmt die Abfrage im If-Block wohl nicht ganz.
schon.
Aber wozu das ganze?
Das kann printf alleine auch. Einfach dafür sorgen, dass die Datentypen
stimmen, und man braucht sich überhaupt nicht mehr selbst darum kümmern.
Also: Welchen Datentyp hat temp?
Auch wenn man in den meisten µC Programmen mit unsigned char (oder
uint8_t) arbeiten, braucht man hier nur rechtzeitig und an der richtigen
Stelle die Kurve zu int (oder int16_t) kratzen, und schon braucht man
sich um die Sache mit dem 2-er Komplement überhaupt nicht mehr kümmern.
Genau deswegen benutzt das der ds1621 nämlich in erster Linie, weil es
für alle Computer bzw. Programmiersprachen völlig normal ist, dass
vorzeichenbehaftete Werte bzw Variablen mit ihm arbeiten und daher auch
alle Ein-/Ausgabefunktionen bzw. Rechenoperationen dafür ausgelegt ist.
Der Hinweis '2-er Komplement' im Datenblatt ist für dich einfach nur der
Hinweis, dass die Zielvariable, in die du die beiden Bytes reinklopfen
musst (und zwar genau so, wie du sie kriegst) einfach nur ein signed
Datentyp sein soll. In C ist das dann eben ein int, ein signed char, ein
int8_t, ein int16_t, long, int32_t oder was du eben sonst noch so hast,
was mit einem Vorzeichen umgehen kann.
Karl Heinz schrieb:>> Auch stimmt die Abfrage im If-Block wohl nicht ganz.>> schon.> Aber wozu das ganze?> Das kann printf alleine auch. Einfach dafür sorgen, dass die Datentypen> stimmen, und man braucht sich überhaupt nicht mehr selbst darum kümmern.
Achso, du meinst die Funktion "printf" pickt sich dann schon den
richtigen Wert raus?
> Also: Welchen Datentyp hat temp?
int temp;
Damit hab ich es mal probiert..Allerdings spuckt er mir bei den
negativen Werten leider 256 und absteigend aus..wobei aber alle meine
Variablen den Wert int besitzen.
> Auch wenn man in den meisten µC Programmen mit unsigned char (oder> uint8_t) arbeiten, braucht man hier nur rechtzeitig und an der richtigen> Stelle die Kurve zu int (oder int16_t) kratzen, und schon braucht man> sich um die Sache mit dem 2-er Komplement überhaupt nicht mehr kümmern.> Genau deswegen benutzt das der ds1621 nämlich in erster Linie, weil es> für alle Computer bzw. Programmiersprachen völlig normal ist, dass> vorzeichenbehaftete Werte bzw Variablen mit ihm arbeiten und daher auch> alle Ein-/Ausgabefunktionen bzw. Rechenoperationen dafür ausgelegt ist.> Der Hinweis '2-er Komplement' im Datenblatt ist für dich einfach nur der> Hinweis, dass die Zielvariable, in die du die beiden Bytes reinklopfen> musst (und zwar genau so, wie du sie kriegst) einfach nur ein signed> Datentyp sein soll. In C ist das dann eben ein int, ein signed char, ein> int8_t, ein int16_t, long, int32_t oder was du eben sonst noch so hast,> was mit einem Vorzeichen umgehen kann.
Ich schreibe in einen Buffer den Wert byte1, in einem zweiten Buffer den
Wert byte2..anschließend muss ich dann wohl die beiten bytes einfach zu
einem zusammenfassen und es als temp ausgeben.
Anbei habe ich mal den ganzen Code angehängt.
1
init_lcd();
2
3
4
I2CWriteLength[PORT_USED]=2;//Address byte + Data byte
5
I2CReadLength[PORT_USED]=0;//Write only
6
I2CMasterBuffer[PORT_USED][0]=0x90;// DS1621_ADDR; //I2C Adresse des Slaves
7
I2CMasterBuffer[PORT_USED][1]=0xEE;
8
I2CEngine(PORT_USED);
9
delayMs(0,1000);
10
11
while(1)
12
{
13
14
15
I2CWriteLength[PORT_USED]=2;
16
I2CReadLength[PORT_USED]=1;//
17
I2CMasterBuffer[PORT_USED][0]=0x90;
18
I2CMasterBuffer[PORT_USED][1]=READ_TEMPERATURE;
19
I2CMasterBuffer[PORT_USED][2]=DS1621_ADDR|RD_BIT;
20
I2CEngine(PORT_USED);
21
delayMs(0,1000);
22
23
byte1=I2CSlaveBuffer[PORT_USED][0];//Read out byte 1 from slave buffer
24
//byte2 = I2CSlaveBuffer[PORT_USED][0];
25
26
//temp = (byte2 |= (byte1<<8)); //Ab hier und drunter ist alles ok! Oben ist iwo das Problem..natürlich noch an meinen ds anpassen!
Florian Müller schrieb:> Ich schreibe in einen Buffer den Wert byte1, in einem zweiten Buffer den> Wert byte2..anschließend muss ich dann wohl die beiten bytes einfach zu> einem zusammenfassen und es als temp ausgeben.> Anbei habe ich mal den ganzen Code angehängt.
Nein, einfach zusammenfassen ist hier nicht.
Hier steht ein Byte für einen int der die Temperatur in ganzen Grad
darstellt (negative eben im Zweierkomplement).
Vom anderen Byte zählt nur das MSB und gibt an ob noch ein halbes Grad
dazu kommt oder nicht.
byte2.7 = 1 --> + 0.5 Grad
byte2.7 = 0 --> + 0 Grad
Wie gesagt, Doku lesen.