Hi,
ich bin ein bischen am Verzweifeln weil ich nicht wirklich weiterkomme
:(
Ich versuche eine einfach kommunikation zwischen einem ATxmega
128A3(slave) und einem atmega8515(Master) auf dem STK500 Board
aufzubauen. (Hardwaretechnisch alles 5 mal kontrolliert und
leitungslängen liegen ca bei 8 cm )
Ziel ist es erstmal nur ein Reg. hin und herzuschicken und mit jedem
Umlauf zu inkrementieren und an den 8 LEDs auszugeben ( mit bischne zeit
zwischen dem senden damit ich was sehe :D )
ich schicke mal den code schnipsel des Masters und des Slaves mit , ich
hoffe einer von euch kann da schon einen Fehler entdecken:
Slave (xmega128A3)
Es geht nicht um ASM oder was anderem, sondern ob man die SPI verstanden
hat. Das ist hier nicht der Fall.
Die Frage bleibt : Wie liest der Master von der SPI Schnittstelle?
Hi,
danke schonmal für die Antwort. Ich muss leider ehrlich gestehen ich
weis nicht wodrauf du hinauswillst.
Grundlegend kann der Master nicht gleichzeitig senden und empfangen,
dass das Senden abgeschlossen ist, fange ich ja mit dem Inter. Flag ab
?! Muss ich nun das Gleiche beim Empfangen machen (erst ausgeben nach
abfrage)?
Ich habe mir das Datenblat nochmal durchgelesen und einige PDF´s zu SPI
ich bin aber anscheinend zu blöd oder ich suche nach dem falschen Ansatz
um mein Problem den mir vorliegenden Informationen zu lösen.
Wenn du vieleicht konkreter werden könntest was ich suchen muss wäre das
nett :)
grüße
J.
hilfe_suchender schrieb:> Grundlegend kann der Master nicht gleichzeitig senden und empfangen...
Doch, genau das ist der Trick an SPI - es wird sychron gesendet und
emfangen. Es gibt daher auch keine getrennten TX und RX Interrupts.
Die während des Sendens am DataIn anliegenden Daten landen nach
Abschluss des Vorgangs im RX-Register.
@Dumpf Backe (Gast)
>Die Daten ins SPI Register zu schreiben ist eine Sache.>Die Frage ist wer bringt den Clock und wie bringt er den Clock ?
Der Master. Das passiert automatisch beim AVR, wenn man ein Byte in SPDR
schreibt, dann wird die Übertragung incl. Takterzeugung automatisch für
ein Byte gestartet. Wie beim UART, nur mit Takt.
Ich will das ja verstehen , dafür bin ich hier !
ich habe nochmals im Datasheet geguckt :
"When configured as a Master, the SPI interface has no automatic control
of the SS line. This must be handled by user software before
communication can start. When this is done, writing a byte to the SPI
Data Register starts the SPI clock generator, and the hardware shifts
the 8 bits into the Slave."
so für mich heißt das "clear SS schreib ins data-reg und er macht alles
allein und setze wieder SS " :D
anscheinend bin ich da auf dem Holzweg :(
hilfe_suchender schrieb:> liegt der Fehler denn im Master oder im Slave ?
Stimmt, Du hast 2 Baustellen gleichzeitig auf.
Ich würde daher erstmal den Master mit einem 74HC595 testen
(RCLK = /SS).
wie ? weiter .. :D
ich dachte dies habe ich so umgesetzt ^^
"After shifting one byte, the SPI clock generator
stops, setting the end of Transmission Flag (SPIF)"
den habe ich auch abgefragt glaube ich ..^^
"The last incoming byte will be kept in the Buffer Register for later
use."
und ja da steht für mich das der letzte reingekommene Wert im
Dataregister steht
Peter Dannegger schrieb:> Stimmt, Du hast 2 Baustellen gleichzeitig auf.>> Ich würde daher erstmal den Master mit einem 74HC595 testen> (RCLK = /SS).
ja da hast du recht...
aber nu weis ich schon wieder nicht was ein 74HC595 ist ;)
>"The last incoming byte will be kept in the Buffer Register for later
use."
und ja da steht für mich das der letzte reingekommene Wert im
Dataregister steht
Ja. wenn es denn hereinkommt. Und wie kommt es herein ?
Der 74HC595 ist insofern wichtig, als man sich einen SPI Master und
slave mit je einem 74HC595 selber basteln kann. Und wenn man diese zwei
verbunden begriffen hat ist alles trivial.
hilfe_suchender schrieb:> aber nu weis ich schon wieder nicht was ein 74HC595 ist ;)
Google hilft.
Ist ein Ausgaberegister (SIPO).
Man kann bis zu 8 LEDs ranhängen und dann schauen, ob sie wie erwartet
reagieren.
Ein Eingaberegister (PISO) wäre der 74HC165.
Da ich nicht weiterkomme mit 2 baustellen könnte ich eigentlich
prinzipiell auf dem xmega ( der hat ja mehrere spi schnitstellen )
master und slave implementieren und damit rum testen ?
>>>Über das Dataregister vom Slave ( MISO-Leitung ) würde ich so spontan
behaupten
>>Mit welchem clock ?>Mit der Master clk , in meinem Fall SPR1=0 SPR0=1 --> f_osc/16
Aber wie kommt die Clock raus? Clock ist ja kein CW signal, das immer
kommt.
Auf einem XMega geht's nicht schneller.
FOsc/16 is etwas schnell... weshalb ist bald klar.
Der Slave hat also ein Datenbyte empfangen, und gelesen. Dann macht er
etwas und kann als einzige Moeglichkeit wieder ein Datenbyte in die SPI
schreiben. Wie kommt das Byte nun an den Master ?
Loesen wir's doch auf. Der Master liest von einem Slave, indem er ein
dymmy-Write macht. Schreibe 0x00 und der Slave bekommt den noetigen
Clock. Wann sollder Master den Write machen? Na. Wenn der slave fertig
ist.
Ganz ehrlich ich verstehe nicht was ihr meint :( ich habe doch auf dem
Master eine Schleife fertig gemacht in der ich ständig den akuellen Wert
inkrementiere und wieder sende. Warum muss ich nun ein Dummy Wert
nochmal senden ?
1
LOOP:
2
rcall WAIT_1s ; 1s PAUSE
3
4
inc SENDE_DATA ; +1
5
mov temp, SENDE_DATA ; KOPIEREN nach TEMP
6
7
rcall SPI_SENDEN ; SPI SENDENINP:TEMP
8
rcall SPI_SPSR_AUSWERTEN ; SPSR-Rgister auswerten
9
rcall SPI_EMPFANGEN ; SPI EMPFANGEN OUT: TEMP
10
11
rjmp LOOP
habe jetzt noch kurz eine WCOL abfrage dazwischen gehauen
warten -> ss low senden (bis SPIF 1 ist) ss high -> WCOL abfragen ->
empfangen
und das ganze in einer Loop damit ich eine dauerhafte Komunikation habe.
Ich bin froh wenn man versucht mir zu helfen, aber ich verstehe ehrlich
gesagt immernoch nicht was eigentlich falsch läuft bei mir, weil aus
Antworten die mir gegeben werden größtenteils Fragen werden... sry aber
diese Art der Hilfe bringt mir momentan nicht viel ;)
Dampf Backe schrieb:> FOsc/16 is etwas schnell... weshalb ist bald klar.
warum zu schnell ? mein xmega läuft mit 32MHz und der 8515 mit default
einstellung ( wies grad nicht wieviel das ist aber auf jedenfall weit
unter dem XMega.)
>Dampf Backe schrieb:> FOsc/16 is etwas schnell... weshalb ist bald klar.
Naja. Der Slave muss den Wert rausziehen, irgendwas damit machen und
dann kommt schon der Naechste. Da ist null Buffer dazwischen. Ein
Interrupt mit push & pop, call & ret verplemert schon 8 oder so takte.
Und wenn da nur 16 Takte dabei sind wird's eng.
Empfangen liest das Byte aus dem SPI input buffer. Es ist aber noch im
outputbuffer des Slaves. Und muss erst ruebergeclockt werden.
Egal, schau's dir an, das waren die tips.
Gut kein problem machen wir des Ding langsamer hab nun 1/128
Das ändert nicht daran das ich immernoch nicht verstehe was du meinst,
da ich doch nach jedem senden, wieder sende ( loop ?!?!?!?! ) und somit
den letzten Wert aus dem Slave raus clocke , warum ist es so schwer wenn
man mir schon helfen will eine präzise Antwort zu geben :(
Was nutzt eine präzise Antwort, wenn du sie - aus welchem Grund auch
immer - nicht verstehst?
Wenn ein Sendevorgang abläuft (MOSI, CLK) ist damit unweigerlich exakt
zeitgleich über MISO und CLK auch ein Empfangsvorgang gekoppelt.
Oder etwas ausführlicher
Wenn man etwas sendet wird zwangsläufig auch empfangen. Ob man die
empfangenen Daten auch benötigt und auswertet hängt vom Slave ab.
Das Empfangsregister (bei vielen µC gleiche Adresse wie Senderegister)
sollte aber auf jeden Fall gelesen werden, sonst kann es zu Fehlern
kommen.
Wenn man etwas empfangen möchte, ist ebenfalls zwangsläufig auch eine
Sendung notwendig. Die gesendeten Daten dürfen den Slave aber auf keinen
Fall stören (mache Slaves haben dafür sogar einen "NOP" Befehl).
Das ist der Hintergrund von SPI Übertragungen und da führt kein Weg dran
vorbei.
Zeichne dir doch mal zwei Blöcke auf, Master und Slave.
Verbinde diese mit CLK, MISO, MOSI.
Dann spiel mal eine Übertragung durch.
Denk daran, dass beide als Schieberegister arbeiten.
Was muss der Master machen um den Slave zu lesen?
(Stichwort Dummybyte)
Ein Blatt Papier kann oft helfen...
ja soweit habe ich das auch verstanden das Prinzip hinter SPI ist mir
nicht bis ins detail aber in der Semantic bekannt.
Was ich unter präzise Antwort verstehe ist mein Fall: was genau ich
falsch, weil ich denke anscheinend richtig habe es aber falsch umgesetzt
oder ich denke auch noch falsch das kann sein ;) aber zu meinen
Gedanken:
Wenn ich eine Loop im Master fertig mache in der ich was verschicke ist
durch diese Schiebe register zwangläufig der Fall das gleichzeitig das
im slave vorliegende Byte im Schieberegister wieder an den Master sende.
( Ich hoffe ich denke da richtig ) . so nun In meinem programm Packe ich
doch mit jedem Umlauf einen Wert in das Schiebe register und versende es
?!dh also im 2. Umlauf ist es wieder beim Master (richtig?)
Ich will nun eigentlich nichts weiter wissen WAS genau ich in meiner
Ausführung falsch mache ,bzw. was muss ich zusätzlich tuen ? was habe
ich vergessen zu tuen ? das verstehe ich halt unter Präzise ;)
Mir zu erklären wie SPI allgemein funktioniert bringt mir nicht viel. Es
tut mir leid vlt reden wir auch aneinander vorbei ;)
Ich habe zu anderen Programmiersprachen auch schon 2 3 mal Foren zu rate
gezogen, in 90% aller Foren wird dann auf den Fehler hingedeutet( oft
mit kleinen code schnipsel) und im besseren Fall noch erklärt warum das
so ist ;)
Ich habe es auch schon so gehandhabt wenn ich mal helfen konnte und mehr
will ich auch nicht :D
> In meinem programm Packe ich doch mit jedem Umlauf einen Wert in das> Schiebe register und versende es ?!dh also im 2. Umlauf ist es wieder> beim Master (richtig?)
Im Prinzip ja - aaaber im Normalfall liest der Slave die Daten aus
seinem Schieberegister um irgendwas damit zu machen und ersetzt sie
durch Daten die er dem Master schicken will/soll.
Welche das sind ist entweder im Slave fest vorprogrammiert oder der
Master muss es mit seiner vorherigen Sendung dem Slave gesagt haben.
Die SPI Schnittstelle überträgt nur die Daten, was damit passieren soll
muss in einem übergeordneten Protokoll festgelegt werden - halt
innerhalb der Möglichkeiten die der Slave zur Verfügung stellt.
jo ok soweit so gut mit den daten will ich vor erst auf dem slave ja
nichts machen :D
ich wollte in meinem fall nur immer wieder einen wert der stetig größer
wird ( incr. ) im 1 s takt schicken und mir das was ich geschickt habe
an 8 LED´s am Master angucken , sozusagen als bestätigung das die
komunikation geklappt hat
dh also Slave macht nichts master macht alles und slave dient nur als
"spiegel"
das klappt wie gesagt bei mir nicht und ich würde halt einfach den
grund dafür erfahren :D
Muss ich vlt die daten die er bekommen hat im gleich atemzug nochma in
das Datenregister vom SPI ( im slave ) reinschreiben also während des
Interrupts ?
Um mal auf den Code zurück zu kommen, der ist Nonsens.
Hättest Du das in C geschrieben, hätte das schon längst jemand gemerkt,
bzw. sogar Du selber.
Und solche Fallstricke, wie etwas aufrufen (rcall) und dann rausspringen
(rjmp), läßt C erst garnicht zu.
Ja stimmt das is blödsinn habe ich auch mitlerweile entfernt, ich bin
nicht gut in ASM aber ich bin noch schlechter in C ;) deswegen schreibe
ich in ASM
ist denn noch irgendwas dadrin was blödsinn ist ?