Hallo, ich habe mir in den vergangenen Tagen schonmal Hilfe im GCC-Forum geholt. Leider konnte mir eine Frage nicht beantwortet werden, sodass ich mich mit dem Problem nochmal an Euch wende. In der angefügten Datei habe ich den Quelltext für Sklave- und Mastercontroller angehängt. Folgende Sache klappt bisher: - Master löst via Timer-ISR eine SPI-DÜ mit Inhalt 0xAA raus + Timer-Reload + /SS=0 + SPDR mit 0xAA laden - Master SPI complete ISR + /SS=1 - Sklave nur Datenempfang (DDRB=0x00) - Sklave SPI complete ISR + Ausgabe des Datenframe von Master (PORTC = SPDR) Jetzt wollte ich gerne einen Datenframe von Sklave an den Master zurückschicken und habe folgende Änderungen/Zusätze (wie im Anhang) gemacht: - Sklave: + in der SPI complete ISR vorm Auslesen den zu sendenden Frame setzten: <c> //SPI transfer complete ISR(SPI_STC_vect) { SPDR = 0x04; //return 0x04 to master PORTC = SPDR; //reading SPI-data } </c> - Master: + in der SPI complete ISR Sklave auslesen <c> //SPI transfer complete ISR(SPI_STC_vect) { PORTB |= 0x01; // /SS=1 PORTD = SPDR; //data from sklave at PORTC } </c> Weiterhin habe ich die Portrichtung des PORTB des Sklave auf DDRB=0x40 (MISO Output) gesetzt. Durch diese Änderung klappt die DÜ Master->Sklave nicht mehr. Hat jemand eine Idee? Mfg Thomas
Hi, ich wuerde es alles ein kleines bischen anders loesen. 1. Master: sendet Commando. 2. Slave: Wartet auf SPI Interupt (1 Byte komplett), setzte ein status_flag fuer komplett. 3. Slave: Main Routine fragt dieses Flag ab, wenn das Flag gesetzt werte das Commandobyte vom Master aus und legt den Rueckgabewert in SPDR. 4. Master sendet 1 Byte und prüft danach das SPDR auf den Rueckgabewert. Hoffe es reicht soweit aus, ansonsten habe ich zu Hause noch ein kleines Master Slave Beispiel. Muss der Slave bei Dir unbedingt die Masterrolle uebernehmen? Gruß, Dirk
Der Sklave soll eigentlich keine Masterroller übernehmen. In meinem Beispiel arbeitet der ATMEGA128 alleinig als Master, der zyklisch eine Nachricht an den Sklave schickt. Gleichzeitig soll der Sklave einfach nur 1 Byte zurückschicken und eben das klappt nicht. Sobald ich die Portrichtung der MISO-Leitung des ATMEGA32 auf Ausgang setze, geht nix mehr. Viele Grüße Thomas
Hi, der SPI Bus ist ein Schieberegister mehr nicht. Du musst schon vom Master ein Byte senden zum Slave damit der Master was im SPDR Register vom Slave erhaelt. Bei bedarf poste ich nen kleines Beispiel. Gruß, Dirk
Genau das mache ich doch, oder? (1) Im "Leerlauf" lädt Master als auch Sklave ein Byte in den SPDR (2) Master schickt ein Byte an Sklave (3) beim kompletten Empfang auf Sklave-Seite wird dort eine ISR aufgerufen und das "Masterbyte" ausgelesen Bisher geht die Datenübertragung vom Master zum Sklave (wenn MISO-Pin beim Sklave auf 0x00) aber nicht vom Sklave zum Master. Dabei ist mir folgendes Problem aufgefallen. Sobald ich die Portrichtung (PORTB) am Sklave so setze, dass das MISO-Pin als Ausgang (DDRB=0x40) geht auch die DÜ zum Sklave nicht mehr. Kann es sein, dass die Verdrahtung MISO/MOSI "kreuzweise" gemacht werden muss. Beispiel würde mich auch freuen. Obwohl ich im ersten Posting ja schon einen Quelltext verlinkt habe. Mfg Thomas
SPI geht nur vom Master zum Slave. MOSI auf MOSI, MISO auf MISO, SCK auf SCK. Willst du was zum Master senden muß der Master dem Slave ein Byte schicken. Willst du davon unabhängig sein, mußt Du ein Multimaster programmieren. Oder du missbrauchst den SS Eingang als Sendeanforderung zum Master wobei dann vom Slave die Daten zum Master übertragen werden.
Erstmal vielen Dank für die Antworten. Mir ist das Prinzip schon klar. Ich habe aber genau hier das Problem der praktischen Umsetzung. Ich habe ja extra meinen Quellcode im 1.Posting angehängt, damit ich eine Lösung für mein Problem erhalte. Dort ist der Master ein ATMEGA128 und der soll es auch bleiben. Er schickt aller einer Sekunden ein Byte an den Sklave und dieses zeigt der Sklave schön brav an PORTC an. Als Ergänzung wollte ich jetzt gerne, dass der Sklave bei jeder Master-Übertragung ein beliebiges Byte (z.B. 0xAA) auf der MISO-Leitung legt. Hierfür muss ich aber das SPI-Port (PORTB) so initialisieren, dass die MISO-Leitung (PB6) als Ausgang geschalten ist. Sobald ich diese Änderung auf dem Sklavecontroller compiliere und in den Flash speichere, geht die Datenübertragung garnicht mehr. (Master-Byte wird auf Sklave nicht mehr an PORTC ausgegeben). Gibts dafür eine Erklärung? Mfg Thomas
Hallo ich habe das selbe Problem. Ich kann auf der Seite des Slave ein Byte ins SPDR schreiben, aber die Daten werden nicht bei der nächsten Übertragung gesendet, sondern lediglich das alte Byte das vorher Empfangen wurde. Verwendeter Controller ATMega64. Also das selbe Problem. Scheinbar hat der Controller einen Bug, oder das Datenblatt ist fehlerhaft. Laut Datenblatt soll man den zu senden Wert in das SPDR Register schreiben bevor man das empfangene Byte ausliesst. Aber egal in welcher Reihenfolge ich das mache, es tut nicht. Der Empfang vom Master klapt dagegen problemlos.
Noch mal zur Ergänzung. Das Ganze verhält sich so, als ob der Schreibzugriff auf das SPDR keine Wirkung hat. Die alten Daten bleiben erhalten und werden auch wieder raus geshiftet. Also MISO MOSI CLK funktionieren. Das ganze betrifft scheinbar nur den Schreibzugriff auf das SPDR im Slave Modus. Kennt jemand das Problem?
Hallo noch eine weitere Eingrenzung der Frage. Kann es sein, dass wenn /SS auf low liegt und der Slavemode aktiv ist (MSTR = 0), nicht auf das SPDR geschrieben werden kann? Blöderweise liegt bei mir /SS hart auf GND. So kann ich das nicht mal auf die Schnelle testen. Das Datenblatt lässt dieses Frage leider offen.
So bei mir war der Grund, dass das letzte Byte noch nicht komplett eingeschoben war, bzw es gab eine Überschneidung beim letzten empfangenen Bit und dem zu senden Bit. Die Lösung ist, das SPI Interface abzuschalten. Die Daten aus dem SPDR zu retten, die zu sendenen Daten reinschreiben und das Interface wieder einschalten. Das ist zwar eine Vergewaltigung der Schnittstelle aber es funktioniert. So long.
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.