Hallo zusammen, ich habe ein paar Fragen zu SPI und hoffe, jemand kann mir helfen: Aufbau: 3 ATMEGA8 AVR1 AVR2 AVR3 ---- --------- --------- | 1|-MOSI-->-|.SI SO|-MISO-->-|.SI SO| | |-SCK--->-|SCK CK|-SCK--->-|SCK CK| | |-PB0--->-|CS | | | | | | PB0 |------>--|CS | ---- --------- --------- | UART <- hier kommen die Daten rein. Jetzt möchte ich in den 1. AVR daten reinschreiben (ca. 100 x in der Sek.), zb. 11 12 13 21 22 23 31 32 33 0. Der 1. AVR muss die ersten 3 bytes weiterverarbeiten und dem AVR2 die bytes ab 21 weiterleiten. Dann analog dazu AVR2 zu AVR3 das selbe. So dass bei dem AVR3 nur 31 32 33 0 rauskommt. Wie realisiert man dieses? Ich habe das Ganze ungefähr wie oben am laufen mit HW SPI zum einlesen in einem Buffer, Buffer verarbeiten, ersten 3 bytes rausnehmen und per SOFT-SPI raus (z.b wie auf Beitrag "SPI per Software"). Anders habe ich das nicht hinbekommen. Gibt es andere und elegantere / performantere Wege dafür`? Vielen Dank Yatko
> So dass bei dem AVR3 nur 31 32 33 0 rauskommt. Müsste nach o.g. Schema beim 3er nicht "nur 0" rauskommen? > Wie realisiert man dieses? Ich würde alles in einen Buffer schreiben, bis die 0 erkannt wird. Danach ab Stelle 4 bzw. Index 3 bei einem Array bis zur 0 weitergeben an den nächsten AVR. Allerdings musst du entweder einen Zähler mitlaufen lassen, der prüft wieviele Bytes im Buffer sind bzw. weitergegeben werden müssen, oder du musst vor dem Weiterleiten prüfen, ob das erste Zeichen im Buffer 0 ist. Ralf
Hi Ralf, danke für deine Antwort. Es kommt schon 31 32 33 0 bei dem letzten raus. AVR1 nimmt die 3 Bytes die mit 1 anfangen, AVR2 die mit 2 usw.. Es klappt ja auch soweit, nur wenn ich die Bytes weiterleite, entsteht durch BinBanging (so nennt sich Soft SPI glaube ich) extremer delay welche die laufenden soft-PWMs dann stören. Mit HW empfangen geht ohne Probleme. Mein Problem ist eigentlich, wie kann ich nur einen Teil des Buffers über HW-SPI weiterleiten und nicht per Soft SPI .. Im Beispiel oben mit den ersten fehlenden 3 Bytes. Achja, die 0 ist als Trennzeichen zu verstehen, sobald eine 0 empfangen wird, wird der Buffer abgearbeitet und weiterverschickt.
Macht der AVR 2 mit den Daten für AVR3 nur das weiterleiten ? Hast du auf AVR 1 noch einen Pin Frei ? Kannst du beide Fragen mit JA beantworten, dann weg mit der SoftSPI und verbinde AVR 2 und 3 mit der HW SPI an AVR 1. Falls nein würde ich den dem Fall die AVR 2 und 3 in eine Kette hintereinander schalten und einfach die Bytes durchtakten. Dann müssen nur beide AVR alle Bytes empfangen und sich die eigenen raus suchen.
Hallo Ralph, AVR2 nimmt sich die ersten 3 Bytes, und leitet den Rest an AVR3 weiter. Das heißt die Daten werden verändert weitergeschickt. Geht das mit HW SPI? Oder macht man das anders? Eventuell müsste vielleicht der Slave auf Master geschaltet werden und dann die Daten weiterleiten. Hierbei befürchte ich aber Kollisionen, falls 2 hintereinander geschaltete AVRs gleichzeitig Master sein wollen. So wie ich SPI verstehe, kann man keine Daten verändern, sondern nur durchschieben. Und zwar immer nur ein Byte unterschied zu dem davor. Ich wollte X Slaves ohne Setup einfach anschließen und es sollte laufen. Im Prinzip das selbe wie LPD6803 oder WS2801 (RGB IC's mit PWM). Vielleicht sollte ich meine Frage anders stellen: Wie kann man LPD6803 oder WS2801 mit einem AVR nachbilden? Sorry, wenn ich mich zu kompliziert ausgedrückt habe. :) LG Y
Also ich würde es so machen; Master ist AVR 1 : AVR 1 MOSI an AVR 2 SIMO AVR 2 MOSI an AVR 3 SIMO AVR 3 MOSI an AVR 1 SIMO AVR 1 CLK an AVR 2 und AVR 3 Alle CS zusammenschalten und dann alle Bytes vom Master aus durchtakten. Jeder Slave liest alle Bytes in einen internen Puffer. Dann sucht sich jeder Slave aus dem Puffer die eigenen Bytes raus. Damit taktest du einmal alles durch und jeder AVR hat seine Daten. Jederzeit erweiterbar, es ändert sich nur die Zahl der Bytes. Ideal mit festem Protokoll. Zb. Byte 1 - 5 ist an AVR 2 Byte 6 - 10 ist an AVR 3 Byte 11 - 15 wäre dann AVR 4 . . . Und jeder Slave brauch dann nur die bytes zu zählen und die eigene lesen die anderen verwerfen. Dementsprechend legt der Slave in die ihm zugeordneten Bytes seine Ausgangsdaten rein, die damit zurück zum Master gehen.
Danke! Ralph schrieb: > Und jeder Slave brauch dann nur die bytes zu zählen und die eigene lesen > die anderen verwerfen. > Dementsprechend legt der Slave in die ihm zugeordneten Bytes seine > Ausgangsdaten rein, > das ist gar nicht so einfach. irgendwelche vorschläge in C? pseudocode würde es auch tun. die slaves sollen dabei immer den gleichen code bekommen ohne irgendwelche parameter einzustellen. an welcher stelle der slave gerade ist sollte ausgerechnet werden, wenns geht... > die damit zurück zum Master gehen. muss man überhaupt zurück zum master? wenn ja, warum? der braucht die daten eigentlich nicht, oder ?
Rückantwort zum Master könnte zb die Bestätigung des Empfang und
Bearbeitung der Daten.
Struct anlegen die alle TX Daten enthält.
zb:
struct
{
U8 AVR2_Byte1;
U8 AVR2_Byte2;
U8 AVR2_Byte3;
U8 AVR2_Byte4;
U8 AVR3_Byte1;
U8 AVR3_Byte2;
U8 AVR3_Byte3;
U8 AVR3_Byte4;
}
Jetzt muss jeder µC nur wissen da in der Struktur 4 Byte für ihn sind.
Der erste Empfänger nimmt dann die ersten 4 Bytes aus dem Empfangsbuffer
der SPI in seinen Datensdtruktur.
Der zweite Empfänger nimmt die Bytes 5 bis 8.
Beliebig erweiterbar.
Wird eine Rückantwort vom slave benötigt geht es genauso.
Der erste Slave legt in Bytes 1 - 4 seine Antwort , der 2.Slave in Bytes
5 - 8.
Der µC muss nur wissen an welcher Position in der Kette er steht.
Wird keine Rückantwort gegeben, könnte zb der erste Slave die 4 Bytes
mit einem Wert füllen den der 2. erkennt. Falls zb der Wert 0xFF bei dir
kein gültiger Wert ist, könnte dieser Wert in Bytes 1 - 4 geschrieben
werden.
Sobald dann der Slave x die ersten Bytes sieht die nicht 0xFF sind, wei0
er das dies sein Block in der structur ist.
Aber für sowas gibt es beliebig viele Möglichkeiten.
Vielen Dank Ralph, Du hast mir sehr geholfen (unter anderem auch SPI ein wenig zu verstehen :). War ein langes Wochenende... jetzt geht aber alles so wie soll... nun ab zum Codetuning und aufräumen :) LG und schöne Woche. Y.
SPI-Gast (Yatko) schrieb: > Gibt es andere und elegantere / > performantere Wege dafür`? Ja. Einfach SCK an jeden Slave und immer MOSI an MISO kaskadiert. Vorzugsweise sind die ersten Bytes für den letzten Slave, da ja das SPI die Daten um ein Byte verzögert durchschiebt. Peter
ein frage hätte ich noch: wie kann man am sinnvollsten feststellen, ob der serielle transfer im z.b. AVR2 durch ist? Also AVR2 muss es selber wissen, damit die daten bearbeitet werden können. Schauen ob PB2 (SS) auf high ist? Kann man das per interrupt auch rausfinden? also, mein transfer findet so statt (vom Master aus gesehen): - ziehe PB0 auf LOW (verbunden mit SS Slave) - sende alle daten (z.b. 48 bytes) - ziehe PB0 auf HIGH (verbunden mit SS Slave) ich habe das gefühl, dass der INTR bei jedem byte ausgelöst wird. kann das sein?
Yatko Jaens schrieb: > ich habe das gefühl, dass der INTR bei jedem byte ausgelöst wird. kann > das sein? das sollte auch so sein. Sobald ein Byte im RX Puffer der HW SPI liegt gib es einen Interrupt um das Byte abzuholen. Die Logik im Empfänge muss dann entscheiden welches der Bytes gebraucht werden und welche nicht.
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.