Forum: Projekte & Code MMC SD library FAT16 FAT32 read write


von Daniel R. (zerrome)


Lesenswert?

@ JVOGEL (Gast)
Ich würde sagen Dein SPI läuft nicht richtig.

Um den von Kurt Bohnen (kurt) angesprochenen Bug zu beheben, müssen 
folgende Zeilen in der Datei file.c in der Funktion fflushFileData() 
ausgetauscht werden:
1
// cluster chain verketten
2
fat_setClusterChain(fat_secToClust(chain.startSectors),fat_secToClust(file.currentSectorNr));  // verketten der geschriebenen cluster

durch
1
    // cluster chain verketten.
2
    if(file.cntOfBytes == 0){                // gerade genau irgend einen sektor voll geschrieben.file.currentSectorNr zeigt jetzt auf den neu zu beschreibenden.
3
      if( file.currentSectorNr-1 >= chain.startSectors ){
4
        fat_setClusterChain(fat_secToClust(chain.startSectors),fat_secToClust(file.currentSectorNr-1));  // verketten der geschriebenen cluster
5
      }
6
    }
7
    else fat_setClusterChain( fat_secToClust(chain.startSectors),fat_secToClust(file.currentSectorNr) );

Vielen Dank für den Hinweis und viele Grüße

Daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Da ich mich irgendwie nicht mehr beim SVN anmelden kann um die neue 
Version hochzuladen, poste ich die erstmal hier...

von Kurt B. (kurt)


Lesenswert?

Vielen Dank Daniel, jetzt läuft es perfekt! Allerdings hast du vergessen 
das ACMD41 von (0x80+41) auf (41) zu ändern.

@JVOGEL,
hast du einen PullUP an MISO? Auch der /SS des µC braucht einen Pullup, 
oder muss auf Ausgang geschaltet werden.

Mfg,
Kurt

von jvogel (Gast)


Lesenswert?

Hi, danke schonmal für die Tipps. Hatte gestern keine Zeit mehr zu 
testen und heute bin ich erst einmal auf der arbeit. Meinst du einen 
Pullup in form des internen oder ein externen Pullup? Wenn er nicht 
schon in der Programmierung eingebunden ist dann eher nicht, aber ich 
kann auch mal ein Foto meiner Schaltung machen, heute Abend. Der halbe 
Sonntag hab ich damit verbracht, leider bisher ohne Erfolg.

Habe ja einen spannungteiler mit 470ohm / 620 Ohm ist wirkt der nicht 
wie ein Pullup?

Bin erstma ein Kaffee trinken ;)

von jvogel (Gast)


Lesenswert?

Habe mir gestern in die Methode spi_write_command? oder so ähnlich ein 
puts("test"); rein gemacht und das ergebnis war dann ungefähr:

Boot test test

also bleibt er beim 2. mal dort hängen bei
1
loop_until_bit_is_set(SPSR,SPIF);

von Daniel R. (zerrome)


Lesenswert?

Hallo,
also nimm diese Version: 
http://www.mikrocontroller.net/attachment/105372/mmc-0.6.3.zip

Da musst Du aber noch in der mmc.c oben bei den defines folgendes 
ändern, weil ich das verpeilt hab:
1
#define  ACMD41  (0x80+41)
auf
1
#define  ACMD41  (41)

So, dann solltest Du zum testen auf jeden Fall erstmal hardware SPI 
benutzen. Bei deinem Spannungsteiler komm ich nur auf 2,844 Volt. Das 
ist bisschen wenig. Und eigentlich generell mist, dass mit dem 
Spannungsteiler!
Betreibe die Schaltung am besten mit 3,3 Volt. Was genau spricht bei Dir 
dagegen?

Zum berechnen der nötigen Timer Werte benutze ich immer folgendes Tool:
http://clsql.med-info.com/download.html
Wie sehen Deine Timer Werte aus?

Bild von der Schaltung wäre gut.

Ich bin mir sicher, dass wir das ans laufen bekommen :)

Viele Grüße

Daniel

von jvogel (Gast)


Lesenswert?

Hatte zuletzt einen spannungsteiler mit 290 ohm / 620 Ohm.

Das problem, dass ich habe ist das mein MAX232 mit 3.3V nicht so richtig 
funktionieren möchte, manchmal liest man, dass er mit 3.3V laufen würde 
aber bei mir leider nicht. Mein LCD Display funktioniert leider auch nur 
mit 5V.

Aber zum testen baue ich mir nachher eine LED auf mein Breadboard um den 
Status anzeigen zu lassen, dann kann ich auch 3.3V verwenden.

Ich hoffe, dass ich heute abend Zeit finde, dann bauch ich mir die 
Schaltung nochmal neu auf (Ohne Spannungsteiler)und mache dann ein Foto 
falls es, dann immer noch nicht geht. Und meinen Sourcecode hänge ich 
dann auch nochmal komplett an.

Vielen dank schonmal im vorraus.

von Daniel R. (zerrome)


Lesenswert?

Ok, dann mach lieber einen Spannungsteiler beim max232 um auf 3,3 Volt 
zu kommen. LCD Displays brauchen nur an der Versorgungsspannung 5 Volt. 
Zu mindest die die ich habe. Beim max232 würde dann sogar nur der RX 
Pfad zum Kontroller als Spannungsteiler reichen. Da TX ja 3,3 Volt wäre 
und das als Hi Pegel reicht...

>Breadboard

Damit hatte ich auch immer Probleme wenn es um SD Karten ging. Extrem 
kurze Kabel und Kontroller 3,3 Volt und SD Karte 3,3 Volt helfen da 
aber.

Mann muss da bedenken, dass die Karten mit 25 MHz spezifiziert sind, da 
sind saubere Flanken ein muss!

Also zusammenfassend.

Kontroller 3,3 Volt
SD/MMC 3,3 Volt
LCD 5 Volt Versorgung und 3,3 Volt Datenleitungen
MAX232 <- TX Kontroller direkt
       -> RX Kontroller Spannungsteiler auf 3 Volt

Viele Grüße

Daniel

von jvogel (Gast)


Lesenswert?

Hatte mich verschrieben, MAX323 habe ich.

von Daniel R. (zerrome)


Lesenswert?

Hm, ok mal doch mal nen kompletten Schaltplan, ich kann mir grad die 
ganze Schaltung nur schwer vorstellen.

Zu MAX323 find ich nur "Precision, Single-Supply, SPST Analog Switches" 
?

von JVOGEL (Gast)



Lesenswert?

So hab mich doppelt vertan, hab den MAx232 der funktioniert aber leider 
nicht bei 3.3v bei mir.

So hab jetzt bilder gemacht, und alles :(
vielleicht kann mir wer den helfenden schlag auf den hinterkopf geben.

von JVOGEL (Gast)


Lesenswert?

Das mit der LED an PORTA vergessen :D da war ich betrunken oder so

von Daniel R. (zerrome)


Lesenswert?

Ok, das 2. Bild ist der Max232?

Ich sehe garkeine Pegelwandlung zwischen uC und SD Karte?
Läuft da alles mit 3,3 Volt?

Toll das Bild vom Multimeter :)
Wo geht das Kabel hin?!?

Ist das da ein ISP Programmier Adapter?
Den machst Du aber nach dem Programmieren immer ab oder?

Bei Deinen Test würde ich Dir empfehlen diese Einstellung in der 
mmc_config.h noch zu machen.
1
#define MMC_MAX_SPEED FALSE


Viele Grüße

Daniel

von jvogel (Gast)


Lesenswert?

Ja im 2. Bild ist der Max232,

Multimeter kabel gehen  an das Breadboard aussen an jeweils ein stift in 
+ und GND.

Der ISP Programmieradapter ist ein USB <--> ISR Programmier adapter der 
gibt der schaltung den 5V Saft, oder bene 3,3V jenachdem was man dort 
mit einem Schalter einstellt.
Der bleibt eigentlich immer dran, oder ist das schon das problem, dass 
das SPI dadurch gestörrt wird? Bzw vom ISP Programmierer als Master 
verwendet wird? :)

von Daniel R. (zerrome)


Lesenswert?

Ja der Programmier Adapter könnte schon das Problem sein.

von JVOGEL (Gast)


Lesenswert?

So hab nun zwei dräht in den ISP programmer gesteckt fuer VCC und GND 
aber funtkioniert trozdem nicht und der MAX232 geht auch immer noch nit 
mti 3.3v :(
 manno

von Daniel R. (zerrome)


Lesenswert?

Ok, ich weiß nicht genau wo ich anfangen soll...

1. Nimm einen anständigen 3,3 Volt Regler der 1 A Strom liefert.
2. Nimm eine Anständige Quelle die den Regler speist!
3. Klemm nur die SD Karte an die SPI Schnittstelle.
4. Überprüfe alle Anschlüsse und Einstellungen im Code 3 mal!

Zu dem Max232 hatte ich Dir schonmal was geschrieben,
5 Volt Versorgung und dann an die RX TTL Seite einen Spannungsteiler!
Weißt Du was ich damit meine?

Du solltest Dir Methoden überlegen wie Du Hardware debuggst.
Mein Vorschlag: Modul weise Prüfen ob es geht und dann nach und nach 
zusammenschalten...





@ Sven S. (schwerminator)
Bist Du weiter gekommen mit diesen seltsamen Spikes da?



Viele Grüße

Daniel

von JVOGEL (Gast)


Lesenswert?

IN AVR Studio hab ich:

Device: atmega32
Frequency: 16000000
OPTIMIZATION:-O2


Ok dann muss ich warten bis ich eirder zum gelben C komme. Hab hier nur 
noch einen 3v Regler und einen 5v. Ein Stabilisiertes Netzteil hab ich 
noch und eine passende buchse dazu.
So kann ich dann auch die verschiedenen Komponente mit 5v oder 3,3v 
gleichzeitig speisen.

von JVOGEL (Gast)


Lesenswert?

@Daniel R.
ja zwischen RXD und R1 out einen spannugnteiler, damit der Atmega kein 
5v High signal bekommt, weil er mit 3.3v läuft.

von Daniel R. (zerrome)


Lesenswert?

Hm, 3 Volt sollte auch gehen. Hauptsache ein richtiger Regler.
So eine SD Karte zieht auch schon mal gerne 200 mA oder mehr kurzzeitig.

Ich hab gerade keine Lust die Pinbelegung vom Max232 nachzuschauen, aber 
ja so meinte ich das. Zwischen Max232 RX und Kontroller RX den 
Spanungsteiler

Mit Einstellungen im Code meinte ich die Pin Einstellungen falls Du sie 
geändert hast, halt sonst noch alle Änderungen im Code. Dann alle Kabel 
Verbindungen usw...


Viele Grüße

Daniel

von JVOGEL (Gast)


Lesenswert?

Ok ich tüfftel das mal die Tage zusammen und melde mich dan nochmal,

1000x Dank schonmal

von JVOGEL (Gast)


Lesenswert?

Ich glaub ich hat nen kurzen und entweder der MAX232 oder der RS232 port 
an meine PC hats durchgeknallt, naja ich lass es jetzt erstmal bis ich 
mal wieder ruhige minuten habe die tage.

von Dome k. (jvogel)


Lesenswert?

Also ergebnis bisher:

MAX232 kann nicht defekt sein, da ich einen neuen Ausgetauscht habe und 
der funktioniert auch nicht.

Atmega32 ist auch nicht defekt, habe ich auch ausgetauscht.

Weiss einer wie ich schnell einfach testen kann ob der RS232 port am pc 
nen knacks bekommen hat?

von Daniel R. (zerrome)


Lesenswert?

RX und TX brücken, dann solltest Du genau das empfangen was Du sendest.

von Dome k. (jvogel)


Lesenswert?

Ok, test Negativ. Ich glaub meine RS232 ist match...

von Buzzwang (Gast)


Lesenswert?

Momentan probiere ich die neuste LIB(0.6.3) aus.
Ich bin von der 0.6.1 umgestiegen

2 Sachen waren zu beachten:
 - Im Dateinamen muss nun ein Punkt sein (8.3). LFN ist bei mir aus
 - Das Chip_select Define ist rausgeflogen und die Pin-Belegung war 
dadurch falsch.

Übersetzen mit
  #define MMC_MULTI_BLOCK   TRUE
ging nicht.

von Matze N. (hupe123)


Lesenswert?

> 2 Sachen waren zu beachten:
>  - Im Dateinamen muss nun ein Punkt sein (8.3). LFN ist bei mir aus
>  - Das Chip_select Define ist rausgeflogen und die Pin-Belegung war
> dadurch falsch.


Kannste dazu mal etwas mehr schreiben?
-> in der Vorlage "main_simple.c" ist doch im dateinamen ein "."
-> wie hast du das Problem mit dem MMC_CHIP_SELECT gelöst. Is mir eben 
auch erst aufgefallen. Umgelötet oder einfach die Pinnummer geändert?

Grüße,
Matze

von Matze N. (hupe123)


Lesenswert?

So, habs dann auch zum laufen bekommen und kann meine Fragen jetzt für 
alle beantworten:

-> Beim Dateinamen nuss nichts geändert werden (zumindest beim 
AVR-Studio 4 und 5beta)
-> Die SD-Karte wird kompett (und nich wie im Wiki angegeben) an den 
SPI-Port angeschlossen. Falls aus einer älteren Version die Leitung vom 
CS der Karte an einen anderen PIN als den SS geht, dann muss das 
geändert werden...

Grüße,
Matze

von Matze N. (hupe123)


Angehängte Dateien:

Lesenswert?

Hi,
ich hab da nen Problem. Ich würde gerne Verzeichnisse anlegen und in 
dieses Verzeichnis eine Datei.
Wenn ich die Datei ohne Verzeichnis anlegen lasse, dann funzt alles! 
Wenn ich allerdings erst das Verzeichnis anlege und das öffne um darin 
dann die Datei zu platieren, dann bekomme ich nur Datenmüll.

Hier der Code, mit dem ich das Verzeichnis anlege und hinein wechsel:
1
  unsigned char datum_verzeichnis[] = "12345678";      
2
  ffmkdir(datum_verzeichnis);
3
  ffcd(datum_verzeichnis);
4
  _delay_ms(10);
(Die Pause an Ende nahm ich mit rein, da ich dachte, daß mein µC (ein 
ATmega128) versucht die Datei anzulegen bevor das Anlegen des 
Verzeichnisses abgeschlossen ist (-> Datendurcheinander).

Der Screenshot von dem, was mir WindowsXP SP3 anzeigt, wenn ich die SD- 
Karte einlege, is im Anhang.

Kann sich das jemand erklären?!
Ohja: Wie erwähnt: PC: Win XP SP3, µC: ATmega128, 3,3V, SD ohne Zusatz 
an SPI, Compiler AVR Studio

Grüße,
Matze

von Daniel R. (zerrome)


Lesenswert?

Hm, schau ich mir heute Abend mal an.
Möglicherweise ist da was durcheinander gekommen bei den 
Versionsänderungen.
Mag ich jetzt mal nicht ausschließen.

Viele Grüße

Daniel

von Matze N. (hupe123)


Lesenswert?

Hi,

Ich würde gerne das Einfügen von Daten in eine Datei in deine Funktion 
implementieren.
Mit Einfügen meine ich:
z.B. aus einer TXT Datei mit dem Inhalt: "Hallo Welt!" Durch einfügen 
von "schöne, neue " an die Stelle 6 "Hallo schöne, neue Welt°" zu 
machen.

Ich habe mir gestern darüber gedanken gemacht und würde dir die gern 
kurz vorstellen, damit du mir ein paar Tipps geben kannst, was ich 
möglicherweise vergessen habe:

1) mit ffseek(x); zu der einzufügenen Stelle springen.
2) mit der Bedingung ("512 - file.cntOfBytes" aus z.B. ffseek() ) die 
restlichen Bytes aus dem Sektor in einer Variablen zwischenparken damit 
sie nich überschrieben werden
3) in einer Variablen die "Nummer" des Folgesektors merken
4) normales Schreiben der einzufügenen Daten (hier "schöne, neue ")
5) zurückschreiben der Daten aus 2)
6) in der Fat Tabelle die Folgesektornummer von 3) angeben, um das alles 
auch wieder schön zu verknüpfen

Das klingt ja erstmal gar nicht schwer. Jedoch weiß ich noch nicht mit 
welches Funktionen ich die aktuelle Sektornummer und die 
Folgesektornummer auslesen kann.
Zudem weiß ich noch nicht, wie ich die Fat-Tabelle aktuallisieren soll:
macht es Sinn die gesamte Tabelle auch in einer Var. zu parken (vgl. 2) 
) um dann normal schreiben zu können. Nebenbei merke ich mir, wieviele 
Einträge ich in die Fat Tabelle mache und schreibe den Inhalt aus Fat- 
Variablen dann einfach wieder an die richtige Stelle zurück? Aber wie 
kann ich in der Fat-Tabelle schreiben?

Du siehst, noch ein paar Fragen, aber eigentlich müsste das doch möglich 
sein, oder?!

Grüße,
Matze

von Daniel R. (zerrome)


Lesenswert?

Hm, diese Diskussion hatten wir da schon mal : 
Beitrag "Re: MMC SD library FAT16 FAT32 read write"

Ich bin zu dem Schluss gekommen,dass es nicht so ohne weiteres möglich 
ist, weil man entweder immer ganze Cluster einfügen müsste. Oder man 
muss die kompletten Daten nach den eingefügten "aufrücken".

Keine Ahnung wie ein Betriebssystem das macht. Wenn ich da in eine 2 GB 
große Datei was einfüge, werden sicher nicht alle Daten umkopiert, oder 
doch?!?

Viele Grüße

Daniel

von Matze N. (hupe123)


Lesenswert?

Aber ein Sektor muss doch nicht zu 100% voll mit Daten besetzt sein. Von 
daher müsste das doch gehen. Das einzige, was ein bißchen aufwendig 
werden könnte, wäre das erneuern der FAT- Tabelle.

Ich werde das mal angehen, wenn ich etwas zeit habe. Aber kannst du mir 
noch kurz sagen, wie ich die Fat- Tabelle auslese, Daten hineinschreibe, 
usw.?

Grüße

von Daniel R. (zerrome)


Lesenswert?

Hallo,
ich hab da im Wiki ein wenig zu geschrieben.
Falls Du danach noch Fragen hast, stell sie :)


Nur der letzte Cluster einer Fat Kette muss nicht voll besetzt sein. 
Alle anderen davor schon. Man kann also nicht einfach einen halb vollen 
Cluster mitten in die Kette schummeln...

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Hallo,
es gab tatsächlich einen Bug in ffmkdir...

Als Anhang die gefixte Version.

Als Beispiel
1
ffmkdir("Ordner     ");
2
ffcd("Ordner     ");

Viele Grüße

Daniel

von Michael Z. (incunabulum)


Lesenswert?

Daniel,

magst du bei Gelegenheit die aktuellen Versionen wieder per SVN 
verfügbar machen?

Ansonsten kommt man per deinem zugehörigen Artikel und dem dort 
gegebenen Link auf aktuelle Versionen nur bis zur Version 0.6.1. Auch 
habe ich ein bisschen die Übersicht verloren, welche Verison mit welchen 
händischen Ändeurngen nun aktuell sein könnte...

Danke, Michael

von Daniel R. (zerrome)


Lesenswert?

Hallo,
ich kann mich nicht mehr anmelden beim SVN.

Hab dem zuständigen schon mal ne Mail geschrieben, ist aber keine 
Antwort gekommen...

Werde wohl wieder dazu über gehen die aktuellste Version im Wiki zu 
verlinken.

Viele Grüße

Daniel

von Michael Z. (incunabulum)


Lesenswert?

Daniel,

einen Link auf die aktuelle Version (wo auch immer) wär schön... svn 
noch besser. Aber was nicht ist, ist nicht :-)

Michael

von Daniel R. (zerrome)


Lesenswert?

Hi,
ja da wo es im Wiki immer den SVN Link gab, gibt es jetzt immer einen 
Link zur aktuellen Version ohne SVN.

http://www.mikrocontroller.net/articles/AVR_FAT32#Der_Status

Falls man da noch händisch etwas ändern muss schreibe ich es dann da 
auch dazu.

Viele Grüße

Daniel

von Hanno W. (hannow)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe folgendes Problem mit der Bibliothek (SourceCodeV3.0).
Mit dem µC kann ich eine Datei auf der SD Karte erstellen und auslesen, 
der Computer (WinXp ServicePack 3) kommt damit auch prima klar. Wenn ich 
allerdings mit dem Computer z.B. eine Textdatei "hallo.txt" auf der SD 
Karte erstelle erkennt der µC diese einfach nicht. Er legt die gleiche 
Datei mit dem selben Namen nochmal an, sodass diese dann zweimal 
vorhanden ist, jedoch ohne brauchbahren Inhalt. Ich habe die Karte unter 
Windows mit FAT formatiert, könnt da das Problem liegen?
Zur bessern Fehlersuche habe ich mal die "config.h", "mmc.h" und 
"SDCardTest.c" angehängt. Ich hoffe ihr könnt mir helfen.

Gruß
Hanno

von Daniel R. (zerrome)


Lesenswert?

Hallo,
nim die neuste Version. Dann ist das Problem behoben.

Viele Grüße

Daniel

von Matze N. (hupe123)


Lesenswert?

Hi, ich glaube ich habe grad wieder nen Bug gefunden...

Er ist reproduzierbar mit der Version 0.6.3.1 auf einem ATmega128 und 
beliebigen SD-Karten.
Er tritt immer auf, wenn man z.B. zwei Dateien immer abwechselnd 
beschreibt. Wenn die erste Datei größer ist als 2 Sektoren (bei 4.096 
Byte / Sektor) und sobald die zweite Datei größer wird als 2 Sektoren, 
hängt sich das Programm auf. Das funktioniert auch mit einem geänderten 
main_sample.c (nicht nur bei meinem "Mutter"- Programm)

Ich hoffe, daß das Problem kein großes ist!

Grüße und schöne Ostern noch!

von Matze N. (hupe123)


Lesenswert?

Sorry, das Problem tritt aus, wenn 4 Dateien geschrieben werden und wenn 
eine zweite größer als 2 Sektoren werden "will"
-> Sprich, wenn zwei Dateien die größe von zwei Sektoren haben und eine 
davon drei Sektoren großer werden "will" / muss.

Grüße,
Matze

von Daniel R. (zerrome)


Lesenswert?

Hallo,
poste mal den Code.

Viele Grüße

Daniel

von Hanno W. (hannow)


Lesenswert?

Hallo,
kann mir mal jemand sagen, wie ich die neue Bibliothek in mein Eclipse 
Projekt integrieren kann? Hab noch nicht so viel Erfahrung damit.
Bei der letzten Version die ich hatte, habe ich einfach die Dateien in 
mein Projekt kopiert und die Pfade zu den Header Dateien angepasst.
Jetzt habe ich mir die Version 0.6.3.1 runtergeladen und weiß eigentilch 
garnicht was ich mit den Dateien anfangen soll?

von Matze N. (hupe123)


Lesenswert?

Matze Niemand schrieb:
> Sorry, das Problem tritt aus, wenn 4 Dateien geschrieben werden und wenn
> eine zweite größer als 2 Sektoren werden "will"
> -> Sprich, wenn zwei Dateien die größe von zwei Sektoren haben und eine
> davon drei Sektoren großer werden "will" / muss.
>
> Grüße,
> Matze

Sorry, war wohl ein Fehler des Programmieres hüstel
geht alles...

Grüße,
Matze

von Daniel R. (zerrome)


Lesenswert?

Hallo.

@ Matze Niemand (hupe123)
Schön das es jetzt geht :)

@ Hanno Winter (hannow)
Ich habe im Wiki ein paar Sätze dazu geschrieben wie man das einbindet. 
Orientier Dich einfach an den mitgelieferten Beispielen. Oder an den 
Beispielen früherer Versionen.

Viele Grüße

Daniel

von Matze N. (hupe123)


Angehängte Dateien:

Lesenswert?

Hi,

ich wollte grad die Version 0.6.3.1 in meine Anwendung einbauen und 
bekomme, auch beim Compilieren der main_sample, haufenweise 
Fehlermeldungen (siehe Anhang).

Wo kommen wie auf einmal her? Ich finde den "wahrscheinlich" einfach 
Fehler nich...

Der Compiler is: AVR Studio 4 und 5beta (beide die gleichen 
Fehlermeldungen, im Anhang sind die aus AVR Studio 5beta), WinXP SP3

Grüße, Matze

von Daniel R. (zerrome)


Lesenswert?

Du versuchst die Version für den STM32 zu kompilieren...

von Matze N. (hupe123)


Lesenswert?

??? Hä? Ich habe die Datei eben nochmal von 
http://www.mikrocontroller.net/articles/AVR_FAT32#Der_Status 
heruntergeladen und aus dem Ordner "AVRStudio-SD.MMC_lib_0.6.2" die 
Datei "mmc_project.aps" geöffnet und wollte die compilieren - das selbe 
Problem. Und wenn ich AVR studio 4 frage, welcher µC benutzt werden 
soll, steht da "ATmega168"...
Was mache ich falsch?

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Äh ja sorry, da ist die falsche mmc.c rein gerutscht...
Muss das neu packen.

Als Anhang mal eine mmc.c die funktionieren sollt.

Viele Grüße

Daniel

von Matze N. (hupe123)


Lesenswert?

Jo, danke!! Und einen schönen Tag dir!

von Matze N. (hupe123)


Lesenswert?

Hmm,... ich wollte eben mal wieder weitermachen und AVRstudio4 schmeißt 
mir mit der neuen mmc.c Datei immernoch ein Fehler raus:
1
../fat.c:213: warning: implicit declaration of function 'toupper'

Grüße,
Matze

von Daniel R. (zerrome)


Lesenswert?

Hallo,
das ist ja nur ein warning.
Eigentlich sollte auch das AVR Studio diese Funktion kennen...

Viele Grüße

Daniel

von Hanno W. (hannow)


Lesenswert?

Hallo,
ich brauche mal wieder einen Tipp...seit dem ich nun die neue Bib auf 
den Controller gespielt habe, funktioniert die Initialisierung einfach 
nicht?
Ich denke, dass ich alles so wie vorher eingestellt habe, also liegt 
Chip Select noch auf PB1,...normal wäre PB4, aber wenn ich das in der 
mmc.h anpasse müsste es ja eigentlich gehn?
Ich weiß gerad gar nicht wo ich anfangen soll zu suchen...an der 
Hardware kanns nicht liegen, denn mit der alten Version klappt die 
initialisierung ohne Probleme.

von Daniel R. (zerrome)


Lesenswert?

Hallo,
hast Du einen Pullup an DO der Karte, bzw am MISO vom Kontroller?
Und ja, der Chip Select Pin hat sich geändert, also die Belegung. Wenn 
Du das in der mmc.h anpasst sollte das gehen.

Viele Grüße

Daniel

von E. L. (robo-man)


Lesenswert?

Hallo!
Das ist eine echt geile Lib. Super Arbeit!
Auch für Einsteiger leicht verständlich.
Kann mir einer vielleicht sagen, wie ich mit dieser Lib z.B. MP3 Dateien 
einfach nach der Reihe auslesen kann, ohne dass ich den Namen angeben 
muss?
Das z.B. 10 mp3´s auf der sd karte sind und der µc die dann alle 
nacheinander ausliest. Ist das möglich?
Danke!!!

von Marcel (Gast)


Lesenswert?

hi

@ Matze Niemand

"Hmm,... ich wollte eben mal wieder weitermachen und AVRstudio4 schmeißt
mir mit der neuen mmc.c Datei immernoch ein Fehler raus:

../fat.c:213: warning: implicit declaration of function 'toupper'"

du musst die Datei ctype.h in fat.c einbinden dann geht`s
#include <ctype.h>


mfg Marcel

von Hanno W. (hannow)


Lesenswert?

Hallo,

ich habe die neue Bibliothek bei mir immer noch nicht zum laufen 
gebracht...hatte zwar keinen Pullup an DO, aber selbst mit klappt die 
Initialisierung nicht.

Mein Problem mit der alten Bib ist ja nur, dass ich mit dem Computer 
keine Dateien auf der SD-Karte erstellen kann, um diese dann mit dem 
Mikrocontroller weiterzuverarbeiten. Kann mir jemand sagen, was der 
Computer anders bei der Erstellung von Dateien macht als der 
Mikrocontroller?

von Daniel R. (zerrome)


Lesenswert?

Hallo,
wo in der Initialisierung bleibt es denn hängen?

Viele Grüße

Daniel

von Hanno W. (hannow)


Lesenswert?

Hallo,
das weiß ich leider nicht, habe keine Möglichkeit das Programm zu 
debuggen...

von Daniel R. (zerrome)


Lesenswert?

Doch, das hat man immer...mit ein wenig Kreativität :)

Mach eine LED mit Vorwiderstand an einen Pin.
Im Programm machst Du die LED dann an einer bestimmten Stelle an. 
Entweder das Programm läuft bis da und die LED leuchtet, oder eben 
nicht. So kann man sehen bis wo es läuft.
Du könntest Dir natürlich auch Debug Ausgaben auf dem uart machen oder 
so...

Viele Grüße

Daniel

von holger (Gast)


Lesenswert?

Wieso ist in der 0.6.3.1 beim AVR STM32 Code drin?

von Daniel R. (zerrome)


Lesenswert?

Weil ich es verpeilt habe.
Versuche am Wochenende mal ein neues Paket zu machen, sorry.

Viele Grüße

Daniel

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Hallo,

habe da mal ein paar Fragen zur lib:

Ist das Low-Level IO (also MMC/SD etc.) vom fat code getrennt?
Weil ich dies selber realisiert habe und das gerne so übernehmen würde.

unter welcher Lizenz läuft der Code? Weil ich derzeit an einem Projekt 
sitze, was unter Umständen kommerziell eingesetzt werden soll.


mit freundlichen Grüßen
Flo

von Daniel R. (zerrome)


Lesenswert?

Hallo,
getrennt ist relativ :)

War mal so gedacht, ist aber dann doch relativ verzahnt.
Klar schreiben eines Blocks und Initialisierung sollte ohne weiteres 
portierbar sein.

Lizenz ist mir egal.

Viele Grüße

Daniel

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Ok, danke für die zügige Antwort, ich schau mal gerade ob ich das 
hinkriege mit dem trennen.

von Sven Meier (Gast)


Lesenswert?

Ist es gestattet diese lib in einem Komerziellen Projekt zu verwenden ?



Gruß Sven Meier

von Sven Meier (Gast)


Lesenswert?

Frage hat sich erledigt

von Daniel R. (zerrome)


Lesenswert?

Hallo,
da das jetzt schon mehrer Leute gefragt haben,
was würde passieren wenn ich sage:" Nee gib mir mal 50 Euro dafür"?

Mir ist es aber egal was wer damit macht...


Viele Grüße

Daniel

von Flo W. (Firma: privat) (florian1x)


Lesenswert?

Mach ne readme.txt mit dazu
wo du nen copyright mit deinem namen reinschreibst
und dadrunter dass es BSD is. Dann kann die jeder Frei verwenden 
bearbeiten und sons was

ein zwei regeln gibt es da noch aber prinzipiel sollte die Linzenz für 
das projekt hier ganz gut sein :P

von Gedankenmacher (Gast)


Lesenswert?

>da das jetzt schon mehrer Leute gefragt haben,
>was würde passieren wenn ich sage:" Nee gib mir mal 50 Euro dafür"?

wahrscheinlich wärst du dann Händler mit allem drum und dran. Steuer, 
Gewährleistung, Support, irgendwelche Anmeldungen, ...

btw. tolle Bibliothek.

von holger (Gast)


Lesenswert?

>btw. tolle Bibliothek.

Ja, wirklich toll. Der STM32 Schrott steht seit dem
31.05.2011 immer noch im AVR Teil.

von Daniel R. (zerrome)


Lesenswert?

Kommendes Wochenende änder ich das, versprochen...

von abccba (Gast)


Lesenswert?

Hallo,

ich habe eine kleine, wahrscheinlich banale Frage. Habe eine SD Karte 
mit einem Mega 16 verbunden und möchte Werte aus einer Text-Datei 
auslesen und an einem Port ausgeben. Als nur komisches Zeug ausgegeben 
wurde habe ich mal per uart ausgeben lassen, was genau der uC eigentlich 
von der Karte einliest und musste feststellen dass da irgendein Murks 
angezeigt wird. Also habe ich zunächst eine Text-Datei mit ffwrite vom 
uC aus erstellt und diese dann anschließend wie vorher ausgegeben... das 
funktionierte einwandfrei. Wenn ich jedoch nur ein einziges Zeichen mit 
einem Text-Editor in der Datei am Rechner verändere und das ganze 
speichere, dann steht wieder nur murks da. Woran liegt das? Ich habe die 
Vermutung dass irgendwas mit der Codierung nicht stimmt, bzw der Editor 
da irgendwie noch was reinmogelt. Wie kann man nun am PC eine Text-Datei 
erstellen, die auch wirklich nur aus dem besteht was man im Editor 
sieht?

Viele Grüße

PS.: die Library ist echt super!

von Daniel R. (zerrome)


Lesenswert?

Hallo,
eine ganz normale Textdatei muss die Lib lesen können. Hast Du die Lib 
mit LFN Untersützung kompiliert? Vielleicht macht der PC da immer lange 
Dateinamen aus den Dateien beim schließen. Wenn Du so eine Datei hier 
hochladen würdest, schau ich mir die mal mit einem Hex-Editor an. Der 
zeigt einem wirklich die Bytes an aus der so eine Datei besteht.

Viele Grüße

Daniel

von abccba (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Daniel,

hier hab ich mal ein paar Werte eingetragen, einmal mit dem Mac 
Text-Edit in test.txt und dann nochmal mit Windows im Editor in 
test1.txt. Die Codierung ist Standardmäßig bei Windows auf ANSI und Bei 
test.txt hab ich ASCII eingestellt, weil dort anscheinend UTF-8 Standard 
ist. Das wär echt super, wenn du dir das kurz mal anschauen könntest. 
Achso, LFN ist natürlich mitkompiliert worden.

Viele Grüße und Danke für die Hilfe

PS.: Ich hätte noch eine andere Frage zur Funktion ffls(): Wie genau 
funktioniert diese?
bzw. was beudeutet genau "// zeigt direktory inhalt an, muss zeiger auf 
eine ausgabe funktion übergeben bekommen" ? Kann ich die Funktion nutzen 
um in einen String sämtliche Dateinamen, die vorhanden sind, 
reinzukopieren? Wenn ja, wie genau stelle ich das an?

von abccba (Gast)


Lesenswert?

Oh ich seh grad das sind in beiden Fällen tatsächlich genau 15 Bytes. 
Sehr seltsam. Kann es sein dass etwas mit der Formatierung der Karte 
nicht stimmt? Bzw wie kann ich diese am besten formatieren?

von Daniel R. (zerrome)


Lesenswert?

Hallo,
am besten formatierst Du die Karte mit FAT32, windows oder linux, das 
ist egal.

ffls() ist eine Baustelle seit der Umstellung auf LFN. Das zeigt 
momentan nämlich nur SFN an.

Ich schau mir das spätestens morgen mal genauer an..

Viele Grüße

Daniel

von Daniel R. (zerrome)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
hier mal die neu gepackte Version.
Um es mir einfacher zu machen, werde ich jetzt einfach die AVR und ARM 
Sachen getrennt hier http://www.mikrocontroller.net/articles/AVR_FAT32 
Posten.

Viele Grüße


Daniel

von SD-Card Greenhorn (Gast)


Lesenswert?

Hallo

ich habe noch keinerlei Erfahrung mit SD-Card Anwendungen. Ich möchte 
angeregt durch diesen Thread mal damit anfangen. Ich habe einen 
Atmega328P. Einige haben da ja schon die LIB angepasst, haben aber nicht 
explizit geschrieben was. Wo muß man da überall anpassen?
-mmc.h
-uart.h
..oder sonst noch wo? Ich habe im Artikel nichts über Prozessoranpassung 
gelesen. Gibt es ein "kleines" Testprogram, mit dem eine "schnelles" 
erfolgserlebnis hat.

Vielen Dank
Achim

von Daniel R. (zerrome)


Lesenswert?

Hallo,
es liegt ein Beispielprogramm bei.

Für den ATmega328 musst Du nur, wie Du schon festgestellt hast, die 
mmc.h und das Uart Zeug anpassen. Hast Du spezielle Fragen?

Viele Grüße

Daniel

von SD-Card Greenhorn (Gast)


Lesenswert?

Hallo Daniel,

vielen Dank für deine Antwort. Konkrete Fragen kommen eventuell erst 
noch....

MfG
Achim

von SD-Card Greenhorn (Gast)


Lesenswert?

Hallo

ich möchte die SD-Card an einen Atmega328P 3,3V System hängen. Meine 
Frage ist nun muß man da Pullup Widerstände dranmachen?
Ich habe in der mmc.c nichts gefunden dass da die internen Pullups 
aktiviert werden?

Es gibt ja da sehr viele Schaltungsvarianten. Kann mir jemand kurz sagen 
welche Ankopplung bei dem 3,3V System am erfogversprechendsten ist?

Vielen Dank
Achim

von Daniel R. (zerrome)


Lesenswert?

Hallo,
ja Pullup an MISO wäre ganz gut. Ordentliche Stromversorgung und 
Enstörkondensatoren Kondensatoren schaden auch nicht.

Ich hab aber auch schon Schaltungen gesehen, da hätte man gesagt, DAS 
läuft NIEMALS, hat es dann aber doch...

Viele Grüße

Daniel

von Andre I. (scuido)


Lesenswert?

Hallo,

super Lib, ein großes Dankeschön an alle die da mitgewerkelt haben.

Ich habe nun ein kleines Problem,

wenn ich eine Datei erstelle und dort mit einer Schleife 100mal das 
gleiche reinschreibe und anschließend wieder schließe, danach denn 
wieder mit dem µC auslese und über uart ausgebe, funktioniert alles 
wunderbar.
(Quelltext ist der aus dem Tutorial nur mit ner Schleife extra)

Wenn ich nun aber die SD Karte in den PC stecke findet er zwar die 
Datei, sie hat auch ne variable Größe z.B. 5kB(jenachdem wie oft ich da 
reinschreibe), nur kann ich sie nicht öffnen. Windows meint, die Datei 
sei beschädigt. Woran liegt das?


Leider bin ich gerade erst mit der SD/FAT Materie angefangen und kenne 
da noch nicht alle Vorgaben.

Viele Grüße
André

von Andre I. (scuido)


Lesenswert?

Was ich noch vergessen habe. Unter Linux kann man die Datei öffnen.

Gruß
André

von Daniel R. (zerrome)


Lesenswert?

Hallo,

probier mal nur mit kurzen Dateinamen zu kompilieren und dann das mit 
der Datei. Poste zur Sicherheit mal den Code den Du geändert hast, 
vielleicht ist da ein Fehler.
Um zu verstehen was da passiert ist es gut sich die Daten mal mit einem 
Hex-Editor wie WinHex anzuschauen. Da kann man dann genau sehen wie die 
Daten auf der Karte strukturiert sind.

Viele Grüße

Daniel

von Andre I. (scuido)


Lesenswert?

Hey, habe das Porblem gefunden.

Scheinbar war das Format der Karte nicht auf FAT16/32, sondern FAT12. 
Deine Lib hat das nicht erkannt und dachte es sei FAT16, so hat die denn 
einfach drauf geschrieben, sodass die Daten zwar drauf waren aber das 
Dateisystem kaputt war.

Mit ne größeren Karte die auf FAT32 formatiert wurde läuft es nun.


Ich hatte das gleiche Problem mit dem exacten Code von dir.

Linux ist es scheinbar völlig wurst was es bekommt, aber Windows ist da 
dummerweise etwas zimperlich... ;)

Danke aber für deine Rückmeldung, vielleicht hilft dir der Fehler ja, um 
die Lib. noch bissle robuster zu machen.

von Max (Gast)


Lesenswert?

Hallo Zusammen,

ich versuche gerade ein Verzeichnis auf der SD Karte an zu legen.
Es wir auch erzeugt, nur lässt es sich am PC nicht öffnen. Es kommt eine 
Fehlermeldung.

der Code sieht so aus.

uint8_t dada[] = "DAN";
ffmkdir(dada);

Mache ich etwas falsch?

Datei erzeugen funktioniert, öffnen schreiben, lesen alles gut.

Gruß

Max

von Daniel R. (zerrome)


Lesenswert?

Hallo,
probier mal ob dieses Beispiel funktioniert:

Beitrag "Re: MMC SD library FAT16 FAT32 read write"

Also nur die Art und Weise wie das da erstellt wird. Nicht diese Version 
von da, sondern mit der Version von hier:

http://www.mikrocontroller.net/articles/AVR_FAT32

Viele Grüße

Daniel

von Max (Gast)


Lesenswert?

Danke das war es.

Ist vielleicht an gedacht in der nächsten Version eine kleine Schleife 
im ffmkdir zu integrieren die prüft wie lang der String ist und dann 
entsprechen SPACE anhängst?

Gruß

Max

von Christian (Gast)


Lesenswert?

Hi Daniel !

Erstmal super Bibliothek.

Ich habe jetzt nicht sämtliche Antworten darauf gelesen und hoffe das 
meine folgende Frage noch nicht gestellt wurde :).


Ich möchte mittels Microblaze und dem dazugehörigen SPI Core Daten auf 
eine SD Karte schreiben und diese komfortabel via PC auslesen. Also z.B. 
Prozessdaten abgespeichert in einer .txt file.

Eignet sich deine Bibliothek für solch eine Hardware Platform?

Ich habe noch nie mit FAT16/32 gearbeitet und hoffe, dass die Frage 
nicht zu trivial ist :)

Gruss

von Daniel R. (zerrome)


Lesenswert?

Hallo,
das sollte kein Problem sein.
Habe auch die Lib auch schon auf einem Altera NIOS laufen gehabt. 
Genauer gesagt mit dem DE2 Board von Altera. Du musst nur den ganzen SPI 
Kram anpassen...

Viele Grüße

Daniel

von Christian (Gast)


Lesenswert?

Hi,

Okay danke Dir!

Werd mich evtl. nochmal melden, sofern ich noch Fragen habe :)

Gruss

von Christian F. (christianf)


Lesenswert?

Eine Frage hab ich noch,

ich war gerade drauf und dran das komplett selber zu schreiben. Also 
zuerst die Karteninitialisierung realisieren, dann schreiben eines 
Blockes und dann am "Ende" die Realisierung von FAT32.

Nun überleg ich gerade ob ich dein angebotenes Projekt verwenden, da ich 
Neuling auf dem Gebiet bin. Jedoch hab ich absolut kein Überblick über 
das, was angepasst werden muss.

Ist die Initilisierungsprozedur denn an den "initialization flow" von 
der Spezifikation angepasst ?
http://elm-chan.org/docs/mmc/sdinit.png

von Christian F. (christianf)


Lesenswert?

Kann den obigen Beitrag nichtmehr editieren (leider). Sorry also für den 
Spam.

Ich wollte Dich fragen ob es mit der TPU Probleme geben könnte.

Irgendwie verwendest du ja "TimingDelay" für die mmc_init Funktion. Ist 
das eine über die TPU vom AVR (falls vorhanden) erzeugte Verzögerung?

Wie müsste man es verändern ? Reicht da eine einfache "Soft-Tpu" in Form 
einer for-Schleife (bissle unsauber ich weiß :) ).

Gruss
Christian

von Xdim (Gast)


Lesenswert?

Hallo,
erstmal großen Dank an diese gute Library. Ich benutze sie um auf einer 
SD/SDHC eine TXTdatei anzulegen um dort meine AD gewandelten Werte 
abzuspeichern. Das funktioniert bis jetzt auch ganz gut... Nun habe ich 
Probleme bei einer anderen Sache. Ich möchte auf der SD Karte eine Datei 
(unter Windows) anlegen. Die heißt dann z.B. config.txt. Von dort soll 
sich der Controller später verschiedene Werte holen und die 
entsprechenden Variablen (also die Controllervariablen wie z.B. 
Abtastzeit) dannach setzen. Das Problem ist, dass die unter Windows 
angelegte Datei von der FATlibrary nicht gefunden wird. Ich habe es mit 
ffopen((unsigned char*)config.txt) und auch direkt mit 
if(fat_loadFileDataFromDir((unsigned char*) "config.txt")==TRUE)... 
probiert, doch leider kein Erfolg. Ich habe auch schon verschiedene 
Schreibweisen versucht (CONFIG, CONFIG  TXT, CONFIG.TXT). Hat auch nicht 
geklappt.
Funktionieren tut es nur, wenn ich mit meinem Controller die config.txt 
Datei anlege und später unter Windows editiere. Dann wird die Datei auch 
immer gefunden und ich kann die nötigen Werte raus holen.


für Tipps wäre ich sehr dankbar.

von Mark (Gast)


Lesenswert?

Hi!

Ich habe ein Problem und zwar hab ich das fertige KEIL - Project von 
Version 0.6.3.1 auf meinen STM32F107VB geworfen. Ich hab nur den CS-Pin 
auf meine Hardware angepasst.
Aber leider funktioniert bei mir das mmc_init nicht.
bei CMD0 bekomm ich noch 0x01 zurück, aber bei ACMD41 oder CMD1 bekomm 
ich immer 0xFF zurück.
Hat wer Erfahrung damit oder eine Idee was mein Problem sein könnte?
Vielen Dank schonmal...

lG
Mark

von US (Gast)


Lesenswert?

Hallo,
wollte mit folgenden Parametern die Lib übersetzen.

MMC_OVER_WRITE = FALSE
MMC_MULTI_BLOCK = TRUE


Fehlermeldung!
start_Sectors und currentSectorNr sind nicht in struct Fat_t vorhanden.

Und so wie es aussieht, hat der Compiler wohl auch noch recht.


Gruß
Uwe

von Daniel R. (zerrome)


Lesenswert?

Hallo, ja hat er.

http://www.mikrocontroller.net/articles/AVR_FAT32#Der_Status

Da steht das Multiblock ungetestet ist...

Hatte momentan sehr wenig Zeit. Wird aber kommenden Monat deutlich 
ruhiger werden.


Grüße

Daniel

von US (Gast)


Lesenswert?

Hallo,
sollte nur eine Mitteilung sein und auf keinen Fall etwas anderes.
Finde die Lib sonst sehr gut.

Danke

Gruß
Uwe

von A. G. (Firma: Conrad) (goth_conrad)


Lesenswert?

Hallo,

ich habe Ihnen eine PM geschickt, leider ohne Hinweis, ob Sie die Info 
erhalten haben. Deshalb schreibe ich zur Sicherheit hier im Thread.
Bitte kontaktieren Sie mich, sobald Sie die Nachricht erhalten.

Vielen Dank

von Steve (Gast)


Lesenswert?

Hi Leute,

Ich versuch schon seit einiger Zeit mit der ffwrite funktion die ADC 
werte meines XMega128 abzuspeichert. Strings klappen einwandfrei jedoch 
mit den int da hab ich probleme entweder er zeigt nur hieroglyphen (im 
übertragenen Sinn) an oder gar nichts an.

Ich speichere es als *.txt file.

Wahrscheinlich ist es nur eine kleinigkeit die ich übersehen hab aber 
ich weis nicht mehr weiter.

Ich hoffe Ihr wisst vielleicht was.

Übrigens danke für die tolle lib.

von Gerhard G. (xmega)


Lesenswert?

Hallo;


Steve schrieb:
> ich weis nicht mehr weiter.


int ffwrite_putchar(char c, FILE *stream); // // bindet ffwrite(c) ein


 // bindet ffwrite() ein
 static FILE my_stdout = FDEV_SETUP_STREAM(ffwrite_putchar, NULL, 
_FDEV_SETUP_WRITE);

int main(void)
{
//....
stdout = &my_stdout; // bindet printf() ein

printf("%02d; %02d; \r\n",ADCWERTxx,ADCWERTyy);// auf SD-Card speichern
//....

}

int ffwrite_putchar(char c, FILE *stream) // // bindet ffwrite() ein
{
   ffwrite(c);
  return 0;
}


bitte die nötigen Maßnahmen für printf(), float, usw. beachten

Makefile :

PRINTF_LIB = $(PRINTF_LIB_FLOAT)


Gruß xmega

von Steve (Gast)


Lesenswert?

Super danke das funktioniert einwandfrei, jedoch hab ich jetzt ein 
anderes kleines problem mit meinen dogl128 den ich verwende. Den 
beschreib ich leider auch mit der printf funktion.

Jetzt schreibe ich zwar wenn ich ins Unterprogramm springe die funktion 
um auf die sd-karte und wenn ich wieder rausspring schreib ichs wieder 
um auf den lcd. Nun geht der Display so lange aus so lang ich im 
Unterprogramm bin.

Gibt es irgendeine möglichkeit auch eine andere funktion als die printf 
zu verwenden???

von Gerhard G. (xmega)


Lesenswert?

Hallo,

du legst im Prinzip zweimal das Selbe an und wechselst nur mit

stdout = &mystdout; // bindet ffwrite() ein

oder

stdout = &my_stdout; // bindet printf() unter DOGM128 ein

Das funktioniert sehr gut, ich mach genau das Selbe.

Ich schreibe Temperaturen auf die SD-Card

z.B


stdout = &my_stdout; // bindet ffwrite()() ein


printf("%02d; %02d; \r\n",ds18b20.cel[0],ds18b20.cel[1]);// SP anzeigen

stdout = &mystdout; // bindet printf() DOGM128 ein



Gruß xmega

von Stephan K. (dustpuppy)


Lesenswert?

Hi,
kann sein, dass ich was falsch mache, aber kann auch sein, dass ich 
einen Fehler gefunden hab.
Ich habe zwei Dateien auf der Karte. Wenn ich eine dritte Datei anlege, 
in die ich die Daten einer der beiden Datein kopiere und dann die 
Quell-Datei loesche, dann wird die zweite Datei, die am Anfang da war 
gleich mit geloescht.
Das Kopieren mach ich so, dass ich eine Zeile lese, die Datei schliesse 
und die Daten dann in die Zieldatei schreibe, diese wieder schliesse und 
so weiter. Also ist immer nur eine Datei offen. fflush verwende ich auch 
nach jedem Zugriff und ich habe es bereits versucht mit Pausen zwischen 
den Zugriffen.

Gruesse

Dusty

von Daniel R. (zerrome)


Lesenswert?

Hallo,

poste doch mal den Code mit dem Du das machst.
Vielleicht kann man dann mehr dazu sagen.

Viele Grüße

Daniel

von Stephan K. (dustpuppy)


Angehängte Dateien:

Lesenswert?

Hi,
das wird jetzt nicht grade wenig.

Die Datenbank Funktionen:
1
struct _data_info_
2
{
3
  uint16_t num_fields;
4
  uint16_t num_data;
5
  char name[20][20];
6
  char DATA[20][20];
7
  char *db;
8
}DATA_INFO;
9
10
void Read_DB(uint16_t n)
11
{
12
      int count=0;
13
      int c,t;
14
      uint16_t s=0;
15
  
16
      if( MMC_FILE_OPENED == ffopen(DATA_INFO.db,'r') )
17
      {
18
  while(s<=n)
19
  {
20
    for(t=0;t<DATA_INFO.num_fields-1;t++)
21
    {
22
      count=0;
23
      c=ffread();
24
      while( (c!=',') )
25
      {
26
        tmp_buffer[count]=c;
27
        c=ffread();
28
        count++;
29
      }
30
      tmp_buffer[count]='\0';
31
      if(n==0)
32
      {
33
        sprintf(DATA_INFO.name[t],"%s",tmp_buffer);
34
      }
35
      else
36
      {
37
        sprintf(DATA_INFO.DATA[t],"%s",tmp_buffer);
38
      }
39
    }
40
    count=0;
41
    c=ffread();
42
    while( (c!='\n') )
43
    {
44
      tmp_buffer[count]=c;
45
      c=ffread();
46
      count++;
47
    }
48
    count--;
49
    tmp_buffer[count]='\0';
50
      if(n==0)
51
      {
52
        sprintf(DATA_INFO.name[t],"%s",tmp_buffer);
53
      }
54
      else
55
      {
56
        sprintf(DATA_INFO.DATA[t],"%s",tmp_buffer);
57
      }
58
    s++;
59
  }
60
  ffclose();
61
      }
62
}
63
64
void Open_DB(char *file_name)
65
{
66
  uint16_t count_fields=0;
67
  uint16_t count_data=0;
68
  int c;
69
  uint32_t seek;
70
  int fields_counted=FALSE;
71
  
72
    if( MMC_FILE_OPENED == ffopen(file_name,'r') ){
73
    seek = file.length;
74
    do{
75
      c=ffread();
76
      if( (c==',') && (fields_counted==FALSE) )
77
      {
78
        count_fields++;
79
      }
80
      if( (c=='\n') )
81
      {
82
        if(fields_counted==FALSE)
83
        {
84
          count_fields++;
85
        }
86
        count_data++;
87
        fields_counted=TRUE;
88
      }
89
    }while((--seek));
90
    ffclose();
91
  }
92
  DATA_INFO.num_fields=count_fields;
93
  DATA_INFO.num_data=count_data-1;
94
  DATA_INFO.db=file_name;
95
  Read_DB(0);
96
}
97
98
void Delete_DB(uint16_t n)
99
{
100
    int t,x;
101
    int c;
102
  
103
    if(MMC_FILE_OPENED == ffopen("temp.tmp",'c') )  // Leere Datei anlegen
104
    {
105
  fflushFileData();
106
  ffclose();
107
    }
108
    
109
    if( MMC_FILE_OPENED == ffopen("temp.tmp",'r') )  // Temporaere Datei oeffnen
110
    {
111
      for(t=0;t<DATA_INFO.num_fields-1;t++)
112
      {
113
  ffwrites(DATA_INFO.name[t]);      // Feldbezeichnung eintragen
114
  ffwrite(',');          // Komma anfuegen
115
  fflushFileData();
116
      }
117
      ffwrites(DATA_INFO.name[t]);      // Feldbezeichnung eintragen
118
      ffwrite(0x0D);          // Zeile abschliessen \n
119
      ffwrite(0x0A);          // Zeile abschliessen \r
120
      fflushFileData();
121
      ffclose();
122
    }
123
    
124
    c=DATA_INFO.num_data;
125
    
126
    for(x=1;x<n;x++)          // Datensaetze vor dem zu loeschenden durchgehen
127
    {
128
      Open_DB("loks.dat");        // Datenbank oeffnen, um die Info struct aktuell zu halten
129
      Read_DB(x);          // Datensatz holen
130
      if( MMC_FILE_OPENED == ffopen("temp.tmp",'r') )  // Temporaere Datei oeffnen
131
      {
132
  ffseek(file.length);        // Bis ans Dateiende gehen
133
  for(t=0;t<DATA_INFO.num_fields-1;t++)
134
  {
135
    ffwrites(DATA_INFO.DATA[t]);      // Datenfeld eintragen
136
    ffwrite(',');          // Komma anfuegen
137
    fflushFileData();
138
  }
139
  ffwrites(DATA_INFO.DATA[t]);      // Datenfeld eintragen
140
  ffwrite(0x0D);          // Zeile abschliessen \n
141
  ffwrite(0x0A);          // Zeile abschliessen \r
142
  fflushFileData();
143
  ffclose();
144
      }
145
    }
146
    for(x=n+1;x<=c;x++)          // Datensaetze nach dem zu loeschenden durchgehen
147
    {
148
      Open_DB("loks.dat");        // Datenbank oeffnen, um die Info struct aktuell zu halten
149
      Read_DB(x);          // Datensatz holen
150
      if( MMC_FILE_OPENED == ffopen("temp.tmp",'r') )  // Temporaere Datei oeffnen
151
      {
152
  ffseek(file.length);        // Bis ans Dateiende gehen
153
  for(t=0;t<DATA_INFO.num_fields-1;t++)
154
  {
155
    ffwrites(DATA_INFO.DATA[t]);      // Datenfeld eintragen
156
    ffwrite(',');          // Komma anfuegen
157
    fflushFileData();
158
  }
159
  ffwrites(DATA_INFO.DATA[t]);      // Datenfeld eintragen
160
  ffwrite(0x0D);          // Zeile abschliessen \n
161
  ffwrite(0x0A);          // Zeile abschliessen \r
162
  fflushFileData();
163
  ffclose();
164
      }
165
    }
166
}

Der Fehler tritt in Delete_DB auf. Die Bilder zeigen, was ich meine. Die 
Funktion ist noch nicht fertig, da ich den Fehler erst behoben haben 
muss.
Spaeter wird das orginal File geloescht und das temporaere File noch mal 
kopiert als orginal.
Was mich dann auch zum naechsten Punkt bringt. Eine Funktion zum 
Umbennen von Dateien waere echt hilfreich.

Die Bilder zeigen Folgendes. Zuerst was auf der Karte ist am Anfang. 
Dann dass das Kopieren funktioniert hat. Datensatz 3 ist geloescht in 
temp.tmp. Dann dass nicht nur das geloescht File weg ist, sondern auch 
noch eine weitere Datei fehlt.
rm im Terminal ruft nur ffrm("temp.tmp") auf.

Gruesse

Dusty

von Stephan K. (dustpuppy)


Lesenswert?

Hi again,
und noch ein Fehler. Ich habe eine Karte geloescht und eine Datei mit 
2mb Groesse angelegt. Diese habe ich mit Leerzeichen vollgeschrieben. 
Wenn ich die Datei jetzt lese, dann sind dort Frakmente alter Dateien 
drin.

Gruesse

Dusty

von Daniel R. (zerrome)


Lesenswert?

Hallo,
erstmal:

Das ist doppelt in der Kombination! ffclose ruft fflushFileData eh auf. 
Das erzeugt unnötige Schreiboperationen.
1
fflushFileData();
2
ffclose();

fflushFileData sollte nur verwendet werden wenn man ewig lange eine 
Datei geöffnet hat und sicherheitshalber zwischendurch mal die Daten 
sichern möchte. Sonst ist das nicht nötig. Im gegenteil, es werden so 
Unmengen von Schreiboperationen verursacht.

>Der Fehler tritt in Delete_DB auf.
Aber erst bei rm verschwinden doch die Dateien oder? Sind vorher alle 
Dateien da und so wie sie sein Sollten? Mit Pc überprüft?

Dann, was meinst Du mit gelöscht? Formatiert?
Wie legst Du denn eine Datei mit 2MB an schreibst erst dann?

Poste mal bitte noch die Dateien, dann schau ich mal, wann ich Zeit habe 
das bei mir laufen zu lassen um den Fehler reproduzieren zu können.
Hilfreich wäre auch die mmc_config.h und welche Version der Lib Du 
benutzt.

Viele Grüße

Daniel

von Kazs (Gast)


Lesenswert?

Hi!

Wie schaut denn der Speicherverbrauch der Lib aus (mit gehts 
hauptsächlich um RAM)? Wieviel belegt die Statisch im RAM und wieviel 
Platz solle auf dem Stack noch verfügbar sein?

von Thilo M. (Gast)


Lesenswert?

Hallo Daniel,

erst mal Kompliment für die gelungene Lib!

Banale Frage:
Ich habe die Lib in einen Datenlogger integriert, läuft so weit auch 
super (Textdatei, ca. 40 Byte pro Zeile, minütliches, zeilenweises 
Schreiben).

Das Problem ist, dass die Ansteuerung nach ca. 12h "abschmiert", die 
Karte wird dauerhaft angewählt und die Datei zerschossen.
Meine Vermutung ist, dass zwischendurch ein fat-lookup stattfinden 
sollte.
Kann das sein? Karte ist dauerhaft unter Spannung.
Und wie kann ich einen fat-lookup bei initialisierter Karte durchführen?

von Thilo M. (Gast)


Lesenswert?

Um meine Frage selbst zu beantworten:

ich habe testweise die MMC_MAX_CLUSTERS_IN_ROW in der mmc_config.h auf 
2048 hochgesetzt. Seit 10 Tagen Dauerbetrieb keine Probleme, alles 
bestens.

Nochmal: super Lib! ;-)

von phanaton (Gast)


Lesenswert?

Hi, ich wollte mal einen (höchstwahrscheinlich jedenfalls) Bug melden,
in der Funktion "mmc_wait_ready (void)":
1
static uint8_t mmc_wait_ready (void){
2
3
  TimingDelay = 50;
4
5
  do{
6
    if(   spi_read_byte() == 0xFF ) return TRUE;
7
  }while ( TimingDelay );
8
9
  return FALSE;
10
}

dort würde eine Endloschleife stattfinden wenn die SD/MMC Karte nicht 
antwortet.
Demnach sollte die Korrektur in etwa so außsehen:
1
//...
2
        }while ( TimingDelay-- );
3
//...

von Fabian B. (fabs)


Lesenswert?

Das ist nicht richtig.
TimingDelay wird an anderer Stelle (im Timer Interrupt) dekrementiert.

Gruß
Fabian

von phanaton (Gast)


Lesenswert?

Oh Sorry hab ich wohl einen Fehler gemacht...
Hab nur kurz den Quellcode überflogen und das kam mir komisch vor, aber 
jetzt da ich sehe das TimingDelay ja gar nicht in der Funktion 
initialisiert wird wird mir klar das ich ein wenig weiter in den 
Quellcode hätte schauen müssen...

Gruß
Philipp

von Sven S. (schwerminator)


Lesenswert?

Hi. Die Library läuft bei mir inzwischen recht gut. Wenn ich allerdings 
in der 0.6.4 sowohl MMC_MULTI_BLOCK auf TRUE als auch MMC_OVER_WRITE auf 
FALSE stelle, kommt es zu folgenden Fehlern in file.c:

Error  1  'struct Fat_t' has no member named 'currentSectorNr'
Error  2  'struct Fat_t' has no member named 'startSectors'
Error  3  'struct Fat_t' has no member named 'startSectors'
Error  4  'struct Fat_t' has no member named 'currentSectorNr'
Error  5  'struct Fat_t' has no member named 'startSectors'
Error  6  'struct Fat_t' has no member named 'currentSectorNr'
Error  7  'struct Fat_t' has no member named 'currentSectorNr'

Und Tatsache: Beschriebene Felder befinden sich in anderen Strukturen. 
Ein einfaches Umändern hat bei mir keinen Erfolg gebracht => weitere 
Fehler. Kann es sein, dass da ein paar Dateien/Funktionen aus 
unterschiedlichen Versionen durcheinander geraten sind?

Gruß Sven

von Daniel R. (zerrome)


Lesenswert?

Hallo,

es ist noch schlimmer als nur durcheinander geraten.
Es ist nicht geprüft. Multiblock wird momentan also nicht unterstützt.

Viele Grüße

Daniel

von Thilo M. (Gast)


Lesenswert?

Ich habe momentan auch noch Probleme,

ich schreibe minütlich Datensätze mit je 182 Byte in eine Textdatei.
Nach 4h25min (263 Datensätzen) + 574 Byte Spaltenüberschrift (insgesamt 
49152 Byte, also exakt 48kB) wird die Karte zwar noch angesprochen, aber 
nicht mehr beschrieben.

Bin momentan ratlos, an was das liegen könnte.

von Thilo M. (Gast)


Lesenswert?

Nachtrag:
die verwendete Karte ist eine etwas ältere Kingston 256MB-Karte.
Mit einer MAX 60x 1GB sind die Leuchtzeiten der LED am CS deutlich 
kürzer.
Ich vermute diese alte Kingston-Karte ist zu langsam.

von Michael M. (eos400dman)


Lesenswert?

Hallo,

ich versuche nun auch schon seit ein paar Tagen eine SD Karte (1Gb mit ) 
deiner Lib anzusteuern. Ich komme aber nicht über mmc_init hinaus. Auf 
dem Terminal wird mir nur Boot angezeigt. Hab bereits den 10k Pullup an 
MISO und auch schon alle Verbindungen geprüft. Mein µC ist ein Atmega 
168 und er läuft mit 10Mhz. Zum testen verwende ich deinen Beispielcode.
Ich habe auch schon #define MMC_MAX_SPEED FALSE versucht, aber das hat 
auch nichts gebracht. Was kann ich noch versuchen?

Gruß Michael

von Thilo M. (Gast)


Lesenswert?

Eben nochmal mit neuer Karte getestet, die Datei wird definitiv beim 
Schreiben >48kB zerschossen (nicht mehr lesbar).

Was könnte da schuld sein?

von Michael M. (eos400dman)


Angehängte Dateien:

Lesenswert?

Ich hab jetzt nochmals mit einer anderen Karte getestet. Aber es läuft 
trotzdem nicht. Meine Hardware müsste doch passen, oder?

Gruß Michael

von Michael M. (eos400dman)


Angehängte Dateien:

Lesenswert?

Hallo,

Hab mir die Signale noch mal mit dem Oszi angesehen. MOSI und SCK sehen 
wie auf dem Bild aus. Dort ist die Ansteigs- und Abfallszeit zu langsam 
für die SD Karte, oder nicht? Wenn ja woran kann das liegen?

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Eine Anstiegszeit von 330ns sollte wohl ausreichen. Das sieht eigentlich 
sogar sehr gut aus.

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Also wenn 330ns iO sind, dann weiß ich auch nicht mehr an was es noch 
liegen kann. Hast du eine Idee?

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Hast du die Möglichkeit deine ganze Schaltung auf 3.3V laufen zu lassen? 
Dann könntest du den Spannungsteiler zur Karte weglassen -> eine 
mögliche Fehlerquelle weniger.

Gruß
Fabian

von Kurt B. (kurt)


Lesenswert?

Du hast doch hoffentlich am LT1763 noch einen vernüftigen Kondensator, 
außer dem 10nF Popel?

von Michael M. (eos400dman)


Lesenswert?

Ich hab nur am Eingang des Reglers 470µ und 100n und an der Karte 
nochmals 100n.

von Michael M. (eos400dman)


Lesenswert?

Ich hab nur am Eingang des Reglers 470µ und 100n und an der Karte 
nochmals 100n. Am Ausgang hab ich sonst nichts.

von Kurt B. (kurt)


Lesenswert?

Das Datenblatt will aber mindestens 3,3µF am Ausgang! 1µF direkt an der 
Karte werden auch nicht schaden.

von Fabian B. (fabs)


Lesenswert?

Ja, miss mal mit deinem Skop den Spannungseinbruch beim Einschalten der 
Karte. Manche Karten sind da sehr zickig und geben schon bei 
Schwankungen <200mV auf. Und die Stromaufnahme der Dinger ist nicht 
unerheblich.

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Danke erst mal für eure Tipps. Ich habe jetzt noch mal 22µF für die 3,3 
V Versorgung eingebaut. Jetzt bricht die Versorgungsspannung nicht mehr 
ein, davor schon. Aber auch das hat nichts geholfen.

Gruß Michael

von holger (Gast)


Lesenswert?

>Aber auch das hat nichts geholfen

Spannungsteiler als Pegelkonverter für SD Karten
sind kompletter Schwachsinn. Das wurde hier schon oft
genug durchgekaut.

von Fabian B. (fabs)


Lesenswert?

Wie gesagt, versuch mal die ganze Schaltung wenn möglich mit 3V3 zu 
versorgen... dann keine Pegelkonverter... sonst such ich dir auch 
nochmal ne Schaltung mit aktivem Konverter (getestet) raus.

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Die ganze Schaltung mit 3V3 wird nicht gehen. Sonst brauch ich wo anders 
wieder Pegelwandler zum Beispiel zum Display oder zum Funkmodul.

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Vielleicht kannst du ein Testprogramm ohne die zwei Peripherieteile 
laufen lassen?

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Ich hab jetzt die Schaltung mal mit 3V3 getestet und die 1k8 
"kurzgeschlossen". Die 3k3 gegen Masse sollten ja nicht Sören oder?
Aber es geht trotzdem nicht.

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Michael Mayer schrieb:
> Die 3k3 gegen Masse sollten ja nicht Sören oder?

Darauf würde ich mich erstmal nicht verlassen...

Wie debuggst Du denn aktuell? Kannst Du sehen, ob die Karte gar nicht 
antwortet oder bei welchem CMD es zum Problem kommt?

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Ich debugge nur über UART. Ich schreibe mal den Code um, damit ich sehe 
an welchem CMD er Probleme hat.

Gruß Michael

von Matthias L. (mcl024)


Lesenswert?

Hallo

echt gute lib. Bin relativ schnell damit zurecht gekommen und jetzt 
läuft sie auf dem ATXMEGA128A1. Ich habe allerdings ein Problem.

Wie kann ich eine Datei immer wieder lesen ohne die Datei wieder mit 
ffopen zu initialisieren?

von Michael M. (eos400dman)


Lesenswert?

Also ich hab jetzt noch mal genauer getestet.
Das Programm bleibt bereits bei
1
  if (mmc_send_cmd(CMD0, 0) == 1) {      // Enter Idle state
Hängen danach bekomme ich keine Ausgabe über UART mehr.
Wenn ihr weiter Informationen bracht kann ich die nachliefern.
Ich hoffe jetzt kann mir jemand helfen.

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Hast du die
 TimingDelay
Geschichte in den Basistimer eingefügt?

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Ich hab das so eingebaut:
1
ISR (TIMER0_COMPA_vect)
2
{
3
  TimingDelay = (TimingDelay==0) ? 0 : TimingDelay-1;
4
}

Und der Timer wird so gestartet:
1
 static void timer0_init(){
2
3
  TimingDelay = 0;    // initialisierung der zaehl variable  
4
5
  TCCR0A = 1<<WGM01;     // timer0 im ctc mode
6
  TIMSK0 = 1<<OCIE0A;    // compare interrupt an
7
8
  TCNT0 = START_TCNT;    // ab wo hochgezaehlt wird,
9
  OCR0A = TOP_OCR;    // maximum bis wo gezaehlt wird bevor compare match  
10
11
  TCCR0B = PRESCALER;    // wenn prescaler gesetzt wird, lauft timer los
12
  sei();          // interrupts anschalten, wegen compare match
13
}

von Matthias L. (mcl024)


Lesenswert?

Ich habe ein Problem beim Lesen meiner microSD-Karte. Wenn ich mir die 
Daten anzeige die gelesen wurden, entdecke ich immer vier Bytes die 
zusätzlich zu den Daten auf der SD-Karte hinzugefügt wurden und zwar 
immer genau nach 512 Bytes folgen 0xB9 0x33 0xFF 0xFE

Woher kommen die?

von Matthias L. (mcl024)


Lesenswert?

Ah jetzt weiss ich es. Das müsste die CRC sein (0xB9, 0x33) und 0xFE das 
Startbyte für den nächsten Block. 0xFF weiss ich noch nicht.

Gibts es auch ein Kommando wo die CRC nicht mit ausgegeben wird?

von Manuel V. (manuelito)


Lesenswert?

Hallo,

Ich habe mir gerade aus dem Wiki die Datei AVR-mmc-0.6.4.zip 
heruntergeladen und versuche die gerade zu kompilieren, allerdings 
bekomme ich folgende Fehlermeldungen:

Error  1  'TCCR0A' undeclared (first use in this function) 
D:\AVR-Studio\sdtest0\sdtest0\main_simple.c  80  2  sdtest0

Error  2  each undeclared identifier is reported only once for each 
function it appears in  D:\AVR-Studio\sdtest0\sdtest0\main_simple.c  80 
2  sdtest0

Error  3  'TIMSK0' undeclared (first use in this function) 
D:\AVR-Studio\sdtest0\sdtest0\main_simple.c  81  2  sdtest0

Error  4  'OCIE0A' undeclared (first use in this function) 
D:\AVR-Studio\sdtest0\sdtest0\main_simple.c  81  14  sdtest0

Error  5  'OCR0A' undeclared (first use in this function) 
D:\AVR-Studio\sdtest0\sdtest0\main_simple.c  84  2  sdtest0

Error  6  'TCCR0B' undeclared (first use in this function) 
D:\AVR-Studio\sdtest0\sdtest0\main_simple.c  86  2  sdtest0

Ich benutze einen ATmega16.


Und noch eine Frage: Ich habe eine "SD-Platine", bei der folgende 
Pinbelegung gegeben ist:
Dat2 - unrouted
CS   - PIN 3 (über 1,8k/3,3k Spannungsteiler)
DI   - PIN 5 (über 1,8k/3,3k Spannungsteiler)
GND  - GND
VCC  - VCC über LF33CV
CLK  - PIN 7 (über 1,8k/3,3k Spannungsteiler)
GND  - GND
DO   - PIN 6 (mit einer 3,3V Zenerdiode von dieser Leitung zu GND)
DAT1 - unrouted

Kann ich diese Platine überhaupt verwenden? Und wenn ja an welchen Port 
soll ich sie am Besten anschließen?
Und welche Anpassungen muss ich dann in den Dateien vornehmen?

Viele Grüße,
Manuelito

von Michael M. (eos400dman)


Lesenswert?

@ Manuel Vossel.
Die Register haben beim Atmega 16 andere Bezeichnungen. Musst du mal im 
Datenblatt nachschauen.

Kann mir keiner bei meinem Problem helfen?
Das Programm bleibt bereits bei
1
 if (mmc_send_cmd(CMD0, 0) == 1) {      // Enter Idle state
stehen.

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Dann stimmt etwas mit deinem Programm aber nicht, weil hängen bleiben 
dürfte er da doch gar nicht.
 Ich hatte damals viel an dieser Funktion rumgepätscht (siehe auch meine 
Posts zur Init weiter oben) damit sie mit allen meinen Karten lief, aber 
wenn du den "aktuellen" Patchstand hast gibt es auch hier ein Timeout.

Wenn du Interesse hast kann ich dir meine init nochmal posten zum 
Vergleich.

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Das wäre sehr nett von dir.

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Ich poste hier mal nur die Init...vielleicht reichts ja:
1
unsigned char mmc_init (void){
2
3
  unsigned char cmd, ty, ocr[4];
4
  unsigned short n, j;
5
6
  spi_init();
7
  mmc_disable();
8
9
  for (n = 100; n; n--) spi_read_byte();    // 80 dummy clocks
10
11
  ty = 0;
12
  j=100;
13
do {
14
  if (mmc_send_cmd(CMD0, 0) == 1) {      // Enter Idle state 
15
    j=0;
16
    TimingDelay = 100;            // Initialization timeout of 1000 msec
17
18
    if (mmc_send_cmd(CMD8, 0x1AA) == 1) {  // SDv2? 
19
      for (n = 0; n < 4; n++){
20
        ocr[n] = spi_read_byte();    // Get trailing return value of R7 resp 
21
        }
22
      if (ocr[2] == 0x01 && ocr[3] == 0xAA) {            // The card can work at vdd range of 2.7-3.6V 
23
      
24
//        while (TimingDelay && mmc_send_cmd(ACMD41, 1UL << 30));  // Wait for leaving idle state (ACMD41 with HCS bit)
25
        while (TimingDelay) {  // Wait for leaving idle state (ACMD41 with HCS bit)
26
          mmc_send_cmd(CMD55, 0);
27
          if(!mmc_send_cmd(ACMD41, 1UL << 30))
28
            break;
29
        }
30
31
        while(TimingDelay) {
32
        if (mmc_send_cmd(CMD58, 0) == 0x00) {    // Check CCS bit in the OCR 
33
          for (n = 0; n < 4; n++){
34
            ocr[n] = spi_read_byte();
35
            }
36
          ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;  // SDv2 
37
/*
38
            if(ocr[0] & 0x40) {
39
             ty = CT_SD2 | CT_BLOCK;
40
            } else {
41
             ty = CT_SD2;  // SDv2 
42
            }
43
*/
44
          break;
45
        }
46
        }
47
//ty = CT_SD2 | CT_BLOCK;
48
49
50
51
      }
52
    } else {        // SDv1 or MMCv3 
53
      if (mmc_send_cmd(ACMD41, 0) <= 1)   {
54
        ty = CT_SD1; 
55
        cmd = ACMD41;  // SDv1 
56
      } else {
57
        ty = CT_MMC; 
58
        cmd = CMD1;    // MMCv3 
59
      }
60
      while (TimingDelay && mmc_send_cmd(cmd, 0));      // Wait for leaving idle state 
61
    }
62
//      if (!TimingDelay || mmc_send_cmd(CMD16, 512) != 0)    // Set R/W block length to 512 
63
//        ty = 0;
64
    if(ty != (CT_SD2 | CT_BLOCK)) {
65
      while(TimingDelay && (mmc_send_cmd(CMD16, 512) != 0));
66
    }
67
    if(!TimingDelay) ty = 0;
68
  } else { j--; }
69
  }while(j>0);
70
  fat.card_type = ty;
71
  mmc_disable(); 
72
73
  if( fat.card_type == 0 ){
74
    return FALSE;
75
  }
76
  #if (MMC_MAX_SPEED==TRUE)
77
    spi_maxSpeed();
78
  #endif
79
80
  return TRUE;
81
}

ich hatte (siehe auch oben bei meinem Patchvorschlag schon angemerkt, 
dass meiner Meinung nach der ACMD41 falsch definiert ist. Bei mir gings 
jedenfalls top nach Änderung:
1
#define  ACMD41  (41) // (0x80+41)  // SEND_OP_COND (SDC)

Ich konnte jedenfalls am Ende alle vorhandenen Karten initialisieren und 
ansprechen.

Genaueres auch oben unter: 
Beitrag "Re: MMC SD library FAT16 FAT32 read write"

Gruß
Fabian

von Manuel V. (manuelito)


Lesenswert?

Also mein Problem hat sich mittlerweile erledigt, ich hatte irgendwie 
ein Hardwareproblem auf meiner Platine.
Ich habe zwar alles mit dem Multimeter durchgepiepst, aber irgendwas 
schien wohl doch kaputt zu sein - mit einer anderen Platine funktioniert 
es nämlich jetzt :-)

Eine Frage habe ich aber noch: Bei ffread() werden ja immer 512 Byte 
gelesen und der Rest zwischengepuffert.
In meinem speziellen Fall wird es allerdings so sein, dass ich alle 40ms 
eine bestimmte Anzahl Byte benötige (wahrscheinlich 432, steht aber noch 
nicht fest), die sich auch nicht ändern wird. Das ganze ist für eine 
LED-Animation, dort will ich einen digitalen RGB-Strip im 25Hz-Takt mit 
Daten füttern. Wäre es dann sinnvoll, diesen Puffer auf 432 Byte (oder 
wieviele es nachher werden) zu verkleinern? Bzw. falls ich mehr brauche 
auf soviel erhöhen?
Da ich mittlerweile einen ATmega644 habe ist RAM nicht mehr so ein 
großes Problem.

Ich blicke den Quellcode leider nicht ganz, daher kann ich nicht 
wirklich sagen, wie dieser Puffer einen Geschwindigkeitsvorteil bringt - 
daher hier die Frage.

Viele Grüße,
Manuelito

von Thilo M. (Gast)


Lesenswert?

Manuel Vossel schrieb:
> Also mein Problem hat sich mittlerweile erledigt, ich hatte irgendwie
> ein Hardwareproblem auf meiner Platine.

Da kann ich auch nur drauf hinweisen, das Problem hatte ich auch!
Es kommt wirklich auf eine sehr ordentliche Hardware mit sauberer, 
stabiler Versorgung an.
Ich hatte das Erweiterungsboard für AVR-NET-IO von Pollin und kann nur 
sagen: Finger weg, das Ding ist Schrott! Falsche Dimensionierung, 
falsche Bauteilwahl, Layout muss angepasst werden (Kratzen und Drähte 
einflicken), SD-Kartenhalter hakt.

Kurz und Gut, wenn man schon Elkos für digitale Technik verwendet, dann 
bitte low-ESR. Der Müll, der von Pollin geliefert wird (step-up-Regler 
statt linear-Spannungsregler für 3.3V), lässt die Karte immer mal wieder 
abschmieren (hängt sich auf). Nachdem ich ordentliche Bauteile 
draufgebaut hatte, lief alles wunderbar.

von Thilo M. (Gast)


Lesenswert?

Mein Problem besteht leider immer noch:

- minutenweises Schreiben, ca. 200 Byte pro Datensatz
- täglich wird ein neues File angelegt
- MMC_MAX_CLUSTERS_IN_ROW auf 16383

Nach zwei Tagen wird ein neues File angelegt und ein Stück weit 
beschrieben, danach bleibt das Chipselect auf low und die Karte hängt 
sich auf (bleibt in der Schreib- oder Lesefunktion hängen). Das neu 
angelegte File ist dann defekt.

Hat irgend jemand eine Lösung für dieses Problem?
Ich bin da irgendwie ratlos.

von Michael M. (eos400dman)


Lesenswert?

Nach langem Suchen hab ich die SD-Karte endlich zum laufen bekommen.

Jetzt hab ich noch zwei Fragen:
1. Kann ich, und wenn ja wie kann ich den verbleibenden Speicherplatz 
bestimme?
2. Wie gehe ich beim trennen der SD-Karte vom AVR ab besten vor? Ich hab 
einen Taster den ich drücken will bevor ich die Karte abziehe. Aber wie 
beende ich die Kommunikation ordnungsgemäß?

Gruß Michael

von Fabian B. (fabs)


Lesenswert?

Hallo Michael,
 woran lag's denn schlussendlich?

Zu 1) Gute Frage ;-)
Zu 2) ein fflushFileData() und danach ein ffclose() sollten alles nötige 
erledigen.

Gruß
Fabian

von Michael M. (eos400dman)


Lesenswert?

Fabian B. schrieb:
> Hallo Michael,
>  woran lag's denn schlussendlich?

Das weiß ich auch nicht genau. Nachdem ich den Spannungsregler 
ausgetauscht habe ging es. Der hat zwar zuvor auch 3,3 V rausgegeben 
aber vielleicht ist er kurz Eingebrochen ( Auf dem Oszi war aber nichts 
zu sehen).

Gruß Michael

von Peter S (Gast)


Lesenswert?

Hallo,

erst mal Danke für die tolle Vorarbeit hier. Damit habe sogar ich es 
hinbekommen Daten auf SD-Karten zu schreiben.
Doch jetzt bin ich auf ein Problem gestoßen:
Ich bekomme jede 10 Sekunden einen Datenstring den ich auf die Karte 
schreiben möchte (Datei öffnen -> schreiben -> Datei schließen)
Nun habe ich das Problem, dass genau 512 Datensätze geschrieben werden 
und alle weiteren im Nirwana verschwinden.
An der Dateigröße kann es kaum liegen, zu Testzwecken habe ich schon 
viel größere Datenmengen schreiben können. Da habe ich die Datei aber 
nicht ständig auf- und wieder zugemacht. Liegt das evtl. daran?

Ich möchte aber nicht die Datei die ganze Zeit offen lassen, damit die 
Daten nicht verloren gehen, wenn man die Karte aus dem Leser zieht, ohne 
sie vorher sauber zu beenden.

Danke schon mal.

Gruß
Peter

von Peter S (Gast)


Lesenswert?

Dann antworte ich mir mal selber :)

Problem hab ich umgangen, indem ich alle x Durchläufe ein 
fflushfiledata() mache und nur ganz am Ende, wenn ich regulär das 
Programm verlasse. Wenn die Karte nicht ordnungsgemäß entfernt wird, 
gehen nur ein paar Daten verloren und nicht alle.

von Peter S (Gast)


Lesenswert?

Peter S schrieb:
> Programm verlasse.

... ein ffclose() machen.

sorry, vergessen

von Dirk (Gast)


Lesenswert?

Hi zusammen,

so wie ich das sehe, ist es mit den Funktionen nur möglich immer nur 
eine Datei zur Zeit zu öffen. Richtig?

Ich bräuchte eine Lib mit der ich zwei (verschiedene) Dateien zeitgleich 
öffnen kann. Theoretisch würde es reichen das nur eine Datei geschrieben 
und die andere nur gelesen wird.

Wie schwierig / groß wäre die Änderung der Lib?

Danke!

von Fabian B. (fabs)


Lesenswert?

Beschreibe doch mal deinen Anwendungsfall. Meist ist sowas nämlich nur 
auf den ersten Blick nötig...

Gruß
Fabian

von Dirk (Gast)


Lesenswert?

Hi Fabian,

ich habe einen Navtex und DWD (Wetter) Empfänger gebaut, der die 
Textmeldungen auf einer SD Karte speichert (FAT16/32).

Der User kann über ein GLCD die Meldungen auswählen und sich anzeigen 
lassen.
Funktioniert super, da ich bisher nur alle 3 Stunden für ca. 10 Minuten 
Meldungen empfange (Navtex). Die DWD Meldungen hatte ich bisher auch 
stark eingegrenzt. So störte es nicht wenn der User mal für 10 - 20 
Minuten keine Meldungen lesen konnte. (Die Datenübertragung läuft mit 50 
Baud :o)

Jetzt will ich evtl. ständig alle DWD Meldungen aufzeichnen (der Sender 
läuft 24/7) und daher ist fast immer eine Datei geöffnet. Der User hat 
nur noch zwischen den einzelnen Meldungen die Gelegenheit zu lesen. Das 
geht gar nicht :-/

Viele Grüße,
Dirk

von Georg M. (georgmeyer)


Angehängte Dateien:

Lesenswert?

Servus alle miteinander!

Super Paket, gefällt mir super und funktioniert noch viel besser!

Da ich eine energieoptimierte Schaltung entwickle, hatte mich der 
laufende Timer und vor allem der Aufruf der ISR gestört, die permanent 
aufgerufen wurde.

Das habe ich behoben, indem beim setzen der Werte in die Variable 
TimingDelay durch den Aufruf der Funktion TimingDelay_set(uint_8t time) 
erledigt wird.

Die Funktion schaltet anschließend den Timer und dessen Interrupts ein ( 
eine Initialisierung des Timers muss vorher dennoch erfolgen).

Die Variable selber kann weiterhin wie gewohnt verwendet werden.

Die ISR wurde dahingehend verändert, dass sie den Timer und dessen 
Interrupts deaktiviert, sofern die Variable den Wert 0 erreicht hat.

1
ISR (TIMER3_COMPA_vect)
2
{
3
  if (TimingDelay--==0)
4
  {
5
     TCCR3B=0;  // disable timer
6
     TIMSK3 &= ~(1<<OCIE3A); // disable timer interrupts
7
  }
8
}
9
10
11
12
// *****************************************************************************************************************
13
static void timer3_init(){
14
15
  TimingDelay = 0;    // initialisierung der zaehl variable  
16
  cli();
17
  TCCR3A = 1<<WGM01;     // timer0 im ctc mode
18
  TIFR3 &=~(1<<OCF3A);  //clearing interrupt flag
19
  TIMSK3 |= 1<<OCIE3A;    // compare interrupt an
20
21
  TCNT3 = START_TCNT;    // ab wo hochgezaehlt wird,
22
  OCR3A = TOP_OCR;    // maximum bis wo gezaehlt wird bevor compare match  
23
24
  //TCCR3B = PRESCALER;    // wenn prescaler gesetzt wird, lauft timer los
25
  sei();          // interrupts anschalten, wegen compare match
26
}
27
28
static void TimingDelay_set ( uint8_t time)
29
{
30
  TimingDelay=time;
31
  cli();
32
  TIFR3 &=~(1<<OCF3A);  //clearing interrupt flag
33
  TIMSK3 |= (1<<OCIE3A);
34
  TCCR3B = PRESCALER;
35
  sei();
36
}

Die entsprechenden Änderungen in der mmc.c habe ich bereits vorgenommen 
und den Timer und dessen dazugehörigen Parts mit eingebunden...

Da ich den AT90CAN128 verwende, ist der Timer 1 ein 8Bit Timer, weswegen 
ich die entsprechenden Register auf Timer 3 geändert habe.

Die mmc.c befindet sich im Anhang. Es wurde die aktuelle Version 0.6.4 
verwendet.

Viele Grüße und frohes Fest!


Georg

von Fabian B. (fabs)


Lesenswert?

Warum machst du dir so eine Mühe? Wenn du die tieferen Sleep-Modus 
benutzt, werden die Timer eh gestoppt...

Gruß
Fabian

von Georg M. (georgmeyer)


Lesenswert?

Weil die ISR nicht unendlichmal oft aufgerufen werden muss, wenn sie 
nicht gebraucht wird.

MfG

von Fabian B. (fabs)


Lesenswert?

Hast du keinen Basistimer der eh immer läuft? Der kann das ja mit 
machen...

Aber solange die CPU mit Takt X läuft isses für den Stromverbrauch 
zumindest gleich, ob der Timer 1000 oder 1 Mal pro Sekunde aufgerufen 
wird.

Gruß
Fabian

von Torsten (Gast)


Lesenswert?

Hallo!
Ich versuche grad meine SD Karte mit Soft SPI anzusteuern (PORTA), weil 
bei mir schon ein VS1011 am SPI Port hängt und die beiden mögen sich 
anscheinend nicht. Deswegen hab ich mir gedacht, dass ich die SD Karte 
einfach per Soft Spi auf einem anderen Port ansteuere.
Aber es funktioniert gar nicht mit PORTA.
ich hab in der config.h

#define MMC_SOFT_SPI       TRUE

geändert und mmc.h meine Pins

#if defined (_AVR_ATmega644_)
#define SPI_MISO       2
#define SPI_MOSI                4
#define SPI_Clock       3
#define SPI_SS        5
#endif

Programm Compiliert, es läuft nicht.

dann hab ich die SPI Pins vom PortB wieder zusätzlich angelötet.
und nochmal kompiliert und es lief.
Aber der Grund ist: in der mmc.c spi_init() warum es auf PORTB läuft und 
auf PORTA nicht.
diese Zeile SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
eigentlich braucht man diese Zeile für Soft SPI nicht. oder?
Weil wenn ich diese Zeile wegkommentiere dann läuft es auch auf PORTB 
nicht mehr.
Hab ich vielleich was übersehen?

von Volker W. (volker_w24)


Lesenswert?

Hallo!
Tolle Lib! - die ich nur zum Lesen von Daten von der SD-Karte verwende. 
Bisher hatte ich Daten immer nur vom Stammverzeichnis der Karte gelesen, 
ging mit der Version 0.6.1 auch bestens. Nun möchte ich aber meine Daten 
von Dateien aus 2 Verzeichnisebenen lesen, und dazu munter zwischen den 
Verzeichnissen hin und her wechseln. Mittels ffcd() war es nicht 
möglich, überhaupt in ein Verzeichnis hinein zu wechseln. Daher habe ich 
die jetzt aktuelle Vers. 0.6.4 heruntergeladen. Hier funktioniert ffcd() 
bestens, nacheinander ffcd(Verzeichnis_Ebene_1) , 
ffcd(Verzeichnis_Ebene_2) wechselt auch in die Verzeichnisse, ich kann 
die dortigen Dateien problemlos lesen.
LEIDER komme ich aber aus dem Verzeichnis nicht zurück, d.h. ffcdLower() 
funktioniert nicht. Muss ich evtl. bei den Verzeichnisnamen und 
Dateinamen irgendwas beachten, damit ich auch mal wieder aus einem 
direktory zurück komme? Habe den gesamten Thread durchgelesen - bin aber 
mit dem Problem scheinbar allein?

Gruß Volker

von Dirk (Gast)


Lesenswert?

Keine Ahnung ob das mit der Lib geht:
cd ..
wars zu DOS Zeiten.

von Buzzwang (Gast)


Lesenswert?

Hallo,

Volkers Nachricht kann ich bestätigen.

cdlower tut nicht richtig.
In meinem Fall bin ich ein Verzeichnis tiefer gegangen.
Das erste cdlower tat garnichts. Nach dem 2. cdlower war ich wieder auf 
dem Root.

Verzeichnis löschen geht auch nicht.

Info:
Zum Test habe ich die FAT-Sourcen in ein PC-Projekt (VC6.0) eingebunden.
Jedoch wird nur Fat.c und File.c verwendet.
Von einer SD-Karte habe Disk-Image gemacht.
Mmc.c greift nun auf das Image zu, statt auf SPI.

von Georg M. (georgmeyer)


Angehängte Dateien:

Lesenswert?

For all my lovely friends

True ist ein boolscher Ausdruck etc und blabla...

  #ifndef TRUE
  # define TRUE (1==1)
  #endif

  #ifndef FALSE
  # define FALSE (0==1)
  #endif


macht weniger Probs im Zusammenhang mit anderen Bibliotheken.

Ferner habe ich die entsprechenden Stellen geändert in den Dateien im 
Anhang (Variablen unt Rückgabewerte direkt durch 1 und 0 ersetzte und 
sonst den Status mit if (status) oder if (!Status) ersetzt).

Jetzt schmiert der Kompiler bei mir bei Verwendung der CAN lib von Atmel 
auch nicht mehr ab :)
(war der Fall, doppelte Definierung und so.... )

Viel Spaß damit!


MfG


Ps.: Weiterhin sind die Änderungen bezüglich des Timers enthalten (siehe 
weiter oben im Thread...)

Edit: Wäre super, wenn 'der Herr der Dateien' das mit in die nächste 
Revision rein packt.

von Georg M. (georgmeyer)


Lesenswert?

für die file.c:
1
void ffwrites( uint8_t *s ){
2
    while (*s){
3
      ffwrite(*s++);
4
    }
5
    fat.bufferDirty = 1;
6
  }
7
8
void ffwrites_P(const char *progmem_s)
9
{
10
    register char c;
11
    while ( (c = pgm_read_byte(progmem_s++)) ) 
12
  {
13
        ffwrite(c);
14
    }
15
  fat.bufferDirty = 1;
16
}
17
#endif

für die file.h
1
  #include "avr/pgmspace.h"
2
3
  extern void    ffwrites_P(const char *progmem_s)  ;

damit kann man strings aus dem Flash auf die SD-Karte schreiben.


Ferner gehören die Strukturdeklarationen
File_t in die file.h
und Fat_t und Chain_t in die fat.h

Sonst kommt es verinzelt zu Problemen mit der Umgebung (AVR STudio 5)(in 
unschönen Fällen kompiliert er dann nicht mehr).

in die mmc.h muss
1
#include "fat.h"
eingefügt werden.

von milan (Gast)


Lesenswert?

Hallo zusammen,
wie kann ich zeilenweisse eine TXT Datei auslesen???
Gruss
Milan

von Georg M. (georgmeyer)


Lesenswert?

1. Datei öffnen
2. Daten lesen.

Ein Zeilenende wird durch 0x0d 0x0a gekennzeichnet.


Wenn du diese beiden Bytes in der Reihenfolge gelesen hast, weisst du, 
dass danach eine neue Zeile beginnt.

Schau dir einfach mal eine text Datei auf dem PC mit einem Hex Editor 
wie 'Hex Editor MX' an.

MfG

von milan (Gast)


Lesenswert?

Hallo,
ja so habe ich es probiert,es kommt nur mühl aus.

        unsigned char test54;
  if( MMC_FILE_OPENED == ffopen(file_name,'r') ){
    seek = file.length;
    do{
      strcpy(test54, ffread());
    }while(--seek);
    ffclose();
  }
hier ausgabe.

Was mache ich falsch??
Gruss
Milan

von Georg M. (georgmeyer)


Lesenswert?

1
unsigned char test54;
2
  if( MMC_FILE_OPENED == ffopen(file_name,'r') ){
3
    seek = file.length;
4
    uint8_t temp=0;
5
    uint8_t last_character;
6
    do{
7
      strcpy(test54, ffread());
8
      if ( test54 == 0x0a && last_character== 0x0d)
9
       {
10
          // Zeilenumbruch
11
       }
12
      else
13
      {
14
        last_character=test54 ;
15
      }
16
17
    }while(temp++<=seek);
18
    ffclose();
19
  }


Du hast die Datei rückwärts, angefangen beim Ende ausgelesen.
Jetzt beginnst du beim Anfang.

Sollte so funktionieren.

Arbeite mit Breakpoints, dann kommst du auch alleine auf die Lösung ;)

von milan (Gast)


Lesenswert?

Hallo zusammen,
ich habe es so jetzt abgeendert:
  unsigned char test54;
  char test56[200];
  if( MMC_FILE_OPENED == ffopen(file_name,'r') ){
    seek = file.length;
    uint8_t temp=0;
    uint8_t last_character;
    do{
      strcpy(test54, ffread());
      if ( test54 == 0x0a && last_character== 0x0d)
       {
         break;
       }
      else
      {
        last_character=test54 ;
  test56[temp] = last_character;

      }

    }while(temp++<=seek);
    ffclose();
  }
  DisplayText(0,10,test56); // heir brauche ich eine Char Array zur 
ausgabe oder einen String;

es kommt nichts raus weil die funktion nie aufhürt du laufen. obwohl 
eine break beim zeilen umbruch ist!

Gruss
Milan

von milan (Gast)


Lesenswert?

Hallo funktioniert immer noch nicht.
kommt nur mühl raus.

Kann mir bitte jemand helfen???

Danke
Gruss
Milan

von milan (Gast)


Lesenswert?

Hallo zusammen,
funktioniert alles bestens!
Den code habe ich verwendet:
1
              
2
char test56[200];
3
  if( MMC_FILE_OPENED == ffopen(file_name,'r') ){
4
    seek = file.length;
5
    uint8_t count=0, count1=0, count2=0;
6
  int c;
7
    uint8_t last_character;
8
   
9
   
10
while(count1<seek) {
11
  count=0;
12
    c=ffread();
13
    while( (c!='\n') )
14
    {
15
      test56[count]=c;
16
      c=ffread();
17
      count++;
18
    count1++;
19
    }
20
    count--;
21
    test56[count]='\0';
22
  DisplayText(0,10*count2,test56);
23
  count2++;
24
}
25
    ffclose();
26
  }

Gruss
Milan

von milan (Gast)


Lesenswert?

Hallo zusammen,
es ist ein neuer Problem aufgetaucht!
1
 if( MMC_FILE_OPENED == ffopen("spot.txt",'r') )
2
  {
3
      
4
      unsigned long int seek =file.length;
5
      
6
      unsigned long int count=0, count2=0;
7
      unsigned long int count1=0;
8
      int zeichen;
9
      char ausgabe[12][50];
10
   
11
      while(seek>=count1) 
12
      {
13
        char test56[260];
14
        count=0;
15
        zeichen=ffread();
16
        while((zeichen!='\n')&&(seek>=count1) )
17
        {
18
            test56[count]=zeichen;
19
            zeichen=ffread();
20
            count++;
21
            count1++;
22
23
            
24
25
            //_delay_ms(50);
26
        }
27
        //count--;
28
        test56[count]='\0';
29
        DisplayText(0,10*count2,test56);
30
        count2++;
31
        
32
        int j;
33
        char d;
34
        int nr2=0,pos2=0;
35
36
        for(j=0;j<strlen(test56)-1;j++) 
37
        {
38
            d=test56[j];
39
            if(d==0) break;
40
    
41
            if(d==',') 
42
            {
43
                // wenn Trennungszeichen
44
                ausgabe[nr2][pos2]=0; // endekennung
45
                nr2++;
46
                pos2=0;
47
                
48
            }
49
            else 
50
            {
51
                // wenn normales zeichen
52
                ausgabe[nr2][pos2]=d; // zeichen speichern
53
                pos2++;
54
            }
55
            
56
        }
57
        
58
      
59
        
60
      }      
61
    ffclose();
62
  }
wenn ich mit der funktion auslese, schreibt mir immer ein paar 
lehrzeichen auf ende. jedes mahl ein paar. obwohl nur lesen ist.

Weiss jemand zufälig warum??
oder was ich da falsch mache??

Danke im Voraus
Milan

von Georg M. (georgmeyer)


Angehängte Dateien:

Lesenswert?

Bugfix von meinem Post vom 20.01.2012 18:01

in der Fat.c war ein Fehler enthalten. Dieser ist nun behoben.


MfG

von Chris (Gast)


Lesenswert?

Hallo und erst mal danke für diese tolle Lib.

Habe so weit alles zum laufen bekommen,
nur bekomme ich beim auslesen der karte nur murx raus.
Eigentlich sollte  -> Inhalt der Testdatei 0123456789 <- ausgelesen 
werden.
Statdessen bekomme ich das hier:
----------------------------------------------------------------
Boot...Ok

Datei wird geoeffnet:

gelesen:





``

ÿ


``
ÿ


`






ÿ


```
``
`




``
---------------------------------------------------------------------
Woran kann das liegen ?

Es wird genau die richtige Anzahl an Chars ausgelesen aber eben falsch 
übermittelt oder so.

Hardware SPI, SANDISK 4GB SDHC, AT90USB1287 @ 8MHz

Liebe Grüße Chris

von Fabian B. (fabs)


Lesenswert?

Meine Glaskugel sagt: deine UART-Baudrate ist falsch.

(Wie gibts du aus? Bist du sicher, dass die Ausgabe ok ist? Mehr Info 
bitte)

Gruß
Fabian

von Chris (Gast)


Lesenswert?

Meine Bautrate scheint OK zu sein, da ich ja folgenden Text angezeigt 
bekomme... nur eben der inhalt der Karte wird falsch gelesen denke ich


Chris schrieb:
> Boot...Ok
>
> Datei wird geoeffnet:
>
> gelesen:
______________________________________________________________________ 
_
Hier mal mein C-Code.
1
#include <stdlib.h>
2
#include <avr/io.h>
3
// In config.h werden alle nötigen Konfigurationen vorgenommen
4
#include <config.h>
5
#include <file.h>
6
#include <fat.h>
7
 
8
// Hardwareabhängig
9
#include <mmc.h>
10
 
11
// Hardwareabhängig, es kann auch eine eigene eingebunden werden !    
12
#include <Rs232.h>
13
 
14
 
15
//**************************************************************************
16
 
17
int main (void)
18
{
19
  DDRB |= (1<<PB5);
20
  PORTB |= (1<<PB4) | (1<<PB5);  
21
22
  rs232_initialisieren(9600);
23
  
24
  while( PINB & (1<<PB4))
25
  {
26
    rs232_text("\nkeine Karte eingesteckt");
27
  }  
28
29
    
30
    rs232_text("\nBoot");
31
 
32
  // Versuch Karte zu Initialisieren, bis es klappt.
33
  // Unbedingt so, weil die Initialiesierung nicht immer
34
  // auf Anhieb klappt.
35
  while (FALSE == mmc_init())
36
  {
37
    nop();
38
  }
39
 
40
  rs232_text("...");
41
 
42
  // Fat initialisieren. Nur wenn das klappt sind weitere
43
  // Aktionen sinnvoll, sonst endet das Programm.
44
  if (!fat_loadFatData())
45
        return -1;
46
 
47
  // Wenn auf dem terminal "Boot... OK" zu lesen ist, ist Init OK.
48
  // Jetzt kann man Schreiben/Anhängen/Lesen.
49
  rs232_text("Ok\n");
50
 
51
52
  
53
54
  // Datei existiert, also lesen.
55
  // Gerade angelegt und beschrieben, oder war schon vorhanden
56
  // und es wurde was angehaengt?
57
  if (MMC_FILE_EXISTS == ffopen("TEST    TXT"))
58
  {
59
60
    rs232_text("\nDatei wird geoeffnet:\n");
61
      // Setzen einer Variable und dann runterzählen geht
62
      // am schnellsten
63
      unsigned long int seek = file.length;
64
 
65
      // Lesen eines chars und Ausgabe des chars.
66
      // Solange bis komplette Datei gelesen wurde.
67
      do {
68
      rs232_text("\n");
69
          rs232_text(ffread());
70
      } while (--seek);
71
 
72
      ffclose();
73
  }
74
75
  else rs232_text("\nDatei konnte nicht gefunden werden");
76
77
78
79
}

von Fabian B. (fabs)


Lesenswert?

Das ist aber nicht der Code zu deiner Ausgabe. Das "gelesen:" wird in 
dem Code ja nirgends geschickt.

Aber kann es sein, dass dein rs232_text() einen Zeiger erwartet, 
ffread() aber einen char zurückgibt? Was ist denn die Deklaration von 
rs232_text()?

Gruß
Fabian

von Chris (Gast)


Lesenswert?

Hallo Fabian...


Fabian B. schrieb:
> Aber kann es sein, dass dein rs232_text() einen Zeiger erwartet,

genau das war auch der Fehler. Hab ich gar nicht dran gedacht.
Jetzt klappt es wunderbar.

Vielen dank für die Hilfe

LG Chris

von Andre I. (scuido)


Lesenswert?

Hey,

ich habe eine Frage. Ich habe das Problem, dass ich geschriebene Strings 
nicht mehr lesen kann.

Das File wird richtig geschrieben und ich kann mit Windows auch drauf 
zurgreifen. Auch werden Strings korrekt angehängt.

Ich bekomme beim Auslesen mit den µC aber immer nur 
0xFA,0x07,0xFA,0x07,...,0xFA,0x07. An der RS232-Kommunikation liegt das 
nicht.

Woran kann das liegen? Ich würde mich freuen, wenn jemand helfen kann :)


// Der Code:
1
int main(void)
2
{  
3
  uint32_t seek;
4
  Initialization();
5
       
6
  //PINA |= (1<<Door_Relay) | (1<<LED1) | (1<<LED2); // Relay einschalten 
7
  
8
  uint8_t file_name [] = "test_file.txt";
9
  uint8_t str [] = "Hallo Datei 2! Andre Iwers ist der Coolste :)";
10
11
  uart1_puts("\nBoot");
12
13
  // sd/mmc config  **************************************************
14
  if( FALSE == mmc_init() )
15
  {
16
    uart1_puts("\nKeine SD gefunden.... Ende....");
17
    return;
18
  } 
19
      
20
  // fat config ******************************************************
21
  if( FALSE == fat_loadFatData() )
22
  {
23
    uart1_puts("\nDateisystem nicht vorhanden.... Ende....");
24
    return;
25
  }
26
27
  // wenn auf dem terminal "Boot...OK" zu lesen ist, war initialisierung erfolgreich!
28
  uart1_puts("...OK\n");
29
30
31
    // if file exists, it will be opened and then append to it.
32
    if( MMC_FILE_OPENED == ffopen(file_name,'r') ){      
33
      ffseek(file.length);
34
         ffwrites(str);        
35
      ffwrite(0x0D);    // new line in file
36
         ffwrite(0x0A);
37
      ffclose();
38
    }        
39
    else if(MMC_FILE_CREATED == ffopen(file_name,'c') ){
40
      ffwrites(str);        
41
      ffwrite(0x0D);    // new line in file
42
         ffwrite(0x0A);
43
      ffclose();
44
    }   
45
46
  // ***************************************************
47
  // read file complete and print via uart!
48
  if( MMC_FILE_OPENED == ffopen(file_name,'r') )
49
  {      
50
    seek = file.length;
51
    do
52
    {
53
      uart1_puts(ffread());            
54
    }while(--seek);
55
    
56
    ffclose();
57
  }
58
  while(1);
59
}


Viele Grüße,
André

von Andre I. (scuido)


Lesenswert?

Habe einen Fehler gefunden...

Hatte versehentlich einen String übertragen und kein Char.
1
  // ***************************************************
2
  // read file complete and print via uart!
3
  if( MMC_FILE_OPENED == ffopen(file_name,'r') )
4
  {      
5
    seek = file.length;
6
    do
7
    {
8
      uart1_putc(ffread());     
9
    }while(--seek);
10
    
11
    ffclose();
12
  }

Jetzt bekomme ich aber immer nur 0x00 als Rückgabewert.

Jemand noch eine Idee?

von Andre I. (scuido)


Lesenswert?

Fehler behoben, scheinbar war das Dateisystem nicht mehr so gesund. Nach 
Formatierung läufts nun wunderbar.

von Milan (Gast)


Lesenswert?

Hallo zusammen,
wie kann man eine zeile in einer TXT datei löschen???

Gruss
Milan

von Christoph Vogel (Gast)


Lesenswert?

@Andre Iwers:

Du hast auch einen 9.3 Dateinamen verwendet, vieleicht zerstört das die 
fat. Laut Doku -http://www.mikrocontroller.net/articles/AVR_FAT32- 
dürfen nur 8.3 Dateinamen verwendet werden.

@Milan:
Deine Frage ist etwas undeutlich. Daten auf der Disk sind physikalisch.
Aber es gibt 2 Möglichkeiten:
1. Die Datei kopieren und dabei die Textzeile überspringen, die alte 
Datei löschen und die neue Datei umbenennen.
2. Wenns nur um's löschen geht kann man die Daten nach der zu löschenden 
Zeile "auf" die zu löschende Zeile "drüberkopieren". -siehe "ffseek"-

sorry, bischen blöd ausgedrückt

Gruß, Christoph

von Andreas H. (andreas_h16)


Lesenswert?

Hallo,

ich hatte Probleme beim Lesen von Dateien deren Name die Form 
<1234567.123> hat, bzw. eine Dateinamenlänge von 10 (ohne den Punkt) bei 
MMC_LFN_SUPPORT = TRUE.

Ich denke der Fehler liegt hier:
1
//***************************************************************************************************************
2
// prueft auf lange dateinamen (lfn), ermittelt anhand des langen dateinamens den kurzen. nur der kurze
3
// enthaelt die noetigen informationen um die datei lesen zu koennen. ist der gesuchte dateiname gefunden
4
// aber im naechsten sektor/cluster ermittelt die funktion selbstaendig diese und holt die informationen !
5
//***************************************************************************************************************
6
static uint8_t fat_loadFileDataFromCluster(uint32_t sec , uint8_t name [])
7
{
8
9
....
10
    // 2.2) ist eintrag ein sfn eintrag?
11
....
12
    // datei gefunden
13
    if( i == 11 && j != 11) // <---- FALSCH
14
    // ersetzen durch
15
    if( i == 11 && j < 13)
16
....
17
}

Könnte das mal jemand verifizieren ?

Danke,
Andreas

von SurtuR (Gast)


Lesenswert?

hi mich würde interessieren wie man auf einfachen weg, unter benutzung 
dieser lib, ab einer bestimmten stelle aus der datei lesen kann. ist 
soetwas möglich? vielleicht habe ichs auch in diesem sehr langen thread 
überlesen.

mfg,
surtur

von Andreas H. (andreas_h16)


Lesenswert?

Mit ffseek vielleicht, wie üblich (o.k. da heißt es fseek) ?

von SurtuR (Gast)


Lesenswert?

wie in etwa würde ein beispielcode aussehen um bis zu einer gewissen 
position durch zu iterieren, und dann ab position n immer x zeichen zu 
lesen. dann wieder ab position x+n+1 und so weiter. :-) oder muss ich 
jedesmal die position merken und dann wieder von vorn bis zur zu 
lesenden position gehen. und von dort aus lesen? wäre nämlich ein 
ziemlicher overhead.

gruß,
surtur

von SurtuR (Gast)


Lesenswert?

wenn ichs mir genau überlege:

natürlich wäre vom dateiende nach vorn lesen auch eine option.
dann bräuchte ich die gelesenen bytes nur umzudrehen.
und nicht erst von vorn bis zu nem index durchzugehen.

sofern soetwas möglich ist.

gruß,
surtur

von Bernd (Gast)


Lesenswert?

Hallo,

gibt es ne Möglichleit, den freien Speicherplatz der SD zu ermitteln?

Gruß

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.