Hallo Leute,
ich versuche gerade 32-Bit SPI Daten von einem MAX31855 in eine 32-Bit
uint Variable zu schreiben. Aber egal welche Methode ich ausprobiere,
der Compiler scheint da immer irgendwie dazwischen zu murksen. Im Moment
benutze ich AVR-Studio 4 mit der avr-gcc-toolchain.
Hier mal ein paar Beispiele, was ich so ausprobiert habe:
Nachtrag:
buffer sollte auch mal definiert gesetzt werden.
Mit dem ersten Byte z.B.
Und die Maskiererei kannst du dir auch sparen.
buffer = (uint32_t)SPI_recvByte() << 24;
buffer |= (uint32_t)SPI_recvByte() << 16;
usw.
Und schon sieht das alles viel einfacher aus
Ja, das mag sein. Ich habe es angepasst, aber besser ist es nicht
geworden.
Es wäre schön wenn die zweite oder dritte Codeschnipsel laufen würde.
Es ist so, das der Sensor (MAX31855) 32-Bit an Daten über den SPI
sendet. Diese lese ich ein. Da der SPI-Eingangsbuffer des Atmega (nur)
8-Bit aufnehmen kann, mache ich das halt vier mal hintereinander.
holger schrieb:> Nachtrag:>> buffer sollte auch mal definiert gesetzt werden.> Mit dem ersten Byte z.B.>
Ja, mache ich. Im Moment ist buffer auch global, um den ganzen Schmarn
debuggen zu können.
Ja, habe ich auch schon gemacht. Das funktioniert soweit.
Was mich wundert, wenn ich das ganze debugge, werden effektiv nur die
beiden Zeilen umgesetzt:
buffer |= (SPI_recvByte() << 8UL);
buffer |= (SPI_recvByte());
Bzw. bewirken diese das sich etwas in buffer ändert.
>Also ich würde den Buffer erstmal per Hand füllen um zu gucken ob der>Fehler vom SPI kommt oder beim Zusammensetzen passiert.
Oder besser gesagt: Ich würde mir die Bytes die
SPI_recvByte() liefert mal per UART ansehen.
Das zusammensetzen klappt hiermit schon:
buffer = (uint32_t)SPI_recvByte() << 24;
buffer |= (uint32_t)SPI_recvByte() << 16;
buffer |= (uint16_t)SPI_recvByte() << 8;
buffer |= SPI_recvByte();
Das hab ich schon tausend mal so gemacht.
Ne, es funktioniert nücht. Ich meinte damit nur das die Sachen die über
SPI eingelesen korrekt auf dem USART ausgegeben werden. Also somit die
SPI Routine funktioniert.
>Hier mal die gesamte Funktion:
Ja, immer schön beratungsresistent bleiben.
buffer |= (uint32_t)(byte[index] << (8 * (3 - index)));
Schmeiß den Müll in die Tonne.
Es scheint immer noch daran zu liegen, dass Werte die größer als 16-Bit
sind, verschluckt werden.
Format:
byte[0] | byte[1] | byte[2] | byte[3] |> buffer > temp
Daten per USART rausgeschickt.
0|196|21|176|>5552> 0.00
Also byte[0..3] ergibt nicht buffer.
holger schrieb:>>Hier mal die gesamte Funktion:>> Ja, immer schön beratungsresistent bleiben.>> buffer |= (uint32_t)(byte[index] << (8 * (3 - index)));>> Schmeiß den Müll in die Tonne.
Btw. das von dir angeratene Vorgehen fluppt auch nicht:
> 0|196|21|176|>5552> 0.00
Das ist sicher nicht 5552. In HEX vieleicht.
Da schmeisst du 18 Bits von 32 weg
buffer = buffer >> 18;
Was wohl diese Frage beantwortet:
>dass Werte die größer als 16-Bit>sind, verschluckt werden.
Ausserdem scheint der Wert ja noch signed zu sein
> if(buffer & 0x2000) // check sign bit
Da ist schieben schon mal eine ganz schlechte Idee.
>Btw. das von dir angeratene Vorgehen fluppt auch nicht:>> byte[0] = SPI_recvByte();> buffer = (uint32_t)(byte[0] << 24);
Natürlich nicht wenn du so einen Müll produzierst.
So geht das
buffer = ((uint32_t)byte[0] << 24);
Ich mach mich jetzt lieber mal vom Acker.
@DrGonzo
Wenn ich bei solch EINFACHEN Problemen nicht weiten komme, extrahiere
ich die paar Zeilen, lege ein neues leeres Projekt an und füttere die
Sequenz mit explizit definierten Daten.
Dann sehe ich was ich mache oder was der böse Compiler verbricht.
for (unit8_t i=0;i<3;i++) {
// ...00000000 | 0b????????
Buffer = ( Buffer << 8 ) | Receive ();
}
oder so