Forum: Mikrocontroller und Digitale Elektronik SPI funktioniert nicht


von Sensing (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier schon einige Beiträge bzgl. SPI-Schnittstelle gelesen, 
jedoch mein Problem noch nicht finden können.......und es treibt mich 
ein bisschen in den Wahnsinn :)

Es handelt sich um einen Hallsensor der via SPI angesteuert wird. Anbei 
habe ich mal das Datenblatt hinzugefügt. Unter Punkt 7 ist auch die 
Vorgehensweise beschrieben, um ein Register zu lesen/schreiben.
Das Datenformat beträgt 32 Bit Länge, 16 Bit sind für die Reg-Adresse 
und die weiteren 16 Bit sind dann Lese/Schreibedaten

Ich möchte zunächst nur den on-chip Temperatursensor auslesen, wofür die 
Adresse 0x0110 gewählt werden muss.
Ich verwende einen Arduino, der auf 8 Bit-SPI läuft. Die Adresse Teile 
ich in 2 Teile und schiebe 16 Bit Nullen nach damit auf 32 Bit 
aufgefüllt wird.


Mein Problem:
Ich bekomme ein Signal(MISO), jedoch ändert sich dieses jedes Mal wenn 
ich den Resetknopf auf dem uc-Board drücke. Nach 16-maligem Drücken 
kommt wieder das "1." Signal aufm Oszi zu sehen.

Kann mir hier bitte jemand helfen?



Hier mal noch ein verwendeter Code:
1
#include <SPI.h>
2
3
#define DATAOUT 11           //MOSI
4
#define DATAIN  12           //MISO 
5
#define SPICLOCK  13         //sck
6
#define SLAVESELECT 10       //ss
7
8
9
//Temp-Sens Register
10
#define TempRegRead1 0x01    // 16-9 Bit
11
#define TempRegRead2 0x10    //  8-0 Bit
12
13
14
15
void setup() {
16
Serial.begin(9600);
17
18
  
19
  pinMode(DATAOUT,OUTPUT);                   // SPI Out/Inputs
20
  pinMode(DATAIN,INPUT);
21
  pinMode(SPICLOCK,OUTPUT);
22
  pinMode(SLAVESELECT,OUTPUT);
23
  
24
SPI.begin();               // SPI Bus aktivieren
25
26
  SPI.setClockDivider(SPI_CLOCK_DIV32);      // 16MHz/32=500kHz
27
  SPI.setBitOrder(MSBFIRST);
28
  SPI.setDataMode(SPI_MODE1);
29
  delay(5);
30
}
31
32
33
34
void loop (){
35
  
36
digitalWrite(SLAVESELECT, LOW);
37
38
byte val[4];
39
40
val[0] = SPI.transfer(TempRegRead1);
41
42
43
val[1] = SPI.transfer(TempRegRead2);
44
45
val[2] = SPI.transfer(0x00);
46
47
val[3] = SPI.transfer(0x00);
48
49
50
Serial.println (val[0] );
51
Serial.println (val[1] );
52
53
54
byte bres = (val[2] <<8 )| val[3];
55
digitalWrite(SLAVESELECT, HIGH);
56
57
58
Serial.println (bres);
59
60
}

von Sensing (Gast)


Lesenswert?

....die Serial Println Befehle braucht man nicht beachten.

von spess53 (Gast)


Lesenswert?

Hi

>Ich verwende einen Arduino, der auf 8 Bit-SPI läuft. Die Adresse Teile
>ich in 2 Teile und schiebe 16 Bit Nullen nach damit auf 32 Bit
>aufgefüllt wird.

Welcher Controller?

>  SPI.setDataMode(SPI_MODE1);

Wie das bei Ardoinos ist weiß ich nicht. Aber bei AVRs entspricht das 
gezeigte Protokoll dem SPI-Mode 0.

MfG Spess

von Sensing (Gast)


Lesenswert?

Hallo,

also wenn ich SPI Mode0 verwende, reagiert der MOSI auf die Mitte der 
fallnden Flanke......hier wird ja steigende Flanke benötigt. Hab hier 
auch schon alles durchprobiert, verstehe einfach nicht wieso die MISO 
Data sich bei Neustart jedes mal ändert?

von Sensing (Gast)


Lesenswert?

und auch in diesem Mode0 ist es genau dasselbe :/

von Sensing (Gast)


Lesenswert?

ou, verwendet wird ein Arduino Duemilanove

von spess53 (Gast)


Lesenswert?

Hi

>ou, verwendet wird ein Arduino Duemilanove

Ich hatte eher an etwas wie ATMgaXYZ gedacht.

Das Datenblatt habe ich nur mal überflogen. Da steht etwas von 
Continuous mode und Single shot mode. Per default ist letzterer 
aktiviert. Vielleicht solltest du mal auf Continuous mode umstellen.

MfG Spess

von Jonas A. (Firma: GreenWire-Elektronik) (padrejohn)


Lesenswert?

Nur so die Frage - warum genau schiebst du 16 Nullen nach?.

Wenn du die Clock weiterlaufen willst, würde sich doch eher 16 mal HIGH 
eignen oder?

SPI-Mode 1 scheint mir falsch zu sein - laut deinem Datenblatt wird auf 
High-Flanke gesampelt - ich hätte auf SPI-Mode 0 getippt.

Viel mehr kann ich nicht zu beitragen, habe mich nur selbst gerade mit 
SPI rumgeschlagen.

Dein Arduino hat einen ATmega168? Hast du den Slave-Pin in Benutzung? 
Soweit ich sehe, wäre dann eher SPI.transfer(slaveSelectPin, val) 
sinnvoll ...

von Sensing (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen und vielen Dank für die Antworten.
Ja ein Atmega168 wird verwendet. Anbei hab ich mal die unterschiedlichen 
Modi beigefügt. Gelb ist Clock, Blau ist MOSI.

Ich kann mir nicht vorstellen, dass es am Continous Mode liegt, aber 
werde es mal ausprobieren. Das Problem ist halt, dass ich ja nur mal 
ausprobieren wollte ob ich den Temperatursensor auslesen kann. Diesen 
kann man nur lesen.....deshalb auch die zusätzlichen 16 Nullen.

von Sensing (Gast)


Lesenswert?

also steigende Flanke ist doch schon Mode1 oder steh ich aufm Kopf?

von Jonas A. (Firma: GreenWire-Elektronik) (padrejohn)


Lesenswert?

Sensing schrieb:
> also steigende Flanke ist doch schon Mode1 oder steh ich aufm Kopf?

Sample und Setup nicht vertauschen - ich verstehe das Datenblatt so, 
dass die Daten bei Rising Edge gelesen werden - sprich gesampelt. Das 
heißt, sie müssen vorher schon fertig anliegen (Setup). Das wäre Mode 0

Und probier mal statt der 16 Nullen Einsen zu verwenden.

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>also steigende Flanke ist doch schon Mode1 oder steh ich aufm Kopf?

Sieh dir mal das Bild an (oben Sensor, unten AVR). Mode0 ist Ruhepegel L 
und Abtastung bei steigender Flanke. Mode 1 Ruhepegel H und Abtastung 
bei fallender Flanke.

Und wie macht das dein Sensor?

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

>Und probier mal statt der 16 Nullen Einsen zu verwenden.

Das gibt auch nur 16 Takte. Allerdings signalisiert ein Bit15=1 das die 
nächsten Daten geschrieben werden sollen. Das könnte den Sensor 
verwirren.

Lt. Datenblatt soll man "0"+15 Bit Adresse senden.

MfG

von Jonas A. (Firma: GreenWire-Elektronik) (padrejohn)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Und probier mal statt der 16 Nullen Einsen zu verwenden.
>
> Das gibt auch nur 16 Takte. Allerdings signalisiert ein Bit15=1 das die
> nächsten Daten geschrieben werden sollen. Das könnte den Sensor
> verwirren.
>
> Lt. Datenblatt soll man "0"+15 Bit Adresse senden.
>
> MfG

Ah ok, hatte ich übersehen - bei meinem EEPROM wars andersrum und ich 
hatte dazu nix gefunden - dann kann er sich den Versuch sparen :)

von Sensing (Gast)


Lesenswert?

ok, das mit dem Mode0 habe ich wohl nicht richtig verstanden. Danke 
dafür!!! aber nach wie vor, funzt ned :)

von Jonas A. (Firma: GreenWire-Elektronik) (padrejohn)


Lesenswert?

Sensing schrieb:
> ok, das mit dem Mode0 habe ich wohl nicht richtig verstanden. Danke
> dafür!!! aber nach wie vor, funzt ned :)

Wenn du ein Oszi schon da hast - hast du dir mal den kompletten 
Datenverkehr angeschaut? Du solltest ja 32 Clockcycles sehen - wird 
alles richtig übertragen?

Und wie ist das mit der Beschaltung - Hast du CS richtig beschaltet? 
Steuerst du es mit SPI_SS?

von Sensing (Gast)


Lesenswert?

jap ich schaue mir den clock und die MOSI oder MISO Daten auf dem Oszi 
an.
Beginn der Übertragung.....SS low.....Ende der Übertragung....SS High

von Jonas A. (Firma: GreenWire-Elektronik) (padrejohn)


Lesenswert?

Hast du da nen Bild zu? Kommt einfach nichts zurück oder wie?

von Johannes R. (rosbuster)


Lesenswert?

Hallo,
auch wenn der Thread schon in die Jahre gekommen ist - gibt es zu dem 
Problem mittlerweile eine Lösung?
Ich hänge an dem selben Problem.
Hab hier einen Arduino Uno an einem AS5410 Hall-Sensor angeschlossen und 
bekomme über den SPI Bus mit ähnlichem Code auch keine Daten raus.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Johannes R. schrieb:
> und bekomme über den SPI Bus mit ähnlichem Code auch keine Daten raus.
Was bekommst du stattdessen?
Hast du ein Oszi?

von Johannes R. (rosbuster)


Angehängte Dateien:

Lesenswert?

Die Serial Ausgabe bringt nur Nullen.
Ich habe im Anhang zwei Oszi Aufnahmen von Mosi und Miso mit Clock 
Signal.
Im Mosi Diagramm ist ein Teil der zu übertragenden Bitfolge 
(000000010001000) um das Register 0110h anzusprechen zu sehen.
Laut Sensordatenblatt müsste das so passen.

Den Code habe ich von Sensing größtenteils übernommen.
1
#include <SPI.h>
2
3
#define DATAOUT 11           //MOSI
4
#define DATAIN  12           //MISO 
5
#define SPICLOCK  13         //sck
6
#define SLAVESELECT 10       //ss
7
8
9
//Temp-Sens Register
10
#define TempRegRead1 0x01    // 16-9 Bit
11
#define TempRegRead2 0x10    //  8-0 Bit
12
13
14
15
void setup() {
16
Serial.begin(9600);
17
  
18
  pinMode(DATAOUT,OUTPUT);                   // SPI Out/Inputs
19
  pinMode(DATAIN,INPUT);
20
  pinMode(SPICLOCK,OUTPUT);
21
  pinMode(SLAVESELECT,OUTPUT);
22
  
23
SPI.begin();               // SPI Bus aktivieren
24
25
  SPI.setClockDivider(SPI_CLOCK_DIV32);      // 16MHz/32=500kHz
26
  SPI.setBitOrder(MSBFIRST);
27
  SPI.setDataMode(SPI_MODE0);
28
  digitalWrite(SLAVESELECT, LOW);
29
  delay(50);
30
}
31
32
33
34
void loop (){
35
36
byte val[2];
37
38
SPI.transfer(TempRegRead1);
39
40
SPI.transfer(TempRegRead2);
41
42
val[1] = SPI.transfer(0x00);
43
44
val[2] = SPI.transfer(0x00);
45
46
47
Serial.println (val[1]);
48
Serial.println (val[2]);
49
50
51
}

von Johannes R. (rosbuster)


Angehängte Dateien:

Lesenswert?

Der Sensor funktioniert leider immer noch nicht.
Niemand eine Idee, was denn hier falsch laufen könnte?

Ich hab mittlerweile unter anderem noch versucht bevor ich eine Abfrage 
der Sensorregister mache den Sequencer in Register 000Eh durch senden 
der Bitfolge 10000000 00001110 (write command + 15 bit Register Adresse) 
+ 00000000 00000010 (Schreibdaten) über die MOSI-Leitung zu starten.
Laut Datenblatt müsste der aber sowieso per Default aktiviert sein?

Muss der Datenaustausch vllt nicht wie auf Seite 15 im Datenblatt 
beschrieben sondern wie auf Seite 41 (E²PROM WRITE/READ) durchgeführt 
werden? Oder muss da sonst noch irgendwas initialisiert werden?
Das komplette Datenblatt ist im Anhang.

Am Sensor habe ich denke ich auch alles richtig angeschlossen.
Ich habe hier ein Adapterboard 
(http://ams.com/eng/Support/Demoboards/Magnetic-Position-Sensors/Linear-Position/AS5410-Adapterboard) 
vorliegen, auf dem der Sensor sich befindet und die relevanten 
Anschlüsse bereits auf eine Stiftleiste herausgeführt sind.
Einzig nicht angeschlossene Pins an der Leiste sind bei mir Reset_n und 
nc.

Wenn mir hier jemand weiterhelfen könnte, wäre ich sehr dankbar.

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.