Forum: Mikrocontroller und Digitale Elektronik SPI-Übertragung beschleunigen [MSP430]


von Mario (Gast)


Lesenswert?

Hallo zusammen,

hab grade ein kleines Timing-Problemchen und komm nicht weiter,
vielleicht hat jemand von Euch einen Tip oder eine Idee für mich.

Folgendes: Ich hab einen MSP430F149, mit dessen SPI-Schnittstelle ich
einen externen Baustein anspreche. Insgesamt sende ich 80 Bit, also
sind es 10 SPI-Pakete zu je 8 Bit.

Mein Problem: Das soll möglichst schnell gehen. Jetzt hab ich aber nach
jedem einzelnen SPI-Paket eine Pause drin; eine Übertragung braucht 8µs,
und dann ist 18µs Funkstille bis zum nächsten Paket !

Das liegt sicher an meiner Software-Routine, mit der ich sowohl Daten
senden als auch empfangen kann (der externe Baustein hat nur eine
Datenleitung, auf der er sendet oder empfängt). Ich frage also
sicherheitshalber ab, ob 1. der Sendepuffer frei ist, und 2. ob die 8
Bit schon vollständig übertragen wurden (TX/RX gehen ja bei der SPI
synchron). Hier ist die Routine:



unsigned char nrf_readwrite(unsigned char data)
{
    while(!(IFG1 & UTXIFG0))    // Warten bis Sendebuffer bereit
    { _NOP(); }

    U0TXBUF = data;             // Daten in Sendebuffer schreiben

    while(!(IFG1 & URXIFG0))    // Warten bis Zeichen übertragen wurde
    { _NOP(); }

    return U0RXBUF;             // Empfangene Daten zurückgeben
}



Was kann ich tun, um diese Totzeit kleiner zu kriegen ?

Schon mal Besten Dank und viele Grüße,

Mario

von Rufus T. Firefly (Gast)


Lesenswert?

Das "nop" kann man auch weglassen:

statt

    while(!(IFG1 & URXIFG0))    // Warten bis Zeichen übertragen wurde
    { _NOP(); }

genügt ein

    while(!(IFG1 & URXIFG0));    // Warten bis Zeichen übertragen
wurde

Das dürfte schon einige Takte Unterschied ausmachen.

von Mario (Gast)


Lesenswert?

Hallo,

bringt leider keine Änderung, das "_NOP();" war nur eine Anweisung
für den IAR-Compiler (zum Debuggen). Weglassen ändert nix ...

Aber ich hab mal die erste Abfrage weggelassen (wenn ich nachher auf
das Ende der Übertragung warte, muss die SPI beim nächsten Aufruf ja
zwangsweise immer noch im Leerlauf sein), und da komm ich jetzt auf
15µs Pause. Schon besser, aber immer noch viel ...

Grüße, Mario

von Arvid Teichtmann (Gast)


Lesenswert?

Zwei Fragen:
Mit welcher Taktfrequenz läuft der Prozessor?
Mit welcher Taktfrequenz läuft die SPI-Schnittstelle?

Gruss
Arvid

von ThoWi (Gast)


Lesenswert?

Hallo,
ich kenne zwar weder den µC noch programmiere ich grossartig in C, aber
an deiner Stelle würde ich mal versuchen, die Zeit zu messen zwischen
Verlassen der Prozedur und Wiederaufrufen der Prozedur. Ich kann mir
gut vorstellen, dass hier die meiste Zeit verloren geht.

Gruß
Thorsten

von Jürgen Schuhmacher (Gast)


Lesenswert?

Ich sehe das auch als ein Bereitstellungsproblem an. Der Sendebuff muss
derart präpariert sein, daß die Senderoutine auch wirklich ein Byte
findet und sendet. Ist das der Fall?  Was genrell nicht so geschickt
ist, ist die Warterei: Solche Senderoutinen sollten als
timer-gesteuerte ISR arbeiten, die wirklich exakt ein Byte abschicken.
Funktioniert das so korrekt?

Wenn es als Zeichenorientiertes System nicht geht, hilft nur, eine ISR
aufzubauen, die exakt den gesamten String abhandelt. Das Restprogramm
ist dann halt tot. In Deinem Fall nehmen due 8 Bit ja wohl 8u - daher
komme ich auf gut 80u Ausszeit.

Wie hoch ist die Datenrate? Gem obiger Rechnung komme ich auf 125kBaud
(?)

von peter dannegger (Gast)


Lesenswert?

Ich kenne den MSP nicht, aber manche MCs (z.B. AT89S8253) haben einen
Sendepuffer, den muß man allerdings erst enablen.

Dann kann man schon das nächste Byte in den Sendepuffer stellen, wärend
das vorhergehende noch rausgeschoben wird und alle Bytes sitzen nahtlos
aneinander.


Peter

von Mario (Gast)


Lesenswert?

Hallo zusammen,

und zunächst mal lieben Dank für die Antworten. Konnte leider nicht
früher antworten, da ich irgendwie nicht auf's Forum zugreifen konnte
-- na egal, es geht ja jetzt wieder.

Beim Senden der 80 Bit ist es so, dass die Senderoutine 10x direkt
hintereinander aufgerufen wird, ohne "Luft" dazwischen. Derzeit läuft
das Ganze (noch ?) ohne (SPI-)Interrupts, da der µC nur die Aufgabe hat,
Daten einzulesen und loszuschicken, weshalb ich da durch Interrupts
wenig gewinne (kann ja nichts parallelisieren).

Da ich die Routine wie gesagt zum Senden UND Empfangen verwende, muss
ich wirklich warten, bis eine Übertragung fertig ist, damit ich beim
Empfangen wieder ein komplettes Byte zurückgeben kann. Einen externen
Sendepuffer will ich nicht verwenden, weil ich definierte zeitliche
Abstände zwischen den Paketen brauche. (Es handelt sich um ein
Funkübertragungssystem, bei dem der Empfänger nur zu bestimmten Zeiten
aktiviert wird - deshalb definierter zeitlicher Abstand.)

Aber ich hab das Problem inzwischen gelöst (bzw. umgangen), indem ich
die Taktfrequenz des µC raufgesetzt habe. Die SPI-Datenrate beträgt
weiterhin 1MBit/s. Jetzt brauchen 8 Bit wieder etwa 8µs, und die Pause
dazwischen hat sich durch die höhere Taktfrequenz auf ebenfalls 8µs
runtergekürzt, effektiv kann ich also mit 500kBit/s übertragen. Das is
schon ganz ordentlich, und damit kann ich jetzt leben.

Also, nochmals besten Dank an Euch alle,

schöne Grüße,

Mario

von Maddin (Gast)


Lesenswert?

Hallo,
Ich weiss dass der Thread schon alt ist, wollte aber nicht extra einen 
neuen anlegen. Eine Frage:
Wie muss ich die SPI Schnittstelle konfigurieren, damit ich mit diesen 
while  Schleifen auf den Empfang/Versenden des Bytes warten kann? Mit 
meiner aktuellen Einstellung klappt das nicht so wirklich. (MSP430F149)
Könnt ihr mir den Code Schnippsel eurer SPI Initialisierung mal zeigen?

Danke.

von Christian R. (supachris)


Lesenswert?

Solange du uns nicht deine Einstellungen und den Code zeigst, können wir 
dir nicht weiter helfen.

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.