SPI_MasterTransmit((SUPPLY_OUT&0b00111111));// RW-Bit auf 0 (lesen). Zero-Bit auf 0. Alle anderen Bits bleiben unveraendert
41
SPI_MasterTransmit(0x00);
42
CS_ADIS16201_H();// ChipSelect auf HIGH
43
44
45
CS_ADIS16201_L();// ChipSelect auf LOW
46
SPI_MasterTransmit(0x00);
47
dataH=SPDR;// MSB
48
SPI_MasterTransmit(0x00);
49
dataL=SPDR;// LSB
50
CS_ADIS16201_H();// ChipSelect auf HIGH
51
52
53
data16=((dataH<<8)|dataL);// 2 Bytes zu einem Wert zusammenfuegen
54
data16=data16&0x0FFF;// die ersten 4 Bits zu 0 setzen, da die Daten nur in den letzten 12-Bit sind
55
printf("%.2f\n",(data16*1.22/1000));// Umrechnen in "Volt" und ausgeben
56
57
return0;
58
}
59
}
Nach meiner Theorie sollte es funktionieren ( :-) ), tut es aber nicht.
Ich bekomme von Sensor nicht die Daten, die ich erwarte (Wert seiner
Versorgungsspannung).
Wo liegt mein Fehler?
In den ersten 8Bits setze den R/W-Bit auf "Read" (Bit7), setze den
zero-Bit auf 0 (Bit6), und setze danach die Adresse des auszulesenden
Registers (Bit5-0).
In den nächsten 8Bits schicke ich einfach Nullen.
Danach wird die Übertragung beendet, und der Sensor müsste nun
"verstehen" was ich von ihm will :-)
Beim nächsten ChipSelect müsste er mir die Antwort auf meine Anfrage
senden.
Dabei speichere ich das ganze als 2x8Bit und verknüpfe es danach
zusammen.
???
>>CS low, 16 bit raus, CS high>>So einfach geht's>das wäre so, wenn ich in den Sensor schreiben möchte.>Wie mache ich es aber, wenn ich AUS dem Sensor auslesen will?>Sensor: 16Bit>Atmega: 8Bit
Genauso.
Du schiebst zweimal acht Bit raus, und liest gleichzeitig die
hereingekommenen zweimal acht Bit ein.
Das ist dein Ergenbis.
Bist Du Dir sicher, dass CPOL und CPHA auf 0 sein müssen?
Ich würde sagen, dass die Teile beide 1 sein müssen. Im 644er Datenblatt
(Seite 168) unteres Diagramm (Fig. 17-4). Die SCK Variante mit CPOL = 1
sieht dem im Sensordatenblatt gezeigten Diagramm ähnlicher als das obere
mit CPHA = 0 und CPOL = 0...
Könnte mich allerdings auch täuschen ;-)
Und dann im Sensordatenblatt auf Seite 5 ganze unten der Satz:
"Utilizing SPI Settings Typically Identified as Phase = 1, Polarity =
1)"
=> Phase = CPHA und Polarity = CPOL würde ich dazu sagen ....
Bensch schrieb:
> Schau doch mal im Datenblatt nach, wie man in den uC einliest ohne zu> schreiben.
Ich müsste ja dem Sensor aber mitteilen, aus welchem Register ich lesen
möchte. Dann wäre es ja quasi ein "schreiben"?
Matthias Lipinsky schrieb:
>>>CS low, 16 bit raus, CS high>>>So einfach geht's>>das wäre so, wenn ich in den Sensor schreiben möchte.>>Wie mache ich es aber, wenn ich AUS dem Sensor auslesen will?>>Sensor: 16Bit>>Atmega: 8Bit>> Genauso.>> Du schiebst zweimal acht Bit raus, und liest gleichzeitig die> hereingekommenen zweimal acht Bit ein.>> Das ist dein Ergenbis.
Dieses Prinzip habe ich verstanden :-)
Aber mache ich mit meinem Code nicht das Gleiche?
Matthias schrieb:
> Bist Du Dir sicher, dass CPOL und CPHA auf 0 sein müssen?>> Ich würde sagen, dass die Teile beide 1 sein müssen. Im 644er Datenblatt> (Seite 168) unteres Diagramm (Fig. 17-4). Die SCK Variante mit CPOL = 1> sieht dem im Sensordatenblatt gezeigten Diagramm ähnlicher als das obere> mit CPHA = 0 und CPOL = 0...>> Könnte mich allerdings auch täuschen ;-)>> Und dann im Sensordatenblatt auf Seite 5 ganze unten der Satz:>> "Utilizing SPI Settings Typically Identified as Phase = 1, Polarity => 1)">>> => Phase = CPHA und Polarity = CPOL würde ich dazu sagen ....
Jep, da war ich mir auch nicht sicher, welchen SPI-Modi ich aussuchen
muss. Habe nun auf Modus 3 umgestellt.
Leider immer noch kein Erfolg :-(
Andreas V. schrieb:
> Ich müsste ja dem Sensor aber mitteilen, aus welchem Register ich lesen> möchte. Dann wäre es ja quasi ein "schreiben"?
Das ist eine Grundeigenschaft von SPI: kein Lesen ohne zu schreiben.
Du schreibst in einer ersten Phase die 16-bittige Registeradresse,
in einer zweiten Phase schreibst du 16 dummy-Bits, damit du die
16-bittige Antwort einlesen kannst. Die select-Leitung bleibt dabei
die ganze Zeit gezogen.
(Disclaimer: ich habe mir das Datenblatt des Slaves jetzt nicht
angesehen. Das ist eine Beschreibung der allgemeinen Funktionsweise
von SPI.)
Matthias schrieb:
> Ich hab da so ein Verdacht:>> Versuch mal das da unten:>>
1
>
2
>voidSPI_MasterTransmit(charcData)
3
>{
4
>SPSR|=(1<<SPIF);// SPIF Flag löschen bevor eine weitere
5
>// Aktion ausgeführt wird....
6
>
7
>/* Start transmission */
8
>SPDR=cData;
9
>/* Wait for transmission complete */
10
>while(!(SPSR&(1<<SPIF)));
11
>}
12
>
13
>
14
>
Habe die Zeile eingefügt, keine Veränderungen :-(
Der Controller funktioniert mit einem anderen Sensor (8-Bit) mit den
gleichen SPI-Funktionen einwandfrei. Aber mit dem 16-bittigen klappt es
nicht.
Jörg Wunsch schrieb:
> Andreas V. schrieb:>>> Ich müsste ja dem Sensor aber mitteilen, aus welchem Register ich lesen>> möchte. Dann wäre es ja quasi ein "schreiben"?>> Das ist eine Grundeigenschaft von SPI: kein Lesen ohne zu schreiben.> Du schreibst in einer ersten Phase die 16-bittige Registeradresse,> in einer zweiten Phase schreibst du 16 dummy-Bits, damit du die> 16-bittige Antwort einlesen kannst. Die select-Leitung bleibt dabei> die ganze Zeit gezogen.>> (Disclaimer: ich habe mir das Datenblatt des Slaves jetzt nicht> angesehen. Das ist eine Beschreibung der allgemeinen Funktionsweise> von SPI.)
Stimmt nicht gant. Zwischen der ersten und der zweiten Phase geht die
select-Leitung kurzzeitig wieder auf High.
holger schrieb:
> Beitrag "Re: ATmega 644v und SPI: Problem mit 16-Bit">> Vieleicht mag er das ja doch noch mal ausprobieren ;)
ups, habe vergessen darauf zu antworten :-/
Ich habe das natürlich ausprobiert, danke für dein Tipp!
Hat aber keine Verbesserung gebracht :-(
Was mir jetzt auffällt:
Bei dem oben von mir aufgeführten Code (Auslesen des
SUPPLY_OUT-Registers) erhalte ich folgende Werte:
MSB: 0x00
LSB: 0xCA
Resette ich den Controller, dann bekomme ich
MSB: 0x00
LSB: 0x00
Nach einem nochmaligen Reset dann wieder
MSB: 0x00
LSB: 0xCA
usw....
Andreas V. schrieb:
> Stimmt nicht gant. Zwischen der ersten und der zweiten Phase geht die> select-Leitung kurzzeitig wieder auf High.
Der ist in der Tat ein wenig eigenwillig hier. Die Registerzugriffe
selbst sind eigentlich gar keine 16-bit-Zugriffe, sondern letztlich
zwei 8-bit-Zugriffe innerhalb eines SPI-Zyklus. Wenn man aber Daten
lesen will, dann muss man einen weiteren 16-bit-Zugriff anhängen,
der dann die Daten liefert, wobei man ihm auf DIN bereits das nächste
Kommando senden kann.
Jetzt könnte es noch sein, dass er ein Problem hat, wenn man Ihm
die Pins für den CS zu schnell schaltet. Evtl. sollte auch zwischen
dem "kurzen" H (zwischen den beiden Phasen) ein kurzes delay()
rein. Im Zweifelsfall ca. das dreifache der Periodendauer des SPI
Taktes.
Matthias schrieb:
> Jetzt könnte es noch sein, dass er ein Problem hat, wenn man Ihm> die Pins für den CS zu schnell schaltet.
Datenblatt Seite 5, das Teil hat ziemlich lange Chipselekt-Zyklen-
zeiten.
Matthias schrieb:
> Jetzt könnte es noch sein, dass er ein Problem hat, wenn man Ihm> die Pins für den CS zu schnell schaltet. Evtl. sollte auch zwischen> dem "kurzen" H (zwischen den beiden Phasen) ein kurzes delay()> rein. Im Zweifelsfall ca. das dreifache der Periodendauer des SPI> Taktes.
das war der etnscheidene Tipp!
Danke schön!
Habe zwischen zwei Phasen eine Warteschleife von 100µs eingefügt, und
bekommen nun meine richtigen Daten!
juhu :-)