Hallo zusammen, ich bin gerade dabei eine SPI-Verbindung zwischen 2 UCs zu bauen. Der Atmga644 agiert als SPI-Slave (Interrupt-gesteuert). Der andere UC ist ein SPI-Master. Nun so weit funktioniert die Kommunikation. Ein Hacken ist noch dran und zwar, dass eine SPI-Master-Abfrage immer den vorletzten Wert liefert und nicht gerade den aktuellsten. Beispiel: Ich sende über den Master den Befehlt Get-ID = 0x0F. Der Atmega644 empfängt die Zahl 0x0F und soll mir die ID beispielsweise 0x12 zurückgeben. Das macht er so weit. Nun ändere ich die ID von 0x12 auf 0x15 und frage nochmals ab. Dann bekomme ich zunächst immer noch die 0x12 und bei einer erneuten Abfrage dann die 0x15. Das sieht so aus, dass beim Empfangen der Get ID = 0x0F eine Kopie des Dataregisters (SPDR) gemacht wird, die zunächst gesendet wird. Diese Kopie ist dann nicht der aktuelle Wert, der gesendet werden soll. Sondern Eins davor. Anbei der Inhalt des ISRs: ISR(SPI_STC_vect) { uint8_t spiByte = 0; uint8_t id = 0; SpiByte = SPDR; // Get Character while(!(SPSR & (1<<SPIF))); // Wait until transmission complete if (SpiByte == 0x0F) { id = id_get(); // Get device id SPDR = id; while(!(SPSR & (1<<SPIF))); // Wait until transmission complete } } Ich freue mich auf eure Vorschläge Gruß Charly
Vom_Arbeitsplatz schrieb: > Ich freue mich auf eure Vorschläge Vorschlag: Lies' endlich das verdammte Datenblatt.
Vom_Arbeitsplatz schrieb: > ISR(SPI_STC_vect) > { > uint8_t spiByte = 0; > uint8_t id = 0; > > SpiByte = SPDR; // Get Character > while(!(SPSR & (1<<SPIF))); // Wait until transmission complete > > if (SpiByte == 0x0F) > { > > id = id_get(); // Get device id > SPDR = id; > while(!(SPSR & (1<<SPIF))); // Wait until transmission complete > } > } Äh. Nein. Der Slave hat keine Kontrolle darüber, wann eine Übertragung stattfindet. Das liegt einzig und alleine im Kontrollbereich des Masters. SPI ist mehr eine Art Byte Austausch. Währned 1 Byte vom Master zum Slave wandert, wandert gleichzeitig 1 Byte vom Slave zu Master. Der Slave muss das zurückzugebende Byte schon im SPDR haben, wenn der Master den Byteaustausch ankurbelt. Das Modell, das ich gerne benutze, sieht so aus: Du sizt an einem Tisch, dir gegenüber dein Kumpel. Jeder von euch beiden hat einen Zettel Papier vor sich liegen. Auf DEIN Kommando hin, nimmt jeder sein Papier mit der rechten Hand und reicht es zu seinem Gegenüber rüber, der es mit der linken Hand nimmt und vor sich hinlegt. D.h. Wenn du das Kommando gibts, dann muss dein Kumpel schon den Wert, den er dir übermitteln will, auf dem Papier stehen haben! Denn während der Papier-Austausch läuft, hat er keine Chance mehr nachzubessern. Genauso musst du dir als Master eine Strategie ausdenken, wie du deinem Kumpel die Möglichkeit gibst, die von dir (per Anweisung auf dem Papier) angeforderte Information zu besorgen und rechtzeitig aufs Papier zu schreiben. Und nein. Dein Kumpel hat keine Chance den Transfer zu verweigern. Wenn du deine rechte Hand ausstreckst, dann muss er das ebenfalls tun. In deinem Fall: Jedesmal, wenn du den rechten Arm ausstreckst, und nachdem die Zettel ausgetauscht sind, wird die ISR aufgerufen. Das ist das Szenario, wie SPI funktioniert. Der Slave kann von sich aus nichts senden. Er muss auch nicht warten, ob eine Übertragung abgeschlossen ist. Er muss nur dafür sorgen, dass beim Erhalt einer Anfrage, im SPDR die gewünschte Information verfügbar ist, wenn sich der Master mit einem weiteren Austausch die gewünschte Information abholt. Und der Master muss dem Slave auch die Zeit zugestehen, diese Information zu besorgen.
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.