Hallo, habe ich was grob falsch gemacht?
Wenn ich meinen Code debugge, änder sich der Wert von "rom_adress"
unerwartet und falsch, selbst die Deklaration mit = 0 hat kein Effekt
auf den Wert. Die Funktion "one_wire_read" liefert uint8_t.
Peter F. schrieb:> Hallo, habe ich was grob falsch gemacht?
Ja.
Peter F. schrieb:> rom_adress|=(data<<shift);
data ist ein uint8_t. Für die Schiebe-Operation wird der nach int
konvertiert, und damit ist die maximal Shift-Weite die von int.
Was ist genau falsch?
Wie sollte es deiner Meinung nach richtig sein?
Meiner Meinung nach muss data erst auf uint64_t erweitert werden, bevor
der shift stattfinden darf.
Also sowas wie
rom_adress|=( (( unint64_t)data)<<shift);
Da ich aber deine falsch/richtig-Bewertung nicht kenne, sind das nur
Vermutungen.
Vielen Dank noch mal. Aber leider Funktioniert das nicht so recht.
@(easylife)
Wenn ich deine Methode mache ist der Wert während der Schleife
0x800000000.
Ich habe die Funktion onewire_read_rom auf uint32_t abgeändert dann
treffen alle erwarteten Werte zu ;), aber wo ist dann der Fehler?
Peter F. schrieb:> Wenn ich deine Methode mache ist der Wert während der Schleife> 0x800000000.
Das verstehe ich dann auch nicht.
Denn wenn in den obersten 8 bit 0x80 steht, heisst das dass im ersten
Schleifendurchlauf korrekterweise 0x80 mit rom_address ver-odert wurde.
Wenn in den nächsten Schleifendurchläufen dann jeweils 0x00 ver-odert
wurde, heisst das für mich, dass one_wire_read() 0x00 zurückgeliefert
hat.
Den cast auf uint64_t beim verodern müsste der Compiler eigentlich
automatisch machen.
Kannst ja mal ausprobieren, ob ein expliziter cast
rom_adress |= (uint64_t)(one_wire_read());
innerhalb der Schleife etwas verbessert.
PittyJ schrieb:> Meiner Meinung nach muss data erst auf uint64_t erweitert werden, bevor> der shift stattfinden darf.>> Also sowas wie> rom_adress|=( (( unint64_t)data)<<shift);
Ja, richtig.
> Da ich aber deine falsch/richtig-Bewertung nicht kenne, sind das nur> Vermutungen.
Ich tendiere dazu, nicht gleich die fertige Lösung zu präsentieren,
sondern einen Hinweis auf den Fehler, damit der Fragesteller die
Möglichkeit hat, selbst auf die Lösung zu kommem und zu verstehen, warum
sie nötig ist.
Peter F. schrieb:> Vielen Dank noch mal. Aber leider Funktioniert das nicht so recht.> @(easylife)
Dann ist wahrscheinlich wirklich was am Compiler.
> Wenn ich deine Methode mache ist der Wert während der Schleife> 0x800000000.
Während, oder danach?
Joe F. schrieb:> Das verstehe ich dann auch nicht.> Denn wenn in den obersten 8 bit 0x80 steht, heisst das dass im ersten> Schleifendurchlauf korrekterweise 0x80 mit rom_address ver-odert wurde.
Nein, denn so weit wird bei deinem Code gar nicht geshiftet, daß da
überhaupt irgendwas ankommen darf. Im Originalcode wird maximal um 48
Bits geshiftet, aber dein Code shiftet nur um maximal 24 Bits und
beschreibt damit nur die unteren 32 Bits. 0x800000000 heißt aber, daß
Bit 35 das einzige ist, das gesetzt wurde.
Rolf M. schrieb:> Joe F. schrieb:>> Das verstehe ich dann auch nicht.>> Denn wenn in den obersten 8 bit 0x80 steht, heisst das dass im ersten>> Schleifendurchlauf korrekterweise 0x80 mit rom_address ver-odert wurde.>> Nein, denn so weit wird bei deinem Code gar nicht geshiftet, daß da> überhaupt irgendwas ankommen darf. Im Originalcode wird maximal um 48> Bits geshiftet, aber dein Code shiftet nur um maximal 24 Bits und> beschreibt damit nur die unteren 32 Bits. 0x800000000 heißt aber, daß> Bit 35 das einzige ist, das gesetzt wurde.
Oops, richtig. Die Schleife müsste korrekterweise 8x durchlaufen werden.
Umso unerklärlicher, dass Bit 35 gesetzt ist.
rom_adress = 0L;
eventuell...
Naja, in deiner Ausgabe kann ja auch was nicht stimmen.
i läuft von 0 bis 3, und hat nicht den Wert, den one_wire_read()
zurückliefert.
Die Schleife sollte auch von 0..7 laufen (den Fehler hat Rolf Magnus ja
bereits erwähnt).
Es sieht so aus, als ob der Compiler die Anweisung den 64-bit Wert zu
shiften einfach ignoriert.
Bzw. evtl. mit 64-bit Werten sehr schlecht bis gar nicht umgehen kann.
Du könntest mal nachgucken, wie der Assemblercode aussieht, den der
Compiler aus den Anweisungen in der Schleife erzeugt.
Vielleicht bringt einen das ja weiter.
Und du solltest mal ausprobieren bei allen 64-bit Operationen long-werte
zu verwenden. Also
uint64_t rom_adress = 0L;
und
rom_adress <<= 8L;
Ausserdem:
Benötigst du überhaupt eine 64-Bit Adresse?
Mit 32-bit kannst du bereits 4 Gigabytes adressieren...
Schade, dass du den Beitrag wieder gelöscht hast.
War interessant.
z.B.
25: x=0;
0x080001F0 BF00 NOP
Klares Compilerproblem.
Dann probiere doch auch nochmal den anderen code aus...
Joe F. schrieb:> Dann probiere doch auch nochmal den anderen code aus...> rom_adress = 0LL;> for (i=0; i<8; i++) {> rom_adress <<= 8LL;> rom_adress |= (unsigned long long)(one_wire_read());> }
An sich dürfte das alles nicht nötig sein, also alle "LL" und der Cast
haben nach C-Definition keine Wirkung. Mag natürlich sein, daß es durch
einen Compiler-Bug irgendwo notwendig wird.
Nur irgendwie ist der ja auch nicht so was exotisches:
Peter F. schrieb:> Software: Keil Arm
Ich kann mir nicht so recht vorstellen, daß der so einfache Sachen wie
Integer Promotion oder Bit-Shifts nicht hinkriegt.
Peter F. schrieb:> Die Werte der Schleife von links nach rechts.> i 0x53 0x37 0x37 0x06> rom_adress 0x800000053 0x800000037 0x800000037 0x800000006
Bist du dir sicher, daß das die Werte von i sind? Die wären dann nämlich
völliger Blödsinn.