Hallo zusammen, ich habe hier ein kleines Problem mit meinem SPI. Zur Hardware: ATmega8515 @ 10MHz auf dem STK500 (Master) verbunden über ca. 15cm lange Kabel/Leiterbahnen mit einem ATmega48 @ 20MHz (Slave). SPI-Takt liegt bei 2.5MHz Das Problem: Der Master überträgt alle 1ms je 2 Dummy-Bytes (0x00) an das Slave welches mit abwechselnd 0xFF und 0xAA antwortet. Da ja immer 2 Byte übertragen werden müsste ich am Oszi ja "festes Bild" bekommen, doch leider ist dem nicht so. Die beiden Byte tauschen immer hin und her. Ich bin der Sache mal auf den Grund gegangen und habe festgestellt, dass der ATmega48 (Slave) gelegentlich, so 1-2mal pro Sekunde, das Erste der beiden Bytes nicht sieht und weder 0xAA noch 0xFF sendet. Der Pegel auf der MISO-Leitung bleibt einfach auf low. Beim Slave ankommende Bytes haben aber keine Fehler, es wird nur eben gelegentlich mal eins komplett ausgelassen. Nun Frage ich mich woran das liegen kann? Das SPI-Signal am ATmega48 ist eigentlich sehr sauber. Bis auf kleine Schaltspitzen ist das Signal auf #SS, MOSI und CLK sehr sauber und unverrauscht. Versuchshalber habe ich auch schon [1..5]µs Delay zwischen Slave-select und erstem clk-pulse durchprobiert, ohne Erfolg. Habt ihr vielleicht ne Idee wo ich mal ansetzen kann um dem Fehler auf die Spur zu kommen? Ich bin gerade etwas Ratlos. Vielen Dank lg Leo
Auf dem Slave wird ein Interrupt ausgeloest ? Oder arbeitet der Slave mit Pollen ? 1)Verwende doch mal einen extra pin am Master, und das senden zu signalisieren. Dann den SCLK und diesen Pin auf das Scope. Trigger auf den einen und den anderen. Sind die immer gleichzeitig ? 2)Verwende einen extra pin am Slave um den Empfang zu signalisieren. Dann den SCLK und diesen Pin auf das Scope. Tiggere au den einen und auf den anderen. Kommen immer beide miteinander ? Ich wuerd mal auf Software tippen.
Also da der #SS-Pin ja das Slave selektieren soll wird dieser vor jeder Übertragung auf low gezogen. Dann passiert ca. 0.8µs nix und dann rattert der CLK-Pin seine Takte fürs erste Byte raus. Anschließend ist ca. 5µs pause (hab ich so programmiert, damit das Slave später mal sicher genug Zeit hat das richtige Byte in den Puffer zu legen und anschließend rattert ein weiteres Byte am CLK-Pin. Zu guter letzt wird das Slave wieder deselektiert (#SS-Pin auf high). All das habe ich so gemessen. Am Slave führe ich den STC-Interrupt aus (Serial-Transfer-Complete) habe dort versuchshalber auch schon einen Debug-Pin auf High-Level ziehen lassen, solange der Interrupt aktiv ist. Resultat wenn die Übertragung klappt: #SS-Pin auf low, Pause, CLK-Rattert und dazu die Daten auf der MISO-Leitung, ca. 0.2µs Pause, Dann der Debug-pin für ca. 0.6µs auf high, ...<2. Byte nach den 5µs>..., #SS-Pin auf high, Interrupt und ende der Übertragung. Wenn das Byte allerdings verloren geht wird der Interrupt auch nicht ausgelöst/der Debug-Pin nicht auf high gezogen. Der ATmega48 (Slave) verhält sich dann wie wenn er sich nicht angesprochen fühlt oder die CLK-Takte nicht sieht. Mir fällt allerdings gerade auf, dass sich der kleine AVR regelmäßig in einem anderen Interrupt etwas länger (ca. 10-15µs) aufhält. Aber warum sendet er dann das eine Byte nicht, welches ja schon vom Interrupt zuvor (welcher definitiv ausgeführt wurde, zwischen 2.Byte und 1.Byte hat er immer locker 900µs lange Weile) im Puffer liegt. Es müsste ja dann immer das 2. Byte schrott sein wenn er seinen Interrupt zwischen 1. und 2. Byte nicht ausführen kann...
Also. Dann nimm einen freien Pin am Slave und signalisier den Zustand. zB wenn er in dem anderen Interrupt ist. Oder zb Hoch, wenn er im Hauptprogramm ist. Dann vergleich wann die Meldung verloren geht.
Jo werd ich wohl mal noch genauer Debug-Outputten müssen. Stand nur wohl etwas auf dem Schlauch, da hätte ich ja auch drauf kommen können... Nun gut. Schlafen gehen und bei etwas freier Zeit nochmal dran setzen. Danke Dir aber. Ich berichte. lg Leo
Die AVRs haben keinen Sendepuffer. Beim Master ist das nicht schlimm, aber als Slave sind die AVRs praktisch unbrauchbar. Sendet der Master 2 Bytes hintereinander, muß er dazwischen eine Gedenkpause einlegen. Peter
Ich habe das Schieberegister großzügig als "Puffer" betitelt...
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.