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...
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
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?
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!
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.
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
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.
...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
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
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.
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.