Forum: Mikrocontroller und Digitale Elektronik Elm Chan's FatFs - SD-Karte


von Freddy (Gast)


Lesenswert?

Hi,
ich wollte mal fragen, ob einer von euch Erfahrungen mit Elm Chan's 
FatFs System gesammelt hat. Ich habe jetzt verschiedenste Sachen 
ausprobiert, bekomme das teil aber nicht zum laufen (nicht wie ich will 
zumindest). Habe erst diese Anleitung probiert:
http://www.basementcode.com/avr/sd_fatfs/fatfs.php

Danach selbst an den Dateien editiert und Fehlersuche betrieben, die 
mich allerdings auch nach Stunden nicht weiterbrachte. Jetzt habe ich 
diese Anleitung gefunden:
http://www.frank-zhao.com/index.php?page=fat_sd

Problem ist bei dieser: Sie scheint zu funktionieren für meine 128mb 
SD-Karte von "extreMEmory". Jedoch nicht bei meiner "Hama" mit 512mb und 
nicht bei meiner "SanDisk" mit 2GB (die eigentlich in dem System 
arbeiten soll).

Hat einer schonmal so eine SanDisk zum laufen gebracht und kennt 
vielleicht ein grundlegendes Problem das ich übersehe?

von Mike (Gast)


Lesenswert?

Hallo,

ich habe gerade FatFs implementiert und kann jetzt Micro-SD Karten von 
1GB (SanDisk) bis 16GB (Medion) problemlos lesen und schreiben.
Eigentlich sollte es nicht von der Karte abhängen wenn doch, folgende 
Punkte abklären:

1. Wo tritt der Fehler auf? Beim Initialisieren, Lesen oder Schreiben?

2. Stimmt die Versogungsspannung der Karte? Manche Karten sind hier 
pingeliger als andere. Eine Versorgung direkt aus einem Portpin halte 
ich für sehr kritisch, besser einen Transistor/Mosfet nachschalten.

3. Zum Initialisieren muss die SPI-Taktfrequenz auf <= 400kHz 
herabgesetzt werden, danach sind bis zu 25MHz erlaubt.

Welche Low-Level-Treiber benutzt Du? Die sind bei FatFS normalerweise 
nicht dabei, ich habe sie mir daher selbst geschrieben. Nachdem diese 
dann funktionierten, gab es mit FatFs keine Probleme mehr.


Gruss
Mike

von Freddy (Gast)


Lesenswert?

Hi,
danke schonmal für deine Antwort.
Ich benutze die Low-Level Treiber, die in den Examples für AVRs dabei 
sind (mmc.c und diskio.h).

1. Der Fehler tritt bei der Initialisierung auf. Scheint also doch ein 
Low-Level-Problem zu sein. Hatte die eigentlich schon durchgeschaut und 
nichts gefunden, was nicht auch so in den Manuals von SanDisk 
dringewesen wäre (also welches Kommando welche Antwort braucht usw.).
2. Wir betreiben die Karte direkt mit einem 3,3V Schaltregler mit wenig 
Spannungsrippel (genauen Wert kann ich erst heute Abend messen, glaube 
es waren um die 8mV).
3. Zum Initialisieren haben wir die Frequenz auf 12,5 KHz, danach auf 
4MHz.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Guck mal hier:
http://www.mikrocontroller.net/articles/AVR_FAT32
Alles fertig, einbinden, läuft.

Kannste dann als Alternative nehmen, wenne elmchan ganich zum laufen 
bringst

von holger (Gast)


Lesenswert?

>2. Wir betreiben die Karte direkt mit einem 3,3V Schaltregler mit wenig
>Spannungsrippel (genauen Wert kann ich erst heute Abend messen, glaube
>es waren um die 8mV).

Und wie ist die Karte an den AVR angeschlossen?

von Freddy (Gast)


Lesenswert?

Ist direkt am PortB des ATMEGA32 angeschlossen (der läuft auch mit den 
3,3V).

@Martin Wende:
Danke, tut jedoch nicht ^^
Den TimingDelay muss man da auch wieder über eine ISR einfügen, die alle 
10ms ausgelöst wird, oder?

Habs so eingebunden wie's hier: 
"http://www.mikrocontroller.net/articles/AVR_FAT32"; angegeben ist, 
jedoch scheint keine der Karten richtig zu initialisieren (getestet mit 
128mb, 512mb und 2GB Karte).

von Freddy (Gast)


Lesenswert?

Kann dummerweise nicht editieren:
Ja, blöderweise die main.c übersehn mit dem Beispiel drin, also hab den 
Timer wie dort angegeben drin. Initialisierung klappt jedoch nicht.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Was fürn Timer? Kopfkratz

Hat der Herr wohl nen Update gemacht und ich gurk noch mit der alten 
Version rum.
Alte Version:
http://www.fritzler-avr.de/HP/Librarys/LIBs/SD_MMC.rar

von Freddy (Gast)


Lesenswert?

Danke dafür,
hab jedoch ein Problem, das einzubinden. Habe ein C++ Projekt und 
bekomme immer "undefined reference" für verschiedene Funktionen, wenn 
ich nur die .h also die Headerfiles per "#include" einbinde. Binde ich 
zusätzlich die .c Dateien per "#include" ein (ja, das tut man nicht und 
nein, ich weiß mir nicht besser zu helfen), bekomme ich den Fehler:
"ISO C++ forbids incrementing a pointer of type 'void*'". hab jetzt alle 
void* mal in char* geändert, scheint der kompiler (AtmelStudio) wohl zu 
nehmen. Hab jetzt aber wieder das Problem einer "multiple definition of 
'card_type'" die, denke ich zumindest, von meiner Einbindung von .c und 
.h kommt.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Das is jetz aber doof, zu C++ kann ich absolut ganix sagen.
Schubs doch mal den Schaltplanausschnitt rüber.
Software SPI oder Hardware?

Zur Not schieb ich dir mal ne .hex Datei rüber die dann per UART ausgibt 
ob er die Karte mit dieser lib initen kann oder nicht.

von Patrick C. (pcrom)


Lesenswert?

Ich habe probleme mit Sandisk 2Gb karten. Ich habe hier 4 verschiedene 
karten von Sandisk-2Gb (micro-sd), alle 4 das gleiche bestellnr aber 
ausserlicht sind die unterschiedlich (made in...; text an vorne oder 
hintere seite). 2 von die Sandisks typen funktionieren gut, 2 davon 
geben manchmal probleme mit
schreiben und sowieso mit formattieren.

Das formattieren kannst du sowieso als guten test benutzen um zu testen 
ob bestimmte karten funktionieren oder nicht. Ich habe selber die 
erfahrung das als die formattierung ohne problemen verlauft, hat man 
nachdem auch keine probleme mit die karten.

Deswegen brache ich jetzt fuer alle 100 platine die ich habe Verbatim 
2Gb sd-karten. Und hab ich mir noch 400 stueck extra davon gekauft fuer 
zukunft

Patrick

von Freddy (Gast)


Angehängte Dateien:

Lesenswert?

Ich versuch jetzt nochmal die Initialisierung zum laufen zu bringen.
Hier der Schaltplanausschnitt (Stützkondensatoren fehlen, sind aber an 
jedem Vcc Pin angebracht, 100nF).

Pins sind richtig verbunden, wie gesagt, mit der 128mb Karte hat's 
schonmal getan, jedoch eben nicht zuverlässig.

Gut, dann bin ich vielleicht schonmal nicht ganz doof, wenn andere auch 
schon Probleme mit den SanDisk Karten hatten ^^
Das mit dem formatieren werd ich versuchen, geht aber auch erst, wenn 
die Initialisierung richtig funktioniert.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

Lesenswert?

Klopp das mal rauf und Probiers aus.

//LED PA7: main läuft
//LED PA6: SD karte gefunden
//LED PA5: kein Dateisystem
//LED PA4: okidoki

Is aus nem funktionierenden Projekt, daraus die SD init rausextrahiert.

von Freddy (Gast)


Lesenswert?

Kommt nur "unterschied bei Byte 1232".

von Freddy (Gast)


Lesenswert?

Arg, sry, SD drin gehabt beim brennen. So, jetzt isses drauf:
Ergebnis: Tut sich absolut nichts.

von Freddy (Gast)


Lesenswert?

Folgender Code sollte nach meiner Interpretation mit CMD0 die SD in den 
SPI Mode holen, mit CMD1 die SD initialisieren und mit CMD16 die Länge 
auf 512 Byte stellen. Der SPI mode scheint zu gehen, die initialisierung 
auch, jedoch kommt keine richtige Antwort auf das CMD16...
1
char SPI_Transmit(char Data)
2
{
3
  //Start transmission
4
  SPDR0 = Data;
5
  //Wait for transmission complete
6
  while(!(SPSR0 & (1<<SPIF0)))
7
  ;
8
  return SPDR0;
9
}
10
11
12
int main(void)
13
{
14
  /*** Set Direction and Port States ***/
15
  IOInitialize();
16
  PORT_LED = ~0b00001111;
17
  
18
  //Set MOSI and SCK output, all others input
19
  DDR_SD |= (1<<P_MOSI)|(1<<P_SCK);
20
  PORT_SD &= ~((1<<P_SCK)|(1<<P_MOSI)|(1<<P_MISO));
21
  //Enable SPI, Master
22
  SPCR0 |= (1<<SPE0)|(1<<MSTR0);
23
  //Set Clockrate fosc/128
24
  SPCR0 |= ((1<<SPR00)|(1<<SPR10));
25
  SPSR0 &= ~(1<<SPI2X0);
26
  //PORT_SD &= ~(1<<P_CS_SD);
27
  PORT_SD |= (1<<P_CS_SD);
28
  _delay_ms(5);
29
  
30
  
31
  //Send Clocks for Synchronization (by sending dummys)
32
  for(int i=0; i<10; i++)
33
  {
34
    SPI_Transmit(0xFF);
35
  }
36
  //Chip enable SD-Card
37
  PORT_SD &= ~(1<<P_CS_SD);
38
  
39
  //Send CMD0 to get the SD-Card to SPI-Mode
40
  SPI_Transmit(0x40);
41
  SPI_Transmit(0x00);
42
  SPI_Transmit(0x00);
43
  SPI_Transmit(0x00);
44
  SPI_Transmit(0x00);
45
  SPI_Transmit(0x95);    //CRC required
46
  //Waiting for the SD-Card to confirm SPI-Idle-State
47
  while(SPI_Transmit(0xFF) != 1)
48
  ;
49
  
50
  bool initSD = false;
51
  char initSDconfirmation = 0;
52
  
53
  while(initSD == false)
54
  {
55
    //CMD1 to initialize the SD-Card
56
    SPI_Transmit(0x41);
57
    SPI_Transmit(0x00);
58
    SPI_Transmit(0x00);
59
    SPI_Transmit(0x00);
60
    SPI_Transmit(0x00);
61
    SPI_Transmit(0xFF);    //CRC not longer required
62
    
63
    //Look for one of the next 100 answers to be initialization-confirmation
64
    for(int j=0; j<255; j++)
65
    {
66
      initSDconfirmation = SPI_Transmit(0xFF);
67
      if(initSDconfirmation == 0)
68
      {
69
        PORT_LED = ~0b11110000; <<<<<<<<<<<<<<<<<< LEUCHTET AUF!
70
        initSD = true;
71
        break;
72
      }
73
    }
74
  }
75
  
76
  bool rerSD = false;
77
  char rerSDconfirmation = 0;
78
  
79
  while(rerSD == false)
80
  {  
81
    //CMD1 to initialize the SD-Card
82
    SPI_Transmit(0x50);
83
    SPI_Transmit(0x00);
84
    SPI_Transmit(0x00);
85
    SPI_Transmit(0x02);
86
    SPI_Transmit(0x00);
87
    SPI_Transmit(0xFF);    //CRC not longer required
88
    
89
    for(int k=0; k<255; k++)
90
    {
91
      rerSDconfirmation = SPI_Transmit(0xFF);
92
      if(rerSDconfirmation == 0)
93
      {
94
        rerSD = true;
95
        ORT_LED = ~0b00001111; <<<<<<<<<<<<<<<<<< LEUCHTET NICHT AUF!
96
        break;
97
      }
98
    }
99
  }

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Freddy schrieb:
> Ergebnis: Tut sich absolut nichts.

Hab mal grad nen Mega32 rausgekramt und in die Platine gesteckt.
Jap tut sich nix, was ich sehr komisch finde, denn mit dem Mega644P 
funktionierts.
Natürlich jeweils das Makefile angepasst...
Sehr Merkwürdig, da der Code weder Interrupts noch Timer nutzt.
Nur die Library und die SPI register beider Prozessoren sind gleich.



Geh doch mal vom LED debugging zum UART debugging über.
Also lass dir aufm UART ausgeben was die SD Karte zurücksendet oder 
klemm nen Buspirat ran.

von Freddy (Gast)


Lesenswert?

Hab nen Oszi drangehängt: CMD16 gibt ein "Illegal Command" aus. Hab kurz 
gedacht es wäre, weil ich vergessen habe nochmal zwischen CMD1 und CMD16 
ein 0xFF zu senden, damit die SD nochmal clocks bekommt, grad eine
1
while(SPI_Transmit(0xFF) != 0xFF)
2
 ;
reingemacht, ändert jedoch nichts, trotzdem illegal command...

von Freddy (Gast)


Lesenswert?

Hab jetzt denke ich CMD0, CMD1 und CMD16 zum laufen gebracht. Bekomme 
aber beim ausführen von
1
ff_open(&logFile, "/text.txt", FA_READ | FA_WRITE | FA_CREATE_ALWAYS)
den Fehler Nr.13, kein Dateisystem vorhanden.
Versucht mit f_mkfs zu formatieren-> gibt keinen Fehler aus, bringt aber 
auch nichts.

Muss man bei der SD Formatierung am PC irgendwas bestimmtes beachten, 
was ich grade völlig übersehe?!?

Danke schonmal =)

von Freddy (Gast)


Lesenswert?

Problem gelöst: SD-Karte defekt. Haben's jetzt auf ner zweiten Platine 
getestet mit anderer SD getestet, tut.

Danke für eure Bemühungen, mit so einem Ergebnis habe ich nicht 
gerechnet. Auf dem Oszi schienen die Antworten der SD zu passen.

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.