Forum: Mikrocontroller und Digitale Elektronik SPI Verständnisproblem


von Florian M. (----florian----)


Lesenswert?

Guten Abend.

Ich stehe vor folgendem Problem:

Es sollten 2 Atmega 8 mit SPI verbunden werden. Der Master sollte
eigentlich 8 bits an den Slave schicken, und der Slave sollte die bits
dann auf einem Port mit Leds ausgeben.

Genügt es da, einfach sck zusammenschließen, und mosi vom Master auf
miso vom Slave dranzuhängen?

Und wenn der Slave richtig konfiguriert ist, brauch ich dann nur:

in temp,spdr
out portd,temp

eingeben?

Ich habe da nämlich einpaar verwirende Sachen gelesen, da wo stand, das
der Slave irgendwelche Daten schicken muß, damit sie der Master auf den
Slave ausgibt. Ist da was wares dran? Oder hab ich da was falsch
verstanden?

Gruß Florian

von Christian F. (fasti)


Lesenswert?

Hi!

Also SPI ist ein Ringbuffer, das heisst der Master muss 8 (Dummy-)Bits
an den Slave schicken, damit dieser ihm dann die gewünschten 8 Bits
schickt.
Der Slave kann von sich aus keine Bits schicken, er kann dem Master nur
durch einen Low pegel am MISO anzeigen, dass er Daten hätte oder aber
mittels eines zusätzlichen Pins. Der Master initiiert immer den
Datenverkehr, er legt den CS Pin auf low, damit der Slave weiss, dass
er gemeint ist. Danach taktet er 8 Bits aus seinem Puffer mittels SCK
und MOSI in den Slave und GLEICHZEITIG wird über MISO die 8 Bits vom
Slave empfangen.

mfg

Fasti

PS: Alle Angaben ohne Gewähr..... :-)

von Florian M. (----florian----)


Angehängte Dateien:

Lesenswert?

Hallo Fasti.

Also bei mir geht ein Kabel von Mosi(Master) auf Miso(Slave) und SCK
sind zusammengeschlossen.

Der Master schickt jede Sekunde 2 verschiedene Bitmuster (zum testen).

Der Slave wird mit dem Programm im Anhang bespielt. Ist eigentlich
alles gleich konfiguriert als wie bei master außer mstr.

Also so funktioniert es leider nicht, was mache ich da falsch?

Gruß Florian

von Hannes L. (hannes)


Lesenswert?

Du solltest SPDR nur einlesen, wenn neue Daten eingetroffen sind. Schau
mal ins Datenblatt auf Seite 125, 126 und 128. Das geht per Polling (S.
125) oder besser per Interrupt (siehe auch S. 44, 45).

...

von Dirk Doerr (Gast)


Lesenswert?

Ich würde mal MOSI mit MOSI verbinden und nicht MOSI mit MISO

Wenn Du eine Antwort willst mußt Du auch noch MISO mit MISO verbinden



Master --MOSI-->------MOSI--Slave
  |                          |
  |______MISO--<------MISO___|


Schau Dir doch mal das Datenblatt an. (Bild: SPI Master-Slave
interconnection im SPI Kapitel)

von Florian M. (----florian----)


Angehängte Dateien:

Lesenswert?

Auwe, das ist natürlich ein schwerer Fehler... Habe jetzt folgendes mit
interrupt gemacht, aber es funzt leider immer noch nicht.

Ist da noch ein Fehler drin?

Gruß Florian

von Kai R. (kairiek)


Lesenswert?

Lass den Interrupt einfach weg. Ich würde in diesem einfachen Fall, wie
Hannes vorgeschlagen hat, einfach das Interrupt Flag pollen. Das machst
du ja mit dem sbis Befehl. Natürlich solltest du das Bit auch wieder
zurücksetzen, sonst gehts auch nicht.

MFG

Kai

von Dirk Doerr (Gast)


Lesenswert?

Mal noch eine Anmerkung:
Hast Du eigentlich an den ChipSelect bzw. SlaveSelect Pin gedacht?

Der muß vom Master vor dem Datentransfer auf low gesetzt werden und
danach wieder auf high.

Solange der Pin auf high liegt wird der SPI im Slave nichts empfangen.

Gruß

      Dirk

von Florian M. (----florian----)


Lesenswert?

Vielen Dank für die vielen antworten.

Das mit SS wußte ich schon, habe es aber einfach beim Slave auf GND
gelegt. Wäre das grundsätzlich falsch?

Oder kann ich es einfach mit dem Master verbinden? Also ich meine,
zieht der Master beim senden die SS Leitung automatisch auf low?

Grundsetztlich funktioniert bei mir der Aufbau, aber er zeigt nur
einmal die eine Ledkombination an, und die zweite. Danach ist aus.

Würde es gerne mit Interrupt machen, doch irgendwas fuxt da noch.

Gruß Florian

von Fasti (Gast)


Lesenswert?

Hi!

Du musst den SS Pin selbst hoch und runter ziehen! Wenn du den Slave SS
Pin permanent auf Ground legst weiss der nie, wann die Übertragung zu
Ende ist! Also einen Pin vom Master auf den SS Pin am Slave! Dieser ist
immer high! Wenn du eine Übertragung startest dann legst du denn Pin
vorher auf low, dann schreibst du in dein SPDR Register, daraufhin
startet der AVR bei Hardware-SPI automatisch die Übertragung. Danach
einfach den SS Pin wieder high setzen, damit weiss der Slave, dass die
Übertragung zu Ende ist. Auf diesem Weg kann man auch 16 Bit und mehr
breite Daten auslesen, weil man den SS Pin immer erst nach Ende der
Übetragung wieder high setzt.

mfg

Fasti

von Florian M. (----florian----)


Angehängte Dateien:

Lesenswert?

Hallo nochmal.

Es tut mir leid, aber ich komme mit dieser einfachen Aufgabe nicht
klar. Ich habe die Schaltung so wie im Anhang aufgebaut doch es
funktioniert nicht.

Er sendet zwar einmal die Daten rüber, und die Leds zeigen dann das
richtige an, aber danach passiert nichts mehr.

Beide laufen mit 1 MhZ intern.

Könntet ihr mal bitte einen Blick drauf werfen, ob ihr da irgnedwo
einen Fehler endeckt?

Das wäre wirklich toll, weil ich weiß wirklich nichtmehr weiter...

Im nächstem Anhang wären dann noch die Programme für den Master und den
Slave.

Ach ja, beim Master ist die Pause eine Sekunde lang.

Vielen Dank

Gruß Florian

von Florian M. (----florian----)


Angehängte Dateien:

Lesenswert?

Und hier noch die Programme...

von Steff (Gast)


Lesenswert?

warum geht bei dir eigentlich der AGND und der C2 auf +5V Versorgung und
nicht auf GND ?

Gruß

von Florian M. (----florian----)


Lesenswert?

Ups, falsch gezeichnet. Danke für den Tip. Aufgebaut habe ich es
natürlich richtig


Gruß Florian

von Florian M. (----florian----)


Lesenswert?

Hi.

Hätte sonst keiner mehr eine Idee, was da falsch sein könnte?

Gruß Florian

von 789 (Gast)


Lesenswert?

Ich hab Dein Programm mal grob überflogen. So wie es aussieht hast Du
einen SPI-Interrupt-Handler in dem eine Endlosschleife auf das SPI-Flag
testet. Sowas macht man doch nicht! ;-)

(Ich hab jetzt nich nachgeschlagen wann genau das Flag gelöscht wird.
Es könnte sein, dass trotzdem alles funktioniert.)

von Thomas F. (thomas-hn) Benutzerseite


Lesenswert?

Wenn ich es richtig weiß wird das Interrupt-Flag automatisch gelöscht
sobald der Interrupt aufgerufen wird. Also entweder über den
Interrupthandler arbeiten oder im "normalen" Programmablauf das Flag
von Hand abfragen. Beides zusammen wird wohl nicht gehen.

Gruß,

Thomas

von Florian M. (----florian----)


Lesenswert?

Hab ich da jetzt etwas falsch gemacht, oder nicht?

Gruß Florian

von Fasti (Gast)


Lesenswert?

Hi!

Also wenn ich das Datenblatt richtig verstanden habe, dann kann MOSI
auf MOSI gar nicht funktionieren. Du musst MOSI beim Master auf MISO
beim Slave geben. (Die Namen der Pins sind da schon sehr
aussagekräftig: MOSI  Master Out Slave In und MISO Master In Slave
Out).
Erst dann kann eine Kommunikation stattfinden. Schliesslich wird ja
gleichzeitig gesendet und empfangen.

mfg

Fasti

von Hannes L. (hannes)


Lesenswert?

> Also wenn ich das Datenblatt richtig verstanden habe, dann kann MOSI
> auf MOSI gar nicht funktionieren. Du musst MOSI beim Master auf MISO
> beim Slave geben. (Die Namen der Pins sind da schon sehr
> aussagekräftig: MOSI  Master Out Slave In und MISO Master In Slave
> Out).

Das wäre aber unlogisch...

Signal   Master   Richtung   Slave
----------------------------------
MOSI     Out      ------->   In
MISO     In       <-------   Out

...

von Thomas F. (thomas-hn) Benutzerseite


Lesenswert?

Ich bin momentan vom Studium aus im Praxissemester bei Atmel in der
Entwicklung ;-)
Und MISO kommt definitiv auf MISO und MOSI auf MOSI.
Denn in jedem Gerät wird mit einem Flag eingestellt ob es Master oder
Slave ist und somit werden die Eingänge von der Richtung korrekt
geschaltet wenn MISO mit MISO und MOSI mit MOSI verbunden wird
(vorausgesetzt es wird der eine Teilnehmer als Master und der andere
als Slave konfiguriert ;-)
Weiterhin muss man die SCK von beiden Teilnehmern miteinander verbinden
und dann kann man noch die /SS-Leitungen von beiden Teilnehmern
miteinander verbinden, denn diese ist beim Slave automatisch Eingang
und muss auf Low-Pegel liegen, damit der Slave arbeitet. Beim Master
ist die /SS-Leitung AFAIK auch ein Eingang, kann aber über das DDRx auf
Ausgang geschaltet werden und kann somit den Slave steuern.
Ich habe die /SS-Leitung vom Master schon dazu verwendet beim
Einschalten einmalig das SPI-Schieberegister vom Slave zurückzusetzen,
bevor die Datenübertragung beginnt...sonst kann es vorkommen, dass ein
Versatz in den Daten vorliegt.

Es gibt auch noch einige Atmel-Application Notes dazu, z.B.
http://www.atmel.com/dyn/resources/prod_documents/doc2585.pdf


Gruß,

Thomas

von Thomas F. (thomas-hn) Benutzerseite


Lesenswert?

Nachtrag zu MISO, MOSI:

Das MOSI heißt ja MASTER OUT, SLAVE IN. Da durch die Konfiguration der
Register beide ICs wissen ob sie jeweils Master oder Slave sind
schalten sie ihre Schieberegisteranschlüsse auch passend auf MISO oder
MOSI.

Somit sendet der Master bei MOSI (MASTER OUT, slave in) seine Daten und
der Slave empfängt auf MOSI (master out, SLAVE IN) die Daten.
Genau umgekehrt ist es dann bei MISO.

Thomas

von Fasti (Gast)


Lesenswert?

Hi!

Upsi, sollte vorher nochmal lesen..... peinlich
natürlich gehört MOSI auf MOSI und MISO auf MISO, argh
tut mir leid....
Bei meinen Boards hab ichs richtig weil es funktioniert bei mir....
mhm, nächstes mal nochmal nachschaun ;-)

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
Noch kein Account? Hier anmelden.