Forum: Mikrocontroller und Digitale Elektronik Fragen zu einer SP Realisierung in Software


von Sepp (Gast)


Lesenswert?

Hallo zusammen,

ich beschäftige mich gerade mit einer SPI Realisierung in Software. Es 
soll eine Verbindung zwischen einem Atmega 644P und einem ARM6 
hergestellt werden.
Hardware SPI ist auf beiden Seiten belegt, deswegen werden drei normale 
IO Pins verwendet.

Mein Master im Atmega 644P gibt per Pin Toggle mit 9,7kHz den Takt vor.
Meine Vorstellung der Funktionsweise:
Ich gebe den Takt auf einem Pin aus, die somit als Clock Leitung 
fungiert.
Der Slave erkennt nun eine steigende Flanke auf der Clock Leitung und 
übernimmt die Daten an seinem InputPin. Wie weiß der Master wann er mit 
dem Senden beginnen darf? Direkt nachdem er sein Clock Signal auf die 
Leitung gegeben hat?
Der Slave empfängt nun die Daten an seinem InputPin bei steigender 
Flanke der Clock Leitung und setzt ein Bit auf seine Output Leitung, 
wenn eine fallende Flanke detektiert wurde.
Beendet wird das ganze sobald kein Clock Signal mehr anliegt.

Beide Seiten senden also immer Vollduplex wenn ein Clock Signal anliegt?

Danke!


Grüße,
      Sepp

von Peter D. (peda)


Lesenswert?

Sepp schrieb:
> Wie weiß der Master wann er mit
> dem Senden beginnen darf? Direkt nachdem er sein Clock Signal auf die
> Leitung gegeben hat?

Nein.
Der Master setzt das Slave-Select auf low und damit weiß der Slave, daß 
er nun adressiert ist.
Dann werden beliebig viele Bytes übertragen und danach setzt der Master 
das Slave-Select wieder auf high. Damit weiß der Slave, daß er sich 
wieder vom Bus verabschieden und die empfangenen Daten auswerten darf.

SPI braucht also mindestens 4 Leitungen und für jeden weiteren Slave 
noch eine.
Getaktet wird nur sobald ein Slave-Select auf low ist.


Peter

von Sepp (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Nein.
> Der Master setzt das Slave-Select auf low und damit weiß der Slave, daß
> er nun adressiert ist.
> Dann werden beliebig viele Bytes übertragen und danach setzt der Master
> das Slave-Select wieder auf high. Damit weiß der Slave, daß er sich
> wieder vom Bus verabschieden und die empfangenen Daten auswerten darf.
>
> SPI braucht also mindestens 4 Leitungen und für jeden weiteren Slave
> noch eine.
> Getaktet wird nur sobald ein Slave-Select auf low ist.

Bei einem Hardware SPI gebe ich Dir Recht, aber meine Variante sollte 
auf beiden Seiten in Software realisiert sein. Brauche ich trotzdem 4 
Leitungen?
Bisher dachte ich drei würden genügen, es existiert in meiner Variante 
ja lediglich ein Slave (Punkt zu Punkt).

von Karl H. (kbuchegg)


Lesenswert?

Sepp schrieb:

> Bei einem Hardware SPI gebe ich Dir Recht, aber meine Variante sollte
> auf beiden Seiten in Software realisiert sein. Brauche ich trotzdem 4
> Leitungen?
> Bisher dachte ich drei würden genügen, es existiert in meiner Variante
> ja lediglich ein Slave (Punkt zu Punkt).

Es steht dir natürlich frei, dein eigenes Schema zu erfinden und das 
dann SPI zu nennen. Solange es funktioniert ist dagegen auch nichts 
einzuwenden. Nur wird sich dein Nachfolger dann etwas wundern, wenn du 
ihm ein SPI verkaufst, welches gar kein SPI ist sondern nur so ähnlich. 
Zumindest nicht das, was gemeinhin unter SPI verstanden wird.

von Sepp (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Es steht dir natürlich frei, dein eigenes Schema zu erfinden und das
> dann SPI zu nennen. Solange es funktioniert ist dagegen auch nichts
> einzuwenden. Nur wird sich dein Nachfolger dann etwas wundern, wenn du
> ihm ein SPI verkaufst, welches gar kein SPI ist. Zumindest nicht das,
> was gemeinhin unter SPI verstanden wird.

Ich wollte schon standardkonform sein, mir stehen aber nur 3 Pins zur 
Verfügung. Evtl. wäre ein vierter rauszukitzeln, das müsste aber noch 
geklärt werden.

Per Slave Select schicke ich dann ein Low Signal um meinem Slave 
mitzuteilen, dass er nun auf seine Input Leitung horchen muss. In dem 
Moment wo die SS Leitung auf High geht ist meine Übertragung beendet?
Die Clock Leitung wird dannn mit der SS aktiviert oder deaktiviert?

von Karl H. (kbuchegg)


Lesenswert?

Sepp schrieb:

> Die Clock Leitung wird dannn mit der SS aktiviert oder deaktiviert?

Mir scheint, du hast da irgendwie falsche Vorstellungen davon, was die 
Clock Leitung eigentlich macht.

Die Clock Leitung ist nicht einfach nur 1 Takt auf dem eine Schwingung 
rausgeht.
So ist das Synchronisierungsinstrument. Eine Flanke auf der Clock 
Leitung sagt dem Gegenüber: Hey Alder, die Datenleitung hab ich richtig 
eingestellt, genau jetzt holst du dir den Pegel davon bitte ab.

D.h. der Master setzt seine Datenleitung auf 0 oder 1, was er eben 
braucht und erst dann wechselt er die Clockleitung um seinem Gegenüber 
anzuzeigen, dass der Zustand auf der Datenleitung gültig ist.

von Peter D. (peda)


Lesenswert?

Man kann auch 3 Leitungen nehmen, wenn der Datenpin bidirektional ist.
Kann man z.B. bei vielen SPI-EEPROMs so machen (DI + DO verbinden).

Nach dem Select = low ist der Datenpin beim Slave erstmal Eingang und 
liest ein Kommando ein.
Ist es ein Lesekommando, schaltet er danach um auf Ausgang und sendet 
dem Master die zu lesenden Daten.


Peter

von Sepp (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Mir scheint, du hast da irgendwie falsche Vorstellungen davon, was die
> Clock Leitung eigentlich macht.
>
> Die Clock Leitung ist nicht einfach nur 1 Takt auf dem eine Schwingung
> rausgeht.
> So ist das Synchronisierungsinstrument. Eine Flanke auf der Clock
> Leitung sagt dem Gegenüber: Hey Alder, die Datenleitung hab ich richtig
> eingestellt, genau jetzt holst du dir den Pegel davon bitte ab.
>
> D.h. der Master setzt seine Datenleitung auf 0 oder 1, was er eben
> braucht und erst dann wechselt er die Clockleitung um seinem Gegenüber
> anzuzeigen, dass der Zustand auf der Datenleitung gültig ist.

Klasse Antwort, jetzt kommt immer mehr Licht ins Dunkel (-:

Der Slave weiß nun durch eine Flanke, dass er das Bit auf seiner Input 
Leitung abholen soll.
Wie sieht die Sache nun aus wenn der Slave sendet? Legt er einfach sein 
Bit auf die MISO, Problem hierbei wäre doch, dass der Master mitbekommen 
muss wann er etwas auf der Input Leitung abholen soll?

von Karl H. (kbuchegg)


Lesenswert?

Sepp schrieb:

> Der Slave weiß nun durch eine Flanke, dass er das Bit auf seiner Input
> Leitung abholen soll.
> Wie sieht die Sache nun aus wenn der Slave sendet?

Dann muss er rechtzeitig seine Datenleitung auf den richtigen Pegel 
setzen. Er muss damit fertig sein, ehe der Master die Clock Leitung 
toggelt.

Der Master gibt also nicht nur den Takt vor, in dem er selber Daten zum 
Slave schickt, sondern er gibt auch dem Slave vor, wann er auf der 
Rückleitung einen korrekten Pegel erwartet.

Da gibt es jetzt natürlich mehrere Möglichkeiten, wie das konkret 
gemacht werden kann. zb eine steigende Flanke steuert den Transfer vom 
Master zum Slave, dann hat der SLave Zeit sein Bit auf die Leitung zu 
lesen und mit der fallenden Flanke holt sich dann der Master dieses Bit.
ABer wie gesagt: Da gibt es mehree Varianten. Daher gibt es ja auch SPI 
in verschiedenen Modi

http://de.wikipedia.org/wiki/Serial_Peripheral_Interface#Protokollablauf_und_Einstellm.C3.B6glichkeiten

von Sepp (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> Da gibt es mehree Varianten. Daher gibt es ja auch SPI
> in verschiedenen Modi

Ok wunderbare Erklärung! Ich möchte gerne den Modus 0 mit CPOL und CPHA 
0 verwenden. Darunter versteht man doch, dass die Daten bei der ersten 
Flanke, also bei der steigenden übernommen werden.

Hier mein angedachter Ablauf:
- Master legt Bit auf MOSI und toggelt die Clock von Low auf High
- Slave Select wird Low
- Slave erkennt pos. Flanke an Clock und übernimmt an MOSI
- Slave legt sein Datenbit auf MISO
- Master übernimmt die Daten auf MISO wenn er Clock von High auf Low 
schaltet
- Nun legt wieder der Master sein Bit auf MOSI und toggelt die Clock auf 
High
- Schleife beginnt...

Verständnisprobleme bereitet mir aber die Synchronisation beim Slave, 
angenommen mir stehen keine Pin Change Interrupts zur Verfügung, dann 
muss der Slave in einer Schleife den Wert des Clock Pins abfragen. Hier 
ist es doch erforderlich die Durchlaufzeit ähnlich der Schleife beim 
Master zu haben? Angenommen der Master ist viel schneller, dann wird der 
Slave doch niemals einen Clock Wechsel mitbekommen...

Anders gefragt, bei unterschiedlich ausgelasteten Mikrocontrollern auf 
beiden Seiten ist doch ein Interrupt zwingend erforderlich?

von Peter D. (peda)


Lesenswert?

Sepp schrieb:
> Angenommen der Master ist viel schneller, dann wird der
> Slave doch niemals einen Clock Wechsel mitbekommen...

Du hast es erfaßt.
Slave-SPI ist extrem ressourcenhungrig und macht man daher in der Regel 
nicht in Software.
Slave-SPI benötigt 2 externe Interrupts mit der höchsten Priorität (darf 
alle anderen Interrupts unterbrechen). Slave-SPI auf CPUs ohne 
Prioritätslevel kannste voll vergessen.

Und der AVR ist trotz HW-SPI als Slave-SPI völlig unbrauchbar, da er 
keinen Sendepuffer hat. Er hat praktisch genau 0ns Zeit, ein Byte in das 
Senderegister zu schreiben.

Eine SPI-Verbindung zwischen 2 MCs ist daher so ziemlich das schlimmste, 
was man sich als Programmierer antun kann.
Man nimmt besser I2C, UART oder CAN.


Peter

von Sepp (Gast)


Lesenswert?

Peter Dannegger schrieb:
> Slave-SPI benötigt 2 externe Interrupts mit der höchsten Priorität (darf
> alle anderen Interrupts unterbrechen). Slave-SPI auf CPUs ohne
> Prioritätslevel kannste voll vergessen.

Reicht nicht ein Pin Change Interrupt am Clock Pin? Dort könnte ich doch 
dann jeden Wechsel erkennen und Daten übernehmen und rausschreiben.


Ich benötige eine Verbindung von einem Atmel644P zu einem ARM7 TDMI.
Auf dem Atmel sind gerade noch 3 IO Pins verfügbar, kein HW UART oder HW 
SPI, alles bereits belegt. Deswegen die fiel die Wahl auf Software SPI.
Dummerweise sind auf dem ARM7 auch noch die Pins für externe 
Interrupts(Pin Change) vergeben. Naja und das stellt mich vor die großen 
Probleme wie oben beschrieben.

Mittlerweile bin ich soweit ein Arduino Uno Platine dazwischen zu 
schalten.
So solls dann aussehen:

Atmega644P(Master SW SPI) <---> Arduino Uno(Slave SW SPI PinChange 
Interrupts)||| ArduinoUno(HW UART) <---> ARM7(HW UART)

Meinungen dazu?

von Karl H. (kbuchegg)


Lesenswert?

Sepp schrieb:

> Mittlerweile bin ich soweit ein Arduino Uno Platine dazwischen zu
> schalten.
> So solls dann aussehen:

Du hast ja auch noch die Möglichkeit, die Probleme im SPI wenigstens ein 
bischen zu entschärfen, indem du das SPI ein wenig abwandelst.

Grundzustand ist

   MOSI  Low
   MISO  High
   SCLK  High

Der Master möchte etwas übertragen.
Er beginnt damit, den Slave zu benachrichtigen, indem er SCLK auf Low 
zieht. Und dann wartet er.

Der Slave pollt regelmässig seinen SCLK Eingang. Solange der High ist, 
gibt es keine Anfrage.
Ist SCLK auf Low, dann ist vom Master die Aufforderung gekommen: Ich 
will was übertragen.
Als Antwort darauf zieht der Slave die MISO Leitung von High auf Low und 
stellt alle anderen Arbeiten sowiet wie möglich ein um möglichst viel 
Prozessorzeit auf das überwachen der SCLK Leitung frei zu haben.

Das wiederrum kriegt der Master mit, der nur darauf gewartet hat. Das 
Low auf MISO zeigt ihm, dass der Slave nun zuhört.

Also setzt er MOSI anhand des zu übertragenden Bits, wartet vielleicht 
noch ein wenig und zieht SCLK wieder auf High und wartet wieder ein 
wenig.

Dieses High ist für den Slave wiederrum die Aufforderung sich das Bit 
vom MOSI zu holen. Gleichzeitig ist es auch die Freigabe das erste Bit 
seines eigenen Bytes auf MISO zu legen.

Hat der Master seine Bitwartezeit absolviert dann zieht er SCLK wieder 
auf Low und holt sich das Bit vom MISO

Und so gehts immer weiter.

Problematisch sind natürlich immer noch die Wartezeiten, die der Master 
einlegen muss um mittels SCLK die Übertragung zu takten.

Aber zumindest für den Verbindungsaufbau hat der Master die Gewissheit, 
dass er den Slave nicht soweit überfährt, dass der noch gar nicht bereit 
ist, ehe er loslegt.

von Sepp (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:
> rundzustand ist
>
>    MOSI  Low
>    MISO  High
>    SCLK  High
>
> Der Master möchte etwas übertragen.
> Er beginnt damit, den Slave zu benachrichtigen, indem er SCLK auf Low
> zieht. Und dann wartet er.
>
> Der Slave pollt regelmässig seinen SCLK Eingang. Solange der High ist,
> gibt es keine Anfrage.
> Ist SCLK auf Low, dann ist vom Master die Aufforderung gekommen: Ich
> will was übertragen.
> Als Antwort darauf zieht der Slave die MISO Leitung von High auf Low und
> stellt alle anderen Arbeiten sowiet wie möglich ein um möglichst viel
> Prozessorzeit auf das überwachen der SCLK Leitung frei zu haben.
>
> Das wiederrum kriegt der Master mit, der nur darauf gewartet hat. Das
> Low auf MISO zeigt ihm, dass der Slave nun zuhört.

Das Konzept werde ich mal übernehmen.
Nun hat sich doch etwas zum Guten geändert in meiner Ausgangssituation:
Der ARM muss pro Sekunde 4 Rechenzyklen durchlaufen von denen ein Zyklus 
ca.  130ms braucht. D.h. ich habe danach  120ms pro Zyklus für meine SPI 
Übertragung.
In dieser Zeit kann ich den ARM alleine als Software SPI Master nutzen.

Der Atmel würde nun zum Software SPI Slave degradiert und kann auf der 
Clock Leitung nun auf Pin Change Interrupts reagieren.
So sollte die Übertragung gelingen....

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.