Forum: Mikrocontroller und Digitale Elektronik Beim L6470 fehlt das 7-te Bit


von tom (Gast)


Lesenswert?

Habe mir den Schrittmotortreiber IC L6470 besorgt und teste gerade die 
Verbindung über SPI durch einen ATmega32.
Die Verbindung selbst steht und funktioniert. Kann Register beschreiben 
und Register lesen.

Das Problem ist aber das 7.Bit! Beim lesen eines Registers wo das 7.Bit 
gesetzt also "1" ist, wird dieses aber immer mit 0 gelesen! Beispiel: 
Wenn man das 16-Bit Config Register ausliest sollte "00101110 und 
10001000 als Defaultwert nach Reset (0x2E88) aus dem L6470 kommen. Es 
kommt aber "00101110 und 00001000 also 0x2E08.
Also das 7.Bit des LOW-Bytes wird nicht als 1 gelesen, obwohl dieses 
aber 1 ist!
Jetzt habe ich schon die SPI so langsam wie möglich gemacht, habe 
zusätzliche Wartezeiten noch mit eingebaut, aber ich kann nicht das Bit7 
als 1 lesen.
Mit dem Logic Analyzer habe ich die Datenübertragung über SPI sichtbar 
gemacht und es ist ganz eindeutig zu sehen, das das 7.Bit auch wirklich 
0 auf dem SPI-Bus ist, obwohl dieses nicht sein kann!
Ich verstehe es nicht mehr und deshalb will ich hier mal Fragen, ob 
jemand eine Idee hat, woran dieses liegen könnte? Ich habe jedenfalls 
keine Idee mehr...

von Holm T. (Gast)


Lesenswert?

..richtige Taktflanke ausgewählt?

Gruß,
Holm

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


Lesenswert?

tom schrieb:
> Mit dem Logic Analyzer habe ich die Datenübertragung über SPI sichtbar
> gemacht und es ist ganz eindeutig zu sehen, das das 7.Bit auch wirklich
> 0 auf dem SPI-Bus ist, obwohl dieses nicht sein kann!
Zeig doch mal einen Screenshot davon.

: Bearbeitet durch Moderator
von tom (Gast)


Angehängte Dateien:

Lesenswert?

habe mal einen Screenshot vom Logic Analyzer angehangen. Im Screenshot 
habe ich das fehlende HIGH des 7.Bit´s per Hand mal eingezeichnet.

Ich habe jetzt festgestellt, immer wenn der Befehl GET_PARAM verwendet 
wird, wird das 7.Bit immer mit 0 ausgegeben. Egal welches Register ich 
mit dem Befehl GET_PARAM anspreche. Ist das Bit7 auf 1 gesetzt wird mir 
immer 0 dafür aus dem L6470 übertragen.
Beim Befehl GET_STATUS funktioniert es aber tadellos. Hier wird das 
7.Bit auch als 1 ausgegeben.

Ich verstehe das Ganze nicht mehr... Sowas ist doch eigentlich nicht 
möglich... Ich habe keine Idee mehr was man machen könnte...

Das sind meine Einstellungen für die SPI:
IRQ=aus, SPI=ein, MSB als erstes, SPI=Master, Takt=Aufsteigende Flanke, 
Phase=bei aufsteigender Flanke, Frequenzteiler durch 128

Der Ablauf des Einlesens ist folgendermaßen gemacht:
1. Register 1 laden mit dem Wert GET_PARAM (0x20 00100000)
2. Register 2 laden mit dem Wert der Adresse für Register Config (0x18 
00011000)
3. Register 1 und Register 2 mit ODER verknüpfen. Dadurch ein 
gemeinsames Byte mit Befehl GET und mit dem Parameter für Adresse CONFIG 
im Register 1. (00111000)
4. /CS auf LOW. Damit L6470 aktivieren
5. Wert aus Register 1 in SPI Register SPDR übergeben
6. SPSR Register lesen und nachsehen ob SPIF schon gesetzt ist, was 
einem beenden der Übertragung der 8Bit´s bedeutet.
7. /CS wieder auf HIGH. L6470 deaktivieren
8. Wartezeit von mindestens 800nS dem L6470 Zeit geben, damit dieser den 
gesendeten Befehl verarbeiten kann. Aktuell habe ich sogar 200uS! Habe 
auch schon noch längere Wartezeiten getestet. Alles ohne Erfolg...
9. Register 1 mit NOP Byte laden (0x00)
10. /CS auf LOW. Damit L6470 aktivieren
11. Wert aus Register 1 (NOP-BYTE) in SPI Register SPDR übergeben und 
warten bis 8bit´s versendet sind.
12. /CS auf HIGH. L6470 deaktiviert
13. empfangenen Wert aus SPDR in Register 1 übergeben und in das SRAM in 
eine Variable kopieren.
14. Register 1 erneut mit NOP Byte laden (0x00)
15. /CS auf LOW. Damit L6470 aktivieren
16. Wert aus Register 1 (NOP-BYTE) in SPI Register SPDR übergeben und 
warten bis 8bit´s versendet sind.
17. /CS auf HIGH. L6470 deaktiviert
18. empfangenen Wert aus SPDR in Register 1 übergeben und in das SRAM in 
eine weitere Variable kopieren.
19. Beide empfangenen Werte aus dem SRAM laden als Bytewerte dekodieren 
und im Display anzeigen.

Ich habe auch schon mal die Werte, die aus dem SPDR Register kommen so 
verändert, das immer das 7.Bit eine 1 ist. Nur um sicher zu stellen das 
die Konvertierung bzw. Dekodierung keinen Softwarefehler hat. Aber es 
ist ja aus dem Logic Analyzer ganz eindeutig zu erkennen, das wirklich 
keine 1 als 7.Bit kommt.

Was ich mich allerdings frage ist dieses:
Normalerweise, so wie ich das eigentlich von der SPI her kenne, wird 
doch /CS beim Anfang auf LOW gesetzt und dann alle Bytes gesendet die 
benötigt werden und erst am Ende wenn alle Bytes übergeben wurden wird 
dann /CS wieder HIGH. Bei dem L6470 muss man nach jedem gesendeten Byte 
das /CS wieder auf HIGH bringen, sonnst funktioniert hier Garnichts! 
Sonnst werden die Daten die ich zum L6470 sende einfach ignoriert.
Ist das denn so überhaupt richtig? Im Datenblatt steht:

After each byte transmission the CS input must be raised and be kept 
high for at least tdisCS in order to allow the device to decode the 
received command and put the return value into the SHIFT register.

Also sollte es doch so richtig sein, oder habe ich da etwas nicht 
verstanden?

von tom (Gast)


Lesenswert?

Noch ein Nachtrag. Der Screenshot stellt das Auslesen des CONFIG 
Register dar. dieses ist laut Hersteller nach dem Einschalten bzw. Reset 
immer mit 0x2E88 geladen. Also sollte binär sein 00101110,10001000 was 
aber nur 0010111000001000 ist!

von A. B. (Gast)


Lesenswert?

tom schrieb:
> habe mal einen Screenshot vom Logic Analyzer angehangen. Im Screenshot
> habe ich das fehlende HIGH des 7.Bit´s per Hand mal eingezeichnet.

Das CS fehlt aber, und das ist mindestens genau so wichtig wie die 
anderen.

> dann /CS wieder HIGH. Bei dem L6470 muss man nach jedem gesendeten Byte
> das /CS wieder auf HIGH bringen, sonnst funktioniert hier Garnichts!
> Sonnst werden die Daten die ich zum L6470 sende einfach ignoriert.
> Ist das denn so überhaupt richtig? Im Datenblatt steht:
>
> After each byte transmission the CS input must be raised and be kept
> high for at least tdisCS in order to allow the device to decode the
> received command and put the return value into the SHIFT register.

Das ist in der Tat etwas ungewöhnlich, aber der Sinn wird auf der 
nächsten Seite klar: Daisy-Chaining. Solange CS low ist, wird einfach 
durchgeschoben, und zwar beliebig(!) weit. Ohne dass die einzelnen 
Slaves wissen müssen, an welcher Position sie in der Kette sind bzw. wie 
lang sie ist! Erst mit CS high weiß der Slave, dass die letzten 8 Bits, 
die er gesehen hat, für ihn bestimmt sind.

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


Angehängte Dateien:

Lesenswert?

A. B. schrieb:
> Das ist in der Tat etwas ungewöhnlich
Nicht unbedingt, und wenn man den SPI als das sieht, was er ist, dann 
wird das auch logisch erklärbar. SPI sind nur verkettete 
Schieberegister. Mit jedem Takt wird einfach das MOSI um ein Register 
weiter getaktet. Und die steigende Flanke des SS# sorgt dann dafür, dass 
man weiß, wann die Schieberei ein Ende haben soll. Man kann also 
vorher beliebig lange takten, es werden nur die letzten Bits des 
Datenstroms verwendet.

Andere Implementierungen nehmen die fallende Flanke des SS# und zählen 
ab dort jedes Bit mit und ordnen es einem internen Register zu. Dann 
kann man hinterher beliebig weitertakten, es werden nur die ersten 
Bits des Datenstroms verarbeitet.

tom schrieb:
> Aber es ist ja aus dem Logic Analyzer ganz eindeutig zu erkennen, das
> wirklich keine 1 als 7.Bit kommt.
Hältst du die Zeiten tsetCS und tdisCS ein?

: Bearbeitet durch Moderator
von tom (Gast)


Angehängte Dateien:

Lesenswert?

OK habe noch ein Screenshot vom Logic Analyzer mit /CS angehangen.

Das mit dem "Daisy-Chaining" macht ja dann auch Sinn das man jedes Mal 
das /CS Ein und Ausschalten muss. Dann habe ich es auf jeden Fall 
richtig verstanden und das Problem kann nicht mit dem ständigen /CS 
zusammen hängen.

von Holm T. (Gast)


Lesenswert?

...also für mich sieht schon das Diagramm komisch aus, da ändern sich 
die Daten auf MOSI ohne das auf dem Taktsignal ein Flankenwechsel 
erfolgt..

Normal kommt mir das nicht vor.

Gruß,

Holm

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


Angehängte Dateien:

Lesenswert?

tom schrieb:
> OK habe noch ein Screenshot vom Logic Analyzer mit /CS angehangen.
Offenbar verletzt du da bei jeder fallenden SS#-Flanke die 
Spezifikation. Denn bei der fallenden Flanke muss laut Datenblatt der CK 
"high" sein.

tom schrieb:
> Aber es ist ja aus dem Logic Analyzer ganz eindeutig zu erkennen, das
> wirklich keine 1 als 7.Bit kommt.
Und zwar niemals. Für mich sieht das nach falschem SPI-Mode aus...

: Bearbeitet durch Moderator
von tom (Gast)


Lesenswert?

Lothar M. schrieb:

> Hältst du die Zeiten tsetCS und tdisCS ein?

Die Zeiten wie im angehangenen Auszug aus dem Datenblatt sind auf 
jedenfalls nicht zu kurz. Für einen Takt werden Minimum 125nS (Anstieg, 
Halten, Abfall) benötigt ich habe hier 8uS für die HIGH Periode und auch 
8uS für den LOW Bereich.

Habe jetzt noch die Zeit nachdem /CS auf LOW geht und bevor ein 
Taktsignal erzeugt wird, ebenfalls auf 8uS verlängert. Bringt aber alles 
nichts. Das Bit7 wird einfach nicht vom L6470 rausgesendet...

Wenn ich keine Lösung dafür finde, lasse ich halt das Auslesen sein. Das 
Status Register lässt sich ja hervorragend auslesen ohne Probleme und 
das ist ja eigentlich auch das einzige was man dringend benötigt. Dann 
lasse ich halt den Befehl GET_PARAM sein, denn das Beschreiben der 
Register mit SET_PARAM funktioniert ja.

von tom (Gast)


Angehängte Dateien:

Lesenswert?

Lothar M. schrieb:

> Und zwar niemals. Für mich sieht das nach falschem SPI-Mode aus...

DANKE Lothar M.! Jetzt funzt es. Es lag tatsächlich nur an der 
Einstellung für den SPI Bus. Ich hatte zwar schon mal herumprobiert mit 
Taktflankenänderung und Phasenänderung, aber immer einzeln und nie 
zusammen.
Jetzt habe ich die Taktflanke Bit3 und die Phase Bit2 des SPI SPCR 
Registers gewechselt und siehe da, da kommt auch das Bit7 mit einer 1.

Habe mal den nun funktionierenden Screenshot angehangen.
Na gut, sollte noch jemand die selben Probleme haben, dann kann er sich 
ja hier dank Lother M. gut informieren.

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


Lesenswert?

tom schrieb:
> Es lag tatsächlich nur an der Einstellung für den SPI Bus.
Das kam mir schon gestern Abend als allererster Gedanke. Ich habe diesen 
Gedanken nur mangels Messdaten nicht laut ausgesprochen... ;-)

> Ich hatte zwar schon mal herumprobiert mit Taktflankenänderung und
> Phasenänderung, aber immer einzeln und nie zusammen.
Bei solchen Problemen (wie z.B. auch bei "versetzten Bits" auf dem Bus, 
oder wenn das letzte Bit auf das "nächste Byte wandert") hilft es, 
einfach mal systematisch alle 4 möglichen SPI-Modes nacheinander 
auszuprobieren:
http://www.lothar-miller.de/s9y/archives/15-SPI.html
In einer halben Stunde sieht man da viel.

> DANKE Lothar M.! Jetzt funzt es.
De nada. Und ebenfalls danke für die Rückmeldung.

: Bearbeitet durch Moderator
von Holm T. (Gast)


Lesenswert?

Hmm.. ich werde mich wohl in Lothar M. umbenennen lassen müssen..

Gruß,

Holm

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.