Forum: Mikrocontroller und Digitale Elektronik SPI Empfangs-Problem


von John Twenty (Gast)


Lesenswert?

Per SPI möchte ich Registerinhalte aus einem Accelerometer auslesen. 
Dazu sende ich per SPI_MasterTransmit den passenden Befehl. Zugleich 
gibt mir diese Funktion auch gleich den empfangen Wert zurück. Wenn ich 
nur ein Register im main auslesen will, so funktioniert alles gut. Falls 
ich aber zwei Register im main auslesen will(d.h 2x nacheinander 
SPI_MasterTransmit aufrufe), so bekomme ich den richtigen Wert des 
ersten Register, aber der Registerinhalt des zweiten Registers ist dann 
angeblich immer gleich der des ersten Registers, was nicht sein kann.

Beispiel:
1) SPI_MasterTransmit(Register_1) beudetet lese register1. das gibt mir 
dann den Rückgabewert -> 0x3A

2) SPI_MasterTransmit(Register_2) beudetet lese register2. das gibt mir 
dann den Rückgabewert -> 0xF5

soweit so gut. wenn ich jetzt 2 register im main nacheinander auslesen 
will, dann passiert folgendes:

3) SPI_MasterTransmit(Register_1)
SPI_MasterTransmit(Register_2)
Rückgabewerte -> 0x3A 0x3A  ich bekomme zweimal den gleichen wert (immer 
der wert den ich als erstes auslese)

4) SPI_MasterTransmit(Register_2)
SPI_MasterTransmit(Register_1)
Rückgabewerte -> 0xF5 0xF5

Unten stehend noch mein code bezüglich SPI. ich habe keinen Plan was da 
los ist. Ist das überhaupt ein SPI Problem oder eher irgendwas anderes?


void SPI_MasterInit(void){
/* Set MOSI, SCK and SS output, all others input */
DDRB = (1<<PB2)|(1<<PB3)|(1<<PB5);
PORTB &= ~(1<<PB2);
/* Enable SPI, Master, set clock rate fck/128, SCK high in idle, 
sampling at rising edge  */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1)|(1<<CPOL);
}

char SPI_MasterTransmit(char cData){
//PORTB &= ~(1<<PB2);  // brauchts nicht da im Moment nur ein Slave 
vorhanden
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)));
//PORTB |= (1<<PB2);  // brauchts nicht da im Moment nur ein Slave 
vorhanden
return SPDR;
}

von holger (Gast)


Lesenswert?

>3) SPI_MasterTransmit(Register_1)
>SPI_MasterTransmit(Register_2)
>Rückgabewerte -> 0x3A 0x3A  ich bekomme zweimal den gleichen wert (immer
>der wert den ich als erstes auslese)

Denk mal über folgendes nach:
Du sendest SPI_MasterTransmit(Register_1) und bekommst
gleichzeitig einen Wert zurück. Jetzt stell dir vor
du sendest den Befehl nach Poweron nur ein mal.
Woher soll dein Baustein wissen welches Register du
abfragen wolltest? Er kann dir gar keine gültige Antwort
schicken. Die sendet er erst wenn der erste Befehl komplett
empfangen wurde und ein weiteres Byte gesendet wird das
die Antwort raustaktet.

Versuchs doch mal mit:

SPI_MasterTransmit(Register_1)
SPI_MasterTransmit(Register_2) empfängt die Antwort für Register 1
SPI_MasterTransmit(egal) empfängt die Antwort für Register 2

von John Twenty (Gast)


Lesenswert?

ja, aber das habe ich schon berücksichtigt. Oben habe ich es stark 
vereinfacht geschildert. ich habe eine funktion readRegister 
geschrieben:

char readRegister(char registerName){
  SPI_MasterTransmit(registerName);
  return SPI_MasterTransmit(0x00);  //send dummy byte
}


hier also nochmals vollständig:

Beispiel:
1) readRegister(Register_1) beudetet lese register1. das gibt mir
dann den Rückgabewert -> 0x3A

2) readRegister(Register_2) beudetet lese register2. das gibt mir
dann den Rückgabewert -> 0xF5

soweit so gut. wenn ich jetzt 2 register im main nacheinander auslesen
will, dann passiert folgendes:

3) readRegister(Register_1)
readRegister(Register_2)
Rückgabewerte -> 0x3A 0x3A  ich bekomme zweimal den gleichen wert (immer
der wert den ich als erstes auslese)

4) readRegister(Register_2)
readRegister(Register_1)
Rückgabewerte -> 0xF5 0xF5

das problem besteht einzig allein darin wie das sein kann dass ich immer 
2 gleiche rückgabewerte erhalte?

von holger (Gast)


Lesenswert?

>ja, aber das habe ich schon berücksichtigt. Oben habe ich es stark
>vereinfacht geschildert. ich habe eine funktion readRegister
>geschrieben:

Und WIE ZUM TEUFEL SOLLTE DAS IRGENDJEMAND WISSEN?

Ich verpiss mich hier.

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.