Forum: Mikrocontroller und Digitale Elektronik MMC-Karte funktioniert nicht


von Gast (Gast)


Lesenswert?

Guten Morgen, ich probiere schon ewig, eine MMC-Karte zum Laufen zu 
bringen.
Das ganze soll eine Art Datenlogger werden, den ich in ein bestehendes 
Projekt integrieren will.
Verwendet wird ein Atmega 32 @ 16MHz. Die Speicherkarte ist über einen 
einfachen Spannungsteiler angebunden, die Betriebsspannung wird von 
einem Spannungsregler erzeugt.
Folgende Beispiele habe ich schon ausprobiert:
http://www.ulrichradig.de/home/index.php/avr/mmc-sd
http://www.roland-riegel.de/sd-reader/

Aber: Mit keinem der Beispiele lässt sich die Speicherkarte zur Funktion 
überreden.
Ausprobiert habe ich schon: DI/DO vertauscht, neue Speicherkarte, neuer 
Atmega - erfolglos.
Die Pin-Einstellungen müssten stimmen, ich habe alles mehrfach 
nachgemessen.

Ein weiteres Problem ist, ich würde sehr gerne auf eine Software 
SPI-Lösung zurückgreifen. Das Beispiel von Ulrich Radig bietet das, 
leider bekomme ich auch den Software-Modus nicht zum laufen.

Woran kann das noch liegen? Ich bin wirklich verzweifelt, wenn noch 
Angaben fehlen bitte fragen...

Kennt außerdem noch jemand eine funktionierende Software-SPI 
Implementierung, über die sich eine MMC/SD-Karte ansprechen lässt?
Ich müsste bzw. würde sehr gern den Hardware-SPI Anschluss meiden, vor 
allem da er schon belegt ist und ich damit seinerzeit schon genug 
Probleme hatte, als das ich da jetzt noch eine Speicherkarte dranhängen 
möchte.

Danke!

von jack (Gast)


Angehängte Dateien:

Lesenswert?

>Verwendet wird ein Atmega 32 @ 16MHz. Die Speicherkarte ist über einen
>einfachen Spannungsteiler angebunden

Nicht gut. ATmega und MMC mit einer Spannung betreiben, keine Spannungs-
teiler verwenden. Atmega32L wäre gut (niedrigere Vcc möglich). Falls Du
unbedingt den 32 verwenden willst, Pegelwandler benutzen.

>Folgende Beispiele habe ich schon ausprobiert:
>http://www.ulrichradig.de/home/index.php/avr/mmc-sd
>http://www.roland-riegel.de/sd-reader/

Am besten eigene Initalisierung schreiben. Das ist keine große Sache,
und Du weißt genau, was gemacht wird.

>Ein weiteres Problem ist, ich würde sehr gerne auf eine Software
>SPI-Lösung zurückgreifen.

Im angehängten .pdf ist auch die Ansteuerung "zu Fuß" beschrieben.

von Christian J. (elektroniker1968)


Lesenswert?

Hallo,

aus meiner Erfahrung (mit PIC18F....): Selbst schreiben andhand der MMC 
Spec (gibts im Netz zu finden)! Es gibt Karten die laufen nicht, zB weil 
der Schreibvorgang länger dauert als das Timeout (rechne mit bis zu 0,1s 
bei alten Karten!)

Ausserdem benötigt das Forum genaue Infos. Läuft nicht .... ist keine 
Info. Was läuft nicht? Hakt es schon bei der Init Sequenz? Oder klappt 
das Schreiben nicht?

usw.

von Pete K. (pete77)


Lesenswert?

Hilfreich wäre auch der Hardware-Aufbau. Wie sieht es mit 
Abblockkondensatoren aus ?

von Benedikt K. (benedikt)


Lesenswert?

Christian J. wrote:
> Selbst schreiben andhand der MMC Spec

Ob das so eine gute Idee ist?
Wenn die Harware falsch ist, dann hilft sowas leider nicht weiter. Ich 
würde daher den anderen Weg gehen, und eine Software verwenden von der 
bekannt ist, dass sie auf jedenfall funktioniert. Dann kann man sich auf 
die Hardware bei der Fehlersuche konzentrieren.

> Es gibt Karten die laufen nicht, zB weil
> der Schreibvorgang länger dauert als das Timeout

Das ist die Software ganz einfach Mist. Wenn alle Specs eingehalten 
wurden, und noch ausreichend Toleranzen in alle Richtungen vorhanden 
sind, dann funktioniert auch jede Karte.

> (rechne mit bis zu 0,1s bei alten Karten!)

Reicht nicht. Selbst neuere Karten brauchen teilweise länger und das 
liegt nicht mal am Hersteller. z.B. bei 1GB Kingston Karten habe ich 
periodisch fast 200ms gemessen. Anscheinend immer dann wenn das Wear 
Leveling zuschlägt. Andere Karten zeigen solch ein Verhalten nicht, oder 
sehr viel weniger ausgeprägt.

von Christian J. (elektroniker1968)


Lesenswert?

Hallo,

ich habe mir die genannte Software mal 15 Minuten angeschaut, versucht 
durchzusteigen. Vielleicht bin ich ja blöde aber ich finde die für den 
Anfang viel zu komplex und durch tausend #if def .... sehr schwer zu 
lesen, nicht nur weil sie Englisch ist. Auf Anhieb wüssste ich nicht wie 
ich eine einfache Funktion realisieren sollte, die nur ein paar Zeichen 
in ein File schreibt. Es gibt zwar viele gute Programmierer aber bei 
solch komplexen Sachen muss man schon eine gut verständliche Doku 
dabeischreiben.

Ich habe mir seinerzeit EFSL von sourceforge.net gezogen. Die ist noch 
viel umfangreicher aber hat ein sehr schönes Manual dabei und ohne die 
ganzen Interna zu verstehen benutzt man nur eine Handvoll Funktionen und 
es funktioniert, wenn man in config.h alles eingestellt hat. Die hat 
auch von Anfang an durchcompiliert für den ARM mit dem GNU CC Compiler.

Für den Anfang würde ich auch nur versuchen die RAW Funktionen der 
unteren Schicht zum Laufen zu kriegen, die sind einfacher verständlich. 
Wenn die laufen müsste das ganze hardwareunabhängige Gebilde drüber auch 
funktionieren. Die habe ich mir damals selbst geschrieben und so einige 
Auffälligkeiten bemerkt, zB dass manche Karten nach jedem Zugriff von 
allein in den Idle Mode gehen und wieder aufgeweckt werden müssen, 
andere gehen erst nach dem Befehl "schlafen legen" da rein.

Christian

von Gast (Gast)


Lesenswert?

Vielen Dank für eure Antworten soweit, damit ist mir schon viel 
geholfen.

Das Problem bei der Sache ist, morgen sollte der Aufbau laufen, deswegen 
fallen größere Änderungen wie z.B. Pegelwandler leider flach.
Einen Atmega32L müsste ich auch wieder bestellen, außerdem kämen dann 
wieder größere Probleme auf mich zu, da noch ein MAX232, ein LCD und 
mehrere Controller über I2C angeschlossen sind, die sich wahrscheinlich 
nicht sofort mit den 3,3V des Controllers vertragen werden.

An einer eigenen Initialisierung würde ich mich nur ungern probieren, 
oder wenn nur als Notnagel, einfach aus Zeitmangel.

Die Angabe "läuft nicht" ist dürftig, zugegeben. Ich versuche es mal 
besser:
Beim Beispiel von Ulrich Radig sowie dem von Roland Riegel scheitert es 
bereits an der Initialisierung. Die Funktionen brechen bereits beim 
Versuch, das erste Kommando zu senden, erfolglos ab.

Mit einer alten Karte habe ich folgendes probiert: Einmal die 
Init-Sequenz durchlaufen lassen und dann nicht auf den Rückgabe-Wert 
achten, sondern einfach weitermachen. Folge: Karte wird im Kartenleser 
zwar erkannt, hat aber kein Dateisystem und verhält sich quasi wie eine 
Speicherkarte ohne Speicher...

Die jetzt verwendete Karte ist eine nagelneu 2GB Karte (SD) von "Dane 
Elec" und wird von allen Kartenlesern erkannt.

Zum Hardware-Aufbau: Abblock-Kerkos sind am Atmega sowie an dem 
Wannenstecker auf dem Controller-Board vorhanden. Von diesem Stecker 
geht es mit ca. 10 cm Flachband-Kabel zum Kartensockel weiter.
Der Spannungsteiler sitzt direkt am Controller. Ich versuche mal, einen 
100nF Kerko direkt am Kartensockel anzulöten, vielleicht bringt das was.

Vielen Dank soweit, ich probier mich mal weiter durch.

von Christian J. (elektroniker1968)


Lesenswert?

Hallo,

also..... wenn es schon beim Init scheitert dann würde ich mal mit dem 
Oszi an die Pins gehen und schauen was da passiert. Init ist sehr 
einfach und MUSS laufen!

Genrell: Init nur mit max 400 khz laufen lassen! Die Löung mit den 
Widerständen funktioniert vielleicht bei Radig und Co, bei mir hat sie 
nie richtig geklappt, ständig schmierte die Karte ab. Erst als ich 
richtige Treiber benutzt habe (5V-3V Wandler) lief es durch.

Vergiss nicht: Alle Kartenleser benutzen den Multimedia Mode der Karten. 
Da mag einiges anders sein als bei SPI.

von Christian J. (elektroniker1968)


Lesenswert?

Hier ist mal meine Init für PIC mit CCS Compiler
1
// *********************************************************************************
2
// Initialisieren der MMC Karte nach Power On
3
// Rückgabe: 1 = ok, 0 = Fehler
4
// *********************************************************************************
5
6
byte mmc_init()
7
{
8
  byte i;
9
10
    mmc_InitSPI(SPI_SPEED);
11
    ChipSelect(devSD,0);    // MMC Karte ausschalten
12
13
  for(i=0;i<100;i++)           // initialise the MMC card into SPI mode by sending clks on
14
     SPIMMC(0xFF);
15
16
  ChipSelect(devSD,1);    // MMC ein
17
18
  // Sende CMD0 an die Karte
19
  restart_wdt();
20
  i=0;
21
22
  do {
23
    SPIMMC(0xFF);
24
    SPIMMC(0x40);           // Sende Reset command
25
    SPIMMC(0x00);
26
    SPIMMC(0x00);
27
    SPIMMC(0x00);
28
    SPIMMC(0x00);
29
    SPIMMC(0x95);  
30
    if(++i >= 50)
31
    {
32
      f_mmc_Error   = TRUE;
33
      mmc_ErrorCode = MMC_ERR_INIT;
34
      ChipSelect(devSD,0);
35
            return (0);              // Timeout, Fehler!
36
          }  
37
  } while(!mmc_response(0x01));
38
39
  SPIMMC(0xFF);
40
  SPIMMC(0xFF);
41
  SPIMMC(0xFF);
42
  
43
  // Sendet CMD1 wiederkehrend an die Karte
44
  i = 0;
45
  restart_wdt();
46
  do  {
47
    SPIMMC(0xFF);
48
        SPIMMC(0x41);            // sende mmc Kommando um Idle Mode zu beenden
49
        SPIMMC(0x00);            // Alle Parameter sind 0x00
50
        SPIMMC(0x00);
51
        SPIMMC(0x00);
52
        SPIMMC(0x00);
53
        SPIMMC(0xFF);            // Checksumme ist immer 0xff
54
    if(++i >= 50)
55
    {
56
      f_mmc_Error = TRUE;
57
      mmc_ErrorCode = MMC_ERR_INIT1;
58
      ChipSelect(devSD,0);
59
         return (0);              // Timeout, Fehler!
60
       }
61
  } while(!mmc_response(0));
62
63
  ChipSelect(devSD,0);
64
  f_mmc_Error = FALSE;
65
  mmc_ErrorCode = NO_ERROR;
66
67
  mmc_reset();
68
69
  return (1);
70
}

von Benedikt K. (benedikt)


Lesenswert?

Gast wrote:

> Beim Beispiel von Ulrich Radig sowie dem von Roland Riegel scheitert es
> bereits an der Initialisierung. Die Funktionen brechen bereits beim
> Versuch, das erste Kommando zu senden, erfolglos ab.

Das klingt sehr nach einem generellen Problem, wie z.B. falsch 
angeschlossen, falsche Pins eingestellt, Kurzschluss auf Leitungen oder 
ähnliches.

Wie hast du den SDO Pin der Karte angeschlossen, hat dieser einen Pullup 
(ob per Software oder als Widerstand ist egal)?

von Christian J. (elektroniker1968)


Lesenswert?

>>Wie hast du den SDO Pin der Karte angeschlossen, hat dieser einen Pullup
>>(ob per Software oder als Widerstand ist egal)?

Volle Bestätigung: Ohne diese Pull Ups läuft es auch nicht, sonst 
floaten Dir die Pins.

von Gast (Gast)


Lesenswert?

Also, habe mal einiges überprüft:
Kurzschlüsse: nein
Pins vertauscht: nein
Pins falsch eingestellt: nein
Pullups vorhanden: Ja (zusätzlich eingelötete 10k-Widerstände brachten 
auch keine Veränderung)

Noch dazu ergänzt: 100nF Kerko + 10µF Elko direkt am Kartensockel - 
erfolglos.
Einen Pegelwandler zu ergänzen ist leider nicht möglich weil mir dazu 
Bauteile+Zeit fehlen...

Ich habe mir mal mit dem Oszi die Signale angeschaut. Das Takt- und 
Datensignal vom Atmega sieht aus wie sonstwas, überlagert mit allem 
möglichem.
Aber: Die Karte liefert ein absolut sauberes Ausgangssignal, dass 
allerdings nicht weiter verarbeitet wird. Irgendwo muss da der Hund 
begraben liegen, ich werde den Aufbau noch einmal genau durchgehen.

Jetzt beim Schreiben bemerke ich, wenn man mit einem 1:1 Tastkopf an der 
Taktleitung misst, springt das Programm auf einmal einen Schritt weiter 
und sagt "MBR Signatur not found". Das deutet doch auf einen Fehler im 
Aufbau hin, vermute ich.

von Benedikt K. (benedikt)


Lesenswert?

Es kann Zufall sein, oder wahrscheinlicher: Timingprobleme aufgrund der 
zu hochohmigen Spannungsteiler. Das Taktsignal sollte eigentlich sehr 
sauber sein, und man sollte deutlich 8 Takte am Stück, danach eine 
kleine Pause und dann wieder 8 Takte und das ganze mehr oder weniger oft 
erkennen können.

von Detlev T. (detlevt)


Lesenswert?

Gast wrote:
> Das Problem bei der Sache ist, morgen sollte der Aufbau laufen, deswegen
> fallen größere Änderungen wie z.B. Pegelwandler leider flach.
> Einen Atmega32L müsste ich auch wieder bestellen, außerdem kämen dann
> wieder größere Probleme auf mich zu, da noch ein MAX232, ein LCD und
> mehrere Controller über I2C angeschlossen sind, die sich wahrscheinlich
> nicht sofort mit den 3,3V des Controllers vertragen werden.

Wenn du nicht unter 2,7V gehen willst, brauchst du keine 
Low-Voltage-Version. Schaue einmal ins Datenblatt. bei 12MHz müsste 3,3V 
so gerade noch gehen (müssten zwar eigentlich 3,5V sein). Es gibt auch 
RS232-Pegelwandler und 3,3V-kompatible LCD-Anzeigen - die DOGM-Typen von 
Electronic Assembly.

Bis morgen ist aber alles natürlich ziemlich knapp.

von Gast (Gast)


Lesenswert?

>Timingprobleme aufgrund der
>zu hochohmigen Spannungsteiler

DAS war das richtige Stichwort. Ich habe jetzt den Spannungsteiler für 
den Takt einfach mit halbierten Widerstandswerten aufgebaut und außerdem 
mit einem einfachen 0815-Transistor dem ganzen etwas mehr Dampf gemacht, 
jetzt scheint es zu funktionieren. Zumindest gibt der Controller nach 
dem einlegen der Karte ein Verzeichnis-Listing aus. Lese/Schreibzugriff 
werde ich jetzt mal probieren.

@Detlev T.: Den gesammten Aufbau auf 3,3 V umzubauen wäre mir schlicht 
zu viel Aufwand. Es ist ja nicht nur der eine Controller mit der 
Speicherkarte, daran sind noch mehrere Controller angeschlossen die so 
ohne weiteres nicht mit 3,3V laufen würden (u.A. hochgenaue 
Temperatur-Sensoren, zwei H-Brücken mit PWM-Ansteuerung und jeweils 120 
Watt Leistung, eine 8-Kanal 230V Schalterkarte usw.)

Dieser Controller ist ein I2C-Master, der eben diese Module steuert. Mit 
dem Master auf 3,3 V und den Slaves auf 5V läuft garnichts, habe ich 
schon probiert (einfach am Netzteil die Spannung runtergedreht). Die 
Debug-LED blinkt munter weiter und auf den Bussen ist auch etwas zu 
sehen, allerdings reichen die Pegel einfach nicht aus.

Vielen Dank euch allen für die Tips, jetzt funktioniert es ja scheinbar. 
Mal sehen, wie lange ;-)

von Christian J. (elektroniker1968)


Lesenswert?

Habe mal angefangen den mit einem CASE Tool erstellten Code 
zusammenzustreichen, um dutzende #defines zu erleichtern und anders zu 
formatieren, kompakter zu machen und alles raus was mit AtMega zu tun 
hat, da ich ARM nutze.

Wird gleich viel lesbarer :-) Vielleicht nehme ich den auch statt der 
erschlagenden efsl, die 20kb Flash verbraucht.

von Detlev T. (detlevt)


Lesenswert?

Gast wrote:
> DAS war das richtige Stichwort. Ich habe jetzt den Spannungsteiler für
> den Takt einfach mit halbierten Widerstandswerten aufgebaut und außerdem
> mit einem einfachen 0815-Transistor dem ganzen etwas mehr Dampf gemacht,

Das würde mich interessieren. Wie hast du das gemacht?

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Meine Spannungsteiler waren seinerzeit mal aus 1.8k und 3.3k 
Widerständen zusammengelötet und funktionierten an einem Mega128 
bestens. Inzwischen betreibe ich Karten und Controller wenn irgendwie 
möglich mit 3.3V und alles ist gut. Aber es ist seitens des Forums nicht 
unbedingt fair, immer auf die Spannungsteilervariante zu schimpfen, denn 
an einem 8Mhz SPI funktionieren diese weitestgehend einwandfrei, mit den 
oben angegebenen Werten.

von Simon K. (simon) Benutzerseite


Lesenswert?

Travel Rec. wrote:
> Aber es ist seitens des Forums nicht
> unbedingt fair, immer auf die Spannungsteilervariante zu schimpfen, denn
> an einem 8Mhz SPI funktionieren diese weitestgehend einwandfrei, mit den
> oben angegebenen Werten.

Wie immer: Kommt auf die Karte an.

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Nicht wirklich. Die Flankensteilheit ist bei den gewählten 
Widerstandswerten vorgegeben und die Pinkapazität ist bei allen Karten 
relativ gleich. Vermeiden sollte man einen zu großen Abstand der Karte 
von den Spannungsteilern oder gar das Anbinden des Kartenslots mit 
Flachbandkabel länger als 10cm. Das geht auch bei direkten 3.3V-Systemen 
in die Hose.

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.