Hallo zusammen. Ich betreibe einen ATMega als SPI Slave. Dieser Slave bekommt über die SPI-Schnittstelle ein Kommando vom Master (auch ein ATMega). Darauf stellt er nach einer nicht genau bekannten Zeit die gewünschten Daten bereit. Jetzt könnte der Master nach Absenden des Kommandos natürlich einfach eine Zeit lang warten, die für alle Fälle lang genug ist und dann die Daten vom Slave einlesen. Wenn ich aber die Daten schnellstmöglich benötige, wäre es besser, wenn der Slave dem Master mitteilen könnte, wenn die Daten bereit stehen. Dazu könnte der Slave eine zusätzliche Interruptleitung zum Master verwenden, ich würde aber gerne auf eine zusätzliche Leitung verzichten. Würde es funktionieren dass der Slave die MISO Leitung manuell kurz auf einen anderen Pegel zieht und damit dem Master signalisiert dass jetzt gelesen werden kann? Schaltet sich dadurch der SPI Port ab? Oder geht das noch einfacher? Grüße, stero
Das klingt nicht nach einer besonders schnellen Verbindung. Mach doch I2C draus. Lass den anderen Atmega als I2C-Slave laufen und hinterlege in der ersten Zelle ein "Data Updated", das zwischendurch vom Master gepollt wird. Ist der Slave fertig und das Bit ist da, wird einfach der Rest ausgelesen. Der Slave kann bei I2C auch die Taktleitung unten halten und so signalisieren, dass er noch nicht bereit ist. Es gibt ne Menge I2C-Master Libraries die du frei konfigurierbar auf alle möglichen Pins anwenden kannst. Die kannst du auch so modifizieren, dass dein Programm weiterläuft, bis der Slave die Clock-Leitung wieder loslässt. Oder eben die erste I2C-EEPROM-Zelle pollen.
Stephan R. schrieb: > Würde es funktionieren dass der Slave die MISO Leitung manuell kurz auf > einen anderen Pegel zieht Das kann er nicht. Solange die Pins dem SPI gehören, lassen sie sich nicht mehr direkt setzen. Der SPI-Slave Mode der AVRs ist einfach nur Schrott. Sogar die 8051-er von Atmel können es besser. Da ist das SPI gepuffert, d.h. man hat eine Byte-Zeit Zeit, um das nächste Byte in den Puffer zu stellen. Und da man auch 4 Interruptprioritäten hat, ist das kein Problem. Peter
Wie bei SDCs: master fragt über SPI ständig ab, solange slave nicht fertig ist, sendet er 0xFF. Dabei darf dann natürlich das erste Nutzbyte nicht den Wert 0xFF haben, sollte aber kein Problem sein.
Solange der Slave nichts ins Transferregister reinschreibt steht dort das drin, was der Master zuletzt reingeschrieben hat. Das gilt auch für mögliches Polling. Nur muss der Master dem Slave Zeit geben, zwischendurch mal auf das Register zugreifen zu können, da kein Pufferregister existiert und der Slave folglich während eines laufenden Transfers nicht rankommt.
der alte Hanns schrieb: > Wie bei SDCs: master fragt über SPI ständig ab, solange slave nicht > fertig ist, sendet er 0xFF. Eben das geht beim AVR nicht, da kein Puffer! Was ist ein SDC? Peter
Wenn der Master als letztes Byte seines Kommandos 0xFF sendet, und beim Polling ebenfalls, dann kriegt er solange 0xFF zurück, bis der Slave mal etwas anderes reinschreibt.
A. K. schrieb: > bis > der Slave mal was reinschreibt. Und genau das kann er nicht, wenn der Master hintereinander ausliest. Der Slave kriegt ständig nur Write-Collision. Der Master muß Pausen machen! Peter
Yep. Das hatte ich 10:07 auch schon geschrieben.
Vielen Dank für die vielen Ideen und Hinweise. Die Lösung mit dem Pollen des Slaves mit 0xFF und zeitlichen Lücken für den Slave zum Einschreiben einer Antwort scheint mir die sauberste Lösung. Die schnellste Lösung ist vielleicht den SPI-Port in Master und Slave abzuschalten und dann seitens des Slaves über einen Pegelwechsel auf der MISO-Leitung (die ja jetzt keine SPI Funktion mehr hat) zu signalisieren, dass Daten bereitstehen. Der Master pollt bis dahin den Pegel auf der MISO-Leitung. Bei Pegelwechsel wird dann SPI in Master und Slave wieder aktiviert und die Daten übertragen. Wenn man nicht pollen möchte, könnte man sicherlich auch den Pin-Change-Interrupt des MISO Pins im Master verwenden. Seht ihr da Probleme die ich nicht sehe? Grüße stero ___________________________ Hier zur Info ein Auszug aus der SPI-Bibliothek zum Öffnen und Schließen der SPI-Schnittstelle: void SPIClass::begin() { pinMode(SCK, OUTPUT); pinMode(MOSI, OUTPUT); pinMode(SS, OUTPUT); digitalWrite(SCK, LOW); digitalWrite(MOSI, LOW); digitalWrite(SS, HIGH); SPCR |= _BV(MSTR); SPCR |= _BV(SPE); } void SPIClass::end() { SPCR &= ~_BV(SPE); }
Umschalten is schon ne gute Idee. Pollen musste da aber nix. Master wird zum Slave und Slave zum Master. Hat der ex Slave die Dwten fertig, werden die rübergewqckelt und der ex Master bekommt nen SPI fertig Interrupt. Klappt natürlich nur wenn nix weiter am SPI rumhängt.
Hallo Martin, > Master wird zum Slave und Slave zum Master. > Hat der ex Slave die Dwten fertig, werden die rübergewqckelt und der ex > Master bekommt nen SPI fertig Interrupt. > > Klappt natürlich nur wenn nix weiter am SPI rumhängt. Da sind schon noch weitere SPI-Slaves angebunden. Die sollten aber doch eigentlich hochohmig sein und so keinen Einfluß haben, wenn sie mit Slave Select nicht aktiviert sind, oder? Dann wäre das meiner Meinung nach die beste Lösung, bei der man sich das pollen sparen kann. Einziges Problem was mir im Moment einfällt wäre eine Pegel-Kollision mit dem ISP-Anschluß (zum Programmieren), der ebenfalls an diesen SPI-Leitungen hängt. Fällt Euch was kluges dazu ein? Grüße, Stephan
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.