Hallo, ich habe mal eine Frage: Ich habe einen HX711 Wiegesensor an einen AVR angeschlossen. Dabei lese ich Bitweise den 24bit ADC Wert als signed 2er Komplement in eine int32_t Wert ein. (Jedes Bit am Eingang auf Null oder ein prüfen, bei 1 dann plus eins und dann immer ein Bit nach links shiften. Jetzt habe ich Quasi in der int32_t den Wert des HX711, kann damit aber nicht weiterrechnen, da ja die ersten 8 Bit immer 0 sind. Wie wandele ich nun am besten den Wert in einen "echten" int32_t um? Würde es so evtl. funktionieren? if (hxwert & (1<<23)) { hxwert |= (1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24); } Oder habe ich da falsch gedacht? Weil die Werte nicht so sind, wie ich sie eigentlich erwartet hätte.
> Würde es so evtl. funktionieren?
ja
oder auch
if (hxwert & 0x800000) hxwert |= 0xff000000;
Johannes schrieb: > Dabei lese ich Bitweise den 24bit ADC Wert als signed 2er Komplement in > eine int32_t Wert ein. (Jedes Bit am Eingang auf Null oder ein prüfen, > bei 1 dann plus eins und dann immer ein Bit nach links shiften. Klingt gut. Mit etwas Glück könnte das auch die SPI-Hardware übernehmen. > Jetzt habe ich Quasi in der int32_t den Wert des HX711, kann damit aber > nicht weiterrechnen, da ja die ersten 8 Bit immer 0 sind. Wo liegt da das Problem? Es ist völlig OK, dass die oberen 8 Bit Null sind. Ist es vielleicht ein Problem der Endianness, also dass höherwertige und niederwertige Bytes vertauscht werden? Oder ist die Variable am Anfang des einlesens nicht Null? Ich würde mal die erwarteten Werte mit den gelesenen Werten auf Bit-Ebene vergleichen.
Markus H. schrieb: > Wo liegt da das Problem? Es ist völlig OK, dass die oberen 8 Bit Null > sind. gilt nur bei positiven Zahlen!
Wenn es avr-gcc-ish sein darf, geht auch
1 | hxwert = (__int24) hxwert; |
Die Frage ist ja, welcher Ausgabeart dein HX11 Wiegesensor folgt? Signed-Magnitude: Das oberste Bit repräsentiert das Minus-Zeichen Das oberste Bit muss entfernt und der Wert mit -1 multipliziert werden. 1er-Complement: http://de.wikipedia.org/wiki/Einerkomplement Das oberste Bit muss entfernt und der Wert invertiert werden. 2er-Complement: http://de.wikipedia.org/wiki/Zweierkomplement Invertieren und noch einmal +1 rechnen. Du kannst zwar die 24 bit auf 32 bit erweitern, in dem Du bit 23 abfragst und in die Bits 24..31 "umlegst" aber eventuell musst Du noch +1 rechnen. Datenblatt Seite 4: The output 24 bits of data is in 2’s complement format. When input differential signal goes out of the 24 bit range, the output data will be saturated at 800000h (MIN) or 7FFFFFh (MAX), until the input signal comes back to the input range. Alles klar? Gruß Ulrich
Also ich lese die 24 bit manuell ohne SPI mit dem ATMEGA 8 ein.
Ich prüfe jedes Bit und shifte dann immer eins nach links.
Sodass dann in der int_32t die ersten 24 Bits befüllt sind.
Dann führe ich if (hxwert & 0x800000) hxwert |= 0xff000000; aus.
Jetzt habe ich aber das seltsame Phänomen das die Werte im Positiven und
Negativen Bereich springen.
Es scheint so als wenn das signed Flag falsch berücksichtigt wird.
Kann es sein das da irgendwas vom C-Compiler falsch gecastet wird etc?
Ich finde den Fehler momentan einfach nicht.
Hier der CODE:
int32_t hxread()
{
volatile int32_t hxwert;
//volatile int32_t temp2;
//Prüfen bzw. warten bis HX Ready ist
while (!HX_READY);
hxwert=0;
for (uint8_t i=0; i<24;i++)
{
PORTD |= (1<<HX_SCK); //Puls an SCK Ausgeben
_delay_us(0.5);
if (PIND & (1<<HX_DATA))
{
hxwert+=1;
}
hxwert <<=1; //Werte um eins weiter nach links shiften
PORTD &= ~(1<<HX_SCK); //SCK wieder auf LOW
_delay_us(0.5);
}
hxwert >>=1;
PORTD |= (1<<HX_SCK); //Puls an SCK Ausgeben
_delay_us(0.5);
PORTD &= ~(1<<HX_SCK); //SCK wieder auf LOW
_delay_us(0.5);
if (hxwert & 0x800000){hxwert |= 0xFF000000;} //in echte int32_t
umwandeln
//if (hxwert & (1<<23)) {
// hxwert |=
(1<<31)|(1<<30)|(1<<29)|(1<<28)|(1<<27)|(1<<26)|(1<<25)|(1<<24);
//}
return hxwert;
}
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.