Probleme mit SPI und SD-Card

Hallo zusammen,

ich habe da ein Problem mit SPI und SD-Card.

In meinem Sketch lese ich Daten von der SD-Card und sende dann Sollwerte an (z.Zt.) einen externen DA-Wandler.
Ist der Datentransfer an SPI beendet, schließe ich mit 'SPI.end()' wieder ab.
Soweit funktioniert das ganze auch, die Werte werden von der SD-Card gelesen, der DA-Wandler gibt korrekte Werte aus und der AD-Wandler liefert auch wieder korrekte Werte zurück.

Nun sollten im Anschluss die nächsten Daten von SD-Card gelesen werden, aber dann lässt sich die Karte nicht mehr initialisieren!
Erneutes initialisieren der Karte ist dann erst nach einem Reset möglich!

Offensichtlich kommt es hier zu einem Konflikt auf der SPI-Schnittstelle.

Ach ja:
Ich muss für meine externen SPI-Bausteile die Datenflussrichtung umkehren (MSBFIRST), das zurücksetzen auf 'LSBFIRST' zeit aber keine Änderung des Verhaltens.
Des weiteren muss ich die Taktfrequenz von SPI auf 1 MHz reduzieren, da mein AD-Wandler max. 1,6 MHz kann.

Für dieses Projekt verwende ich den ARDUINO-MEGA.

Gibt es eine Möglichkeit, die Zustände der relevanten Register des Prozessors vor Aufruf der SPI-Kommunikation zu sichern und dann vor dem erneuten Aufruf der SD-Card wiederherzustellen?

Oder ist es möglich, per Software eine SPI-Schnittstelle zu emulieren?
Bei der SPI-Kommunikation kann ich durchaus Abstriche an die Geschwindigkeit machen, das ist nicht zeitkritisch.

N.B.: SPI muss ich deswegen verwenden, da ich wegen unterschiedlicher Potenziale eine galvanische Trennung benötige, und das geht am einfachsten mit SPI und Induktivkopplern.

Vielen Dank für Eure Hilfe!

Grüße

Martin

marau:
Oder ist es möglich, per Software eine SPI-Schnittstelle zu emulieren?
Bei der SPI-Kommunikation kann ich durchaus Abstriche an die Geschwindigkeit machen, das ist nicht zeitkritisch.

Du kannst shiftOut() verwenden.
http://arduino.cc/en/Reference/ShiftOut

marau:
N.B.: SPI muss ich deswegen verwenden, da ich wegen unterschiedlicher Potenziale eine galvanische Trennung benötige, und das geht am einfachsten mit SPI und Induktivkopplern.

Vielen Dank für Eure Hilfe!
Grüße Martin

Bitte beschreibe die Schaltung genau. Vieleicht finden wir eine bessere Lösung.

Grüße Uwe

Hallo Uwe,

was bitte ist shiftout?

Nun zur Beschreibung was ich vorhabe.

Die Netzteile, welche ich ansteuern will, sind für ein Röhrenmessgerät.
Da ist es z.B. so, dass für die Steuergittervorspannung das positive Potenzial an GND liegt und das negative zwischen 0 und -120V je nach Röhrentype betragen kann.

Spannungs- bzw. Stromquellen für die Röhrenheizung möchte ich potenzialfrei haben.

Da ich bei den Stromversorgungen für Anoden- und Schirmgitterversorgung auch die fliessenden Ströme messen will, benötige ich eben auch noch AD-Wandler.
Bei diesen beiden Netzteilen kommt erschwerend hinzu, dass die Schaltungsmasse und GND unterschiedliche Potenziale haben.

Ich habe also insgesamt 5 Netzteile mit teilweise unterschiedlichen Potenzialen:

Heizspannungsquelle 0..12,6V für die Spannungsserien, Strom nicht rücklesbar
Heizstromquelle 0..300mA für die Stromserien, Strom nicht rücklesbar
Anodenspannungsquelle 0.. ca. +350V, Strom rücklesbar
Schirmgitterspannungsquelle 0.. ca. +350V, Strom rücklesbar
Steuergitterspannungsquelle 0.. -120V, Strom nicht rücklesbar

Ursprünlich hatte ich an I²C gedacht, aber für I²C gibts keine handelsüblichen Bausteine, welche eine galvanische Trennung ermöglichen, weiterhin gibt es hier nach meinem Kenntnisstand keine AD- bzw. DA-Wandler mit mehr als 8 bit Auflösung.

Die von mir favorisierten SPI-Bausteine MCP4921 bzw. MCP3201 haben 12 bit Auflösung.
SPI lässt sich auch, wie bereits geschrieben, mit Induktivkopplern einfach galvanisch trennen.
Diese Induktivkoppler sind von der Bauform her SMD-IC's, wegen der benötigten Luft- und Kriechstrecken jedoch im breiten Gehäuse.
Sie bieten insgesamt vier Übertragungsfunktionen in einem Gehäuse (MISO, MOSI, SCLK und 1x CS), den zweiten benötigten CS müsste ich dann per Optokoppler realisieren.

Eine Möglichkeit, wenn es gar keine andere Lösung gibt, wäre noch, das ganze zu verteilen.
Der MEGA sendet die zu übertragenden Werte samt Chipnummer an einen zweiten ARDUINO (ich habe da noch iregndeinen Clone mit ATMEGA168 rumliegen), dieser sendet die Sollwerte per SPI an die DA-Wandler, liest bei den dazu vorgesehenen Netzteilen den Strom von den AD-Wandlern zurück und sendet diese Werte wiederum per serieller Verbindung an den MEGA.

Gruß

Martin

Ursprünlich hatte ich an I²C gedacht, aber für I²C gibts keine handelsüblichen Bausteine, welche eine galvanische Trennung ermöglichen, weiterhin gibt es hier nach meinem Kenntnisstand keine AD- bzw. DA-Wandler mit mehr als 8 bit Auflösung.

Der MAX127 ist ein I2C 8-Kanal 12Bit AD-Wandler.

Liebe Grüße

Dirk

marau:
Hallo Uwe,

was bitte ist shiftout?

Eine Funktion des Arduino. Ich hab Dir auch den Link zur Erklärung dazugeschrieben.

Grüße Uwe

Gibt es eine Möglichkeit, die Zustände der relevanten Register des Prozessors vor Aufruf der SPI-Kommunikation zu sichern und dann vor dem erneuten Aufruf der SD-Card wiederherzustellen?

Du kannst die relevanten Register der SPI-Hardware schon retten und später wieder herstellen:

byte saved_spcr = 0;
byte saved_spsr = 0;

// save the SPI registers
saved_spcr = SPCR;
saved_spsr = SPSR;

// restore the SPI registers
SPCR = saved_spcr;
SPSR = saved_spsr;

Hallo zusammen,

vielen Dank für die Antworten!

Der Vorschlag von Pylon hat mich weitergebracht, das ganze funktioniert jetzt problemlos!
Nach dem SD-Card-Zugriff rette ich die Registerinhalte der SPI-Schnittstelle, nach der SPI-Kommunikation stelle ich diese wieder her um den nächsten Datensatz einlesen zu können.
Das funktioniert sogar ohne erneutes initialisieren der SD-Card!

Jetzt werde ich mich den nächsten Schritten für das Projekt widmen:

  • Entwurf einer Leiterplatte zum koppeln des MEGA mit Display und den Schnittstellen für 'den Rest der Welt'
  • Integration der bereits fertiggestellten Peripherie (Relaismatrix für Elektrodentest über I²C)

Danach geht es an das austesten der Netzteile, die Schaltungen habe ich bisher nur mit LTSpice simuliert.

Für dieses Projekt habe ich noch ne Menge Arbeit vor mir, aber dank Eurer Hilfe bin ich jetzt einen Schritt weiter!

Grüße

Martin