Gibt es trotz "Baustelle" ein Möglichkeit die ffls Funktion zu nutzen?
Ziel ist es, das Dateien über ein Lcd ausgewählt werden können. Ich habe
die Funktion bereits so abgewandelt, dass ich nur die Dateinamen
erhalte. Allerdings sind diese im 8.3 Format und ffopen akzeptiert dies
anscheinend nicht.
ffopen funktioniert super mit 8.3.
Was genau bekommst du denn als Dateinamen zurück? Hast du mal ein
Beispiel, auch wie du's dann an ffopen weitergibst?
Gruß
Fabian
Das Öffnen funktioniert übrigens, wenn ich einen Dateinamen, der alle 8
Zeichen belegt, übergebe (also wenn keine Leerzeichen im Dateinamen
sind).
Fabian B. schrieb:> Hast du mal ein> Beispiel, auch wie du's dann an ffopen weitergibst?
Kannst du mal das ganze Codesegment posten, bitte? Also von einlesen per
ffls bis öffnen per ffopen. Inkl. Definition relevanter Variablen.
Gruß
Fabian
Die Dateien, die volle 8.3 Zeichen haben, können übrigens nur dank
dieser vorgeschlagenen Änderung gelesen werden:
Beitrag "Re: MMC SD library FAT16 FAT32 read write"
Ich vermute, in der fat_loadFileDataFromCluster ist noch ein weiterer
Fehler drin, der seit Umstellung auf LFN, diese nicht mehr funktionieren
lässt?
Hallo Daniel R.
iste die Aussage noch aktuell, dass die Library nich mehrere Dateien
gleichzeitig öffnen kann?
SDHC Support ist inzwischen drin, habe ich das richt verstanden?
Hallo Daniel,
es ist mir gelungen, die Library erfolgreich in mein web basiertes I/O
Modul einzubinden. Ich habe zwar noch keinen Anwendungsfall für den neu
gewonnenen Speicherplatz, aber das kommt sicher noch.
Ich musste lediglich die SPI Schnittstelle an den ATxmega128D3 anpassen,
aber das war überhaupt kein Problem. Schwieriger fiel mir die Einbindung
in uIP (den Webserver), weil der Multi-Threading fähig ist, die avrfat32
library aber nicht. Aber ich denke, ich habe das nun mit akzeptablen
Beschränkungen hinbekommen:
- Der Webserver listet nur die ersten 1300 Bytes des
Inhaltsverzeichnisses auf. Mehr Dateien will ich sowieso nicht ablegen.
- Beim Datei-Download müssen alle anderen konkurrierenden Web-Anfragen
warten, bis der Download beendet ist oder abgebrochen wurde.
Vielen Dank für die Veröffentlichung der SD/MMC Karten Library. Sie war
mir eine sehr große Hilfe.
Mein Projekt ist hier: http://stefanfrings.de/avr_io/
Hallo Thilo,
hast Du inzwischen eine Lösung des Problems gefunden? Bir mir tritt der
gleiche Fehler auf. Nach Reparatur der Datei bleiben exakt 48k
verfügbar. Setze ich per PC/Editor noch Zeichen an das Ende der Datei -
abspeichern - schreibt mein Gerät die nächsten Datensätze einwandfrei.
Wenn nicht, geht die Datei bei weiterem Beschreiben kaputt.
Offensichtlich passiert das, wenn die Datenbytes genau bis Sektorende
reichen. Ist es nur 1 Byte mehr, wird ordentlich weiter geschrieben.
Thilo M. schrieb:> 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.
Ich habe noch keine Lösung dafür gefunden, aber falls Daniel das mal
testen will hänge ich eine Datei an, bei der dieser Fehler auftritt.
Zusätzlich die mmc_config.
Thilo M. schrieb:> Ich habe noch keine Lösung dafür gefunden, aber falls Daniel das mal> testen will hänge ich eine Datei an, bei der dieser Fehler auftritt.>> Zusätzlich die mmc_config.
Fehler beim zyklischen Zufügen von Messdaten zu einer bestehenden Datei.
Heute habe ich einen entscheidenden Hinweis gefunden. Offensichtlich hat
das etwas mit dem Hersteller und dem Kartentyp zu tun. Eines meiner
Geräte (hatte ich ganz vergessen) läuft seit 35 Tagen mit zyklischem
Abspeichern 15s/je ca.60 Byte unter Verwendung einer billigen SD-Card.
Bei teuren ATP-Industrial-Grade - Karten - 512MB steigt die Geschichte
bei einer Dateigröße von 48 oder 54KB aus - und zwar immer genau bei
einem Sektorwechsel zwischen zwei Speichervorgängen.
Dabei werden Daten in den schon benutzten Datenbereich an falscher
Stelle abgelegt. Es entstehen u.a. neue Dateinamen, die einen Teil der
ASCII-Zeichen aus den abgespeicherten Daten enthalten.
Ich werde mich mal mit den Unterschieden zwischen industriellen und
nichtindustriellen SD-Karten beschäftigen und melde mich wieder.
Wolfgang Sch. schrieb:> Offensichtlich hat> das etwas mit dem Hersteller und dem Kartentyp zu tun.
Das habe ich nun auch festgestellt.
Eine uralte 256MB Kingston Karte zeigt diesen Fehler nicht. Sie schreibt
(bis jetzt) fehlerfrei, hat aber deutlich längere Zugriffszeiten.
Die Motorola Micro-SD (2GB) mit Adapter brach nach 38kB ab (siehe oben
verlinktes File).
Das Zerstören des Files kann man vehindern, indem man bei 10 erfolglosen
Initialisierungs- Lese- oder Schreibversuchen den Versuch abbricht. Dann
sind wenigstens die Daten bis dahin nicht verloren.
Thilo M. schrieb:> Wolfgang Sch. schrieb:>> Offensichtlich hat>> das etwas mit dem Hersteller und dem Kartentyp zu tun.>> Das habe ich nun auch festgestellt.
Hallo Thilo,
ich glaube, ich habe das Problem beseitigen können.
Probiere mal am Ende der Funktion "fat_writeSector"
einige Dummy-Bytes von der SPI zu lesen. Ebenso in "fat_loadSector"
so etwa:
#if (MMC_WRITE==TRUE)
if( fat.bufferDirty == TRUE )
{
fat.bufferDirty = FALSE; // buffer kann nicht dirty sein weil
wird geschrieben
mmc_write_sector( file.currentSectorNr,fat.sector ); //
schreiben von sektor puffer
Takte(); //einige Bytes dummy-Lesen
}
#endif
Offensichtlich brauchen manche Karten an der Stelle noch ein paar Takte.
Das ist erst mal ein vorläufiges Ergebnis, ich teste mal über ein paar
Tage.
Jetzt bin ich bei 200KB geloggte Daten, soweit bin ich bisher noch nie
gekommen.
Hi Wolfgang,
habe getan, was du geraten hast, drei Byte zusaätzlich gelesen, und
siehe da: die Motorola-Karte schreibt auch weiter (alte Datei von oben
im Anhang verwendet)!
Werde die auch mal ein paar Tage laufen lassen.
;-)
Kleine Änderung:
Um ganz korrekt zu sein habe ich das dummy-read jetzt nur noch an einer
Position in "mmc_write_sector" eingefügt. Funktioniert.
..............
if ( retrys == 0)return FALSE; // If not accepted, return with
error
mmc_disable();
spi_read_byte();
spi_read_byte();
spi_read_byte();
spi_read_byte();
spi_read_byte();
spi_read_byte();
return TRUE;
}
.............
In den FALSE - Fällen werden sowieso jede Menge Bytes gelesen - ohne
Schreiben.
Wolfgang Sch. schrieb:> Kleine Änderung:> Um ganz korrekt zu sein habe ich das dummy-read jetzt nur noch an einer> Position in "mmc_write_sector" eingefügt. Funktioniert.> ..............
Kommando zurück! Mit dieser Änderung treten dann doch wieder Fehler auf.
Ich bleibe jetzt bei der Version vom 13.05.
Ich habe seit Jahresanfang eine Sandisk 1GB Micro-SD am Laufen, alle
paar Wochen taucht ein Fehler auf: Schreiben des Files wird abgebrochen,
ab 00:00 Uhr wird ein neues File angelegt (so gewollt) und bei jedem
Schreibvorgang wird ein neues File mit demselben Filenamen angelegt.
Habe auch dort die Änderung eingefügt, weil zufällig heute dieser Fehler
auftrat. Der Logger hat sofort korrekt weitergeschrieben, mal sehen
wie's weitergeht.
Hi Wolfgang,
mit 6 zusätzlich gelesenen Byte (wie du oben beschrieben hast) war bei
einer Motorola 128MB Micro-SD nach 6144 Byte Schluss. Funktioniert also
auch nicht immer.
Thilo M. schrieb:> Hi Wolfgang,>> mit 6 zusätzlich gelesenen Byte (wie du oben beschrieben hast) war bei> einer Motorola 128MB Micro-SD nach 6144 Byte Schluss. Funktioniert also> auch nicht immer.
Bin auf der Suche nach der Ursache. Auf jeden Fall tritt aber kein
Dateisalat mehr auf - oder? Wie äußert sich bei Dir das Problem? Ich
vermute, dass früher geschriebene Sektoren nicht mehr vorhanden sind?
Wolfgang Sch. schrieb:> Auf jeden Fall tritt aber kein> Dateisalat mehr auf - oder?
Nein, das hatte ich vorher schon ausgeschlossen, indem ich 10 Versuche
beim Lesen und Schreiben gemacht habe, bei Fehler bricht er einfach ab.
Ich habe die zusätzlichen Byte (Lesen und Schreiben) wieder entfernt und
habe die Taktrate (clk) auf 500kHz heruntergestellt. Seit vier Tagen
schreibt er jetzt auf der "Problemkarte" fehlerfrei (minütlich ein
Datensatz).
Manche Karten scheinen an gewissen Stellen ein kleines Päuschen zu
benötigen, ist der Takt zu schnell, reicht die Zeit nicht. Wenn ich Zeit
habe, suche ich die Stelle(n), brauche den Logger aber gerade an einer
Solaranlage.
Hallo,
wie provoziert Ihr den Fehler? ich schreibe Teilweise meherere 100 MB
Files auf die Karte und habe bis jetzt noch keine Fehler gehabt.
Schreibe entweder in einem Stück oder mit mehrmaligem öffnen der Datei.
Viele Grüße.
Hi Andre,
die Fehler tauchen bei mir nach mehreren Tagen bis Wochen auf.
Provoziert habe ich die nicht. Beim einen Logger schreibt er auch
mehrere Wochen ohne Fehler (tägliche Textfiles mit ca. 220kB), dann
taucht ein Fehler auf.
Es ist ein Fehler in der ffcdLower() Funktion,
fat_loadRowOfSector(1); ist falsch!!
richtig ist:
fat_loadRowOfSector(0x20);
dann funktioniert auch das cd..
uint8_t ffcdLower(void){
if( fat.dir == 0 )return FALSE; // im root dir, man kann nicht
hoeher !
fat_loadSector(fat_clustToSec(fat.dir)); // laed 1. sektor des
aktuellen direktory.
fat_loadRowOfSector(0x20); // ".." eintrag (parent dir) ist 0
wenn parent == root
fat.dir=file.firstCluster; // dir setzen
return TRUE;
}
Gruß Dietmar
Thilo M. schrieb:
Hallo Thilo,
Du hast recht, der Fehler tritt bei langsamen Takt nicht mehr auf. Ich
habe jetzt probeweise mal Abspeichern von je 512 Byte programmiert,
Abtastzeit 10s.
Nach spätestens 3 Minuten tritt der Fehler auf, wenn Takt > 500KHz.
Ursache ist wohl die interne Speicherplatzverwaltung der SD-Karten, die
sehr viele Speicherzyklen vertragen --> bis zu 10Mio. Praktisch ist der
Flash auch nur einige 1000mal beschreibbar, die interne Organisation der
Karte sorgt aber dafür, dass der Speicher möglichst gleichmäßig
abgenutzt wird.
Diese Umspeicher-Arbeitsschritte macht die Karte allein, ohne äußeres
Zutun.
Wenn man nun wüsste, wann das passiert, hätten wir das Problem gelöst.
Bin weiter am Testen...
Thilo M. schrieb:> Hm...>> der Fehler ist immer noch da, trotz 500kHz Takt.> In angehängter Datei wird einfach nicht weitergeschrieben.
Hallo Thilo,
mir ist nach längerem Test jetzt absolut klar, worin das Problem
besteht.
Immer, wenn genau bis zum Ende eines Sektors oder Clusters geschrieben
wird und die Datei dann geschlossen wird, gehen Daten verloren und/oder
die FAT wird fehlerhaft.
Das kann man simulieren, indem man nicht seine Orginaldaten schreibt,
sondern immer 16 oder 32 oder 64.... Byte. Dann tritt der Fehler exakt
an der gleichen Stelle auf. Kartenart und Hersteller sind egal. Was
weiter oben angenommen wurde, basierte auf Zufall.
Ich habe jetzt erst mal um den Fehler herumprogrammiert:
ffwrites(Messwerteintrag);
if((file_.cntOfBytes &1) ==0) ffwrite(0x20);
- soll heißen, dass vor dem Schreiben von 0dh 0ah geprüft wird, ob die
Dateilänge ungerade oder gerade ist. Im letzteren Fall hänge ich noch
ein Leerzeichen dran.
Seit einigen Tagen läuft es nun ohne Fehler, egal wie schnell, egal
welcher Kartentyp.
Die Funktion
void fflushFileData(void)
enthält noch einen Fehler, wahrscheinlich ist es irgendwie an dieser
Stelle falsch:
// wenn fat.cntOfBytes == 0 ist der sektor gerade vorher schon
geschrieben worden oder es ist noch nichts hinein geschrieben worden.
dann wert so setzten, dass die schleife uebersprungen wird
count = (file_.cntOfBytes==0) ? 512:file_.cntOfBytes;
Eine Abhilfe habe ich noch nicht gefunden, dazu muss man sich tiefer
einarbeiten. Vielleicht kann uns Daniel helfen?
Wolfgang Sch. schrieb:> count = (file_.cntOfBytes==0) ? 512:file_.cntOfBytes;
Man hätte auch schreiben können:
count = (file_.cntOfBytes==0) ? 512:0;
dürfte aber kein Unterschied bei der Funktion sein.
Welcher Fehler taucht denn da auf?
Ist bei dir der Unterstrich nach file (als file_.) überall dran?
Den gibt's bei mir nicht. Evtl. ist das 'ne andere Version?
Ich werde es auch mal testen, gerade Zählerstände zu vermeiden.
Hallo zusammen,
hab leider sehr viel um die Ohren momentan.
Lese aber schon noch mit hier.
Muss mal sehen das ich meine Entwicklungsumgebung für den FAT kram
wieder zusammenbaue. Sollte sich das mit den geraden und speziell mit
den 2er Potenzen bestätigen gehe ich dem auf den Grund.
Viele Grüße
Daniel
Thilo M. schrieb:> Wolfgang Sch. schrieb:>> count = (file_.cntOfBytes==0) ? 512:file_.cntOfBytes;>> Man hätte auch schreiben können:>> count = (file_.cntOfBytes==0) ? 512:0;>> dürfte aber kein Unterschied bei der Funktion sein.> Welcher Fehler taucht denn da auf?>> Ist bei dir der Unterstrich nach file (als file_.) überall dran?> Den gibt's bei mir nicht. Evtl. ist das 'ne andere Version?>> Ich werde es auch mal testen, gerade Zählerstände zu vermeiden.
Hallo Thilo,
das mit den ungeraden Sektorenlängen habe ich vereinfachend gemacht, um
gerade komplett gefüllte Sektoren (512 Byte) zu vermeiden. Alle anderen,
mit einer geraden Anzahl Bytes gefüllter Sektoren werden auch auf
"ungerade" gebracht, das wäre aber eigentlich nicht nötig.
file_ - Unterstrich:
Die Software wurde auf einem Luminary - Prozessor (ARM-CORTEX) zum
Laufen gebracht. Compiler: Keil µVision4.
Bei der Implementierung gab es ein Problem mit der Bezeichnung "file",
daher der Unterstrich.
Zum Problem:
Ich vermute, dass das Problem darin besteht, dass
fat.bufferDirty = TRUE;
gesetzt wird, wenn
count < 512 (while - Schleife)
aber nicht, wenn
count == 512
Ich werde mal noch ein wenig probieren.
Hat eigentlich mal jemand Lust mit den neuen Erkenntnissen ein Paket zu
bauen?
Das letzte Paket zu nehmen und dann alle hier gefundenen Fixes
einzubauen wäre etwas aufwendig.
Vielleicht wäre einer der "Vielverwender" hier dazu bereit?
Gruß
Fabian
Hi Fabian,
ich denke, wenn der Fehler mit den "eben vollen" Sektoren gefunden ist,
wäre es an der Zeit, da hast du Recht.
Mittlerweile ist es, bis auf diesen Fehler, ziemlich wasserdicht.
Lassen wir Daniel noch Zeit, er kennt seinen Code am besten und dürfte
wissen, wo er suchen muss. ;-)
Stimmt.
Bisher habe ich die Lib nur für's lesen genutzt, daher habe ich oben
nach meinem init-Patch nix mehr geupdated. Gerade auch weil's ja
scheinbar immer wieder Schreibprobleme gab.
Wenn das jetzt wirklich eine Lösung ist, wäre alles zusammen in einem
"0.7"-release ne tolle Sache.
Gruß
Fabian
Daniel R. schrieb:> Hallo zusammen,> hab leider sehr viel um die Ohren momentan.> Lese aber schon noch mit hier.>> Muss mal sehen das ich meine Entwicklungsumgebung für den FAT kram> wieder zusammenbaue. Sollte sich das mit den geraden und speziell mit> den 2er Potenzen bestätigen gehe ich dem auf den Grund.>> Viele Grüße>> Daniel
Hallo Daniel,
bin hocherfreut, dass Du noch mal einen Blick darauf wirfst.
Ich konnte aus Platzgründen nicht 512 Byte auf einmal schreiben, deshalb
16 oder 32 ... Byte. Kann man auch anders machen, z.B. 2x250 Byte, dann
12 Byte, ev. auch 1x512 Byte -- habe ich aber nicht probiert.
Fehler auslösen:
Wichtig ist nur, dass der Sektor zum Schluss genau bis Ende gefüllt
wurde.
Bitte für jeden Schreibvorgang
1. Datei öffnen (bzw. neu anlegen)
2. Bytes schreiben
3. Datei schließen
so kann ich bei meinem Gerät den Fehler auslösen.
Viele Grüße,
Wolfgang
Scheinbar liegt das Problem nicht nur an den "eben vollen" Sektoren.
Vor zwei Stunden hat er trotz ugerade gehaltener Filegröße einfach
wieder aufgehört weiterzuschreiben.
Falls es zur Analyse hilft hänge ich da geloggte File mal dran.
Edit:
nachdem ich versucht habe, ein Byte anzuhängen, hat Windows das File als
schreibgeschützt erkannt und es ließ sich nicht mehr abspeichern.
Scheinbar liegt das Problem in der FAT, nicht an der Datei an sich.
Irgendwo macht die Software falsche Einträge, warum auch immer.
Ich hatte auch schon den Fall, das der selbe Dateiname 25x vorkam, sich
aber nur auf eine Datei bezog.
Edit 2:
Karte ist defekt. Lässt sich weder formatieren, noch beschreiben.
Windows erkennt den Datenträger als schreibgeschützt, egal wie der
Schiebeschalter steht.
Wäre natürlich ein dummer Zufall, wenn das Stück ausgerechnet jetzt
gestorben wäre.
Thilo M. schrieb:> Edit 2:>> Karte ist defekt. Lässt sich weder formatieren, noch beschreiben.> Windows erkennt den Datenträger als schreibgeschützt, egal wie der> Schiebeschalter steht.>> Wäre natürlich ein dummer Zufall, wenn das Stück ausgerechnet jetzt> gestorben wäre.
Hallo Thilo,
bei mir laufen 2 Datenlogger seit 2 Wochen mit 10s Speicherabstand im
"ungerade" - Modus fehlerfrei. Jedes Mal werden ca. 60 Byte abgelegt.
Gruß, Wolfgang
Hallo,
wie macht sich das bei Euch bemerkbar. Hängt er sich bei Euch auf? Wenn
ja, in welcher Funktion genau? Ich habe zurzeit das Problem, dass er
sich kurz nach Start des Logvorgangs aufhängt.
Gruß
André
Wolfgang Sch. schrieb:> bei mir laufen 2 Datenlogger seit 2 Wochen mit 10s Speicherabstand im> "ungerade" - Modus fehlerfrei.
Bei mir jetzt auch.
Ich hatte den Takt des SPI versehenlich auf 8MBit gelassen, was für das
DOGm Display kein Problem ist. Nur die alte SD-Karte konnte das nicht
und hat sich verabschiedet. Die neue PLATINUM 1GB ist für max. 5MBit
Schreiben spezifiziert und hat mit gelegentlichen Schreibfehlern
reagiert (Resekt!).
Nun läuft das Ganze mit 1MBit seit Tagen fehlerfrei.
Ich denke, wenn der "Eben-Voll-Fehler" gefunden ist, dann ist das Ganze
ziemlich wasserdicht.
> Nun läuft das Ganze mit 1MBit seit Tagen fehlerfrei.> Ich denke, wenn der "Eben-Voll-Fehler" gefunden ist, dann ist das Ganze> ziemlich wasserdicht.
Gratuliere.
Beitrag "MMC/SD-Karte mit FAT16 an AVR"
läuft bei mir ~5 Jahren 24/7. Steuert nebenbei ne FB und hat nen
Webserver. Fehlerfrei.
SCNR
Torsten S. schrieb:> läuft bei mir ~5 Jahren 24/7. Steuert nebenbei ne FB und hat nen> Webserver. Fehlerfrei.
Ja, bei mir läuft der Heizungsregler seit 2008 auch prima (8x PT1000,
DCF77/RTC, 6 Ausgänge, Dreipunkt-Schrittregler, State-Machine, VBus
(RESOL) einbindung, DOGm-Display), die SD-Karte kam dazu und dürfte
jetzt serienreif sein.
Webserver habe ich auch zwei am Laufen, machen keine Probleme mit
SD-Karte seit 1.1.12.
Hallo Daniel,
mich würde mal interessieren ob es hier schon irgendwelche Fortschritte
in Bezug auf den Bug mit der Clusterlänge gibt, ich würde die lib gern
auf einem atmega128 einsetzen welche Version ist denn da angebracht ? Im
SVN gibt es die 0.6.1 die hatte ich mir jetzt erstmal runtergeladen und
damit mal ein paar erste Tests gemacht, das funktionierte soweit. Sollte
ich besser die 0.6.4 verwenden ? Ich habe mal den Thead quergelesen - so
ganz schlau werde ich daraus eigentlich nicht welche Version nun noch
bekannte Bugs enthält.
@Wolfgang Sch.: Was genau hast Du denn geändert ?
A.H. schrieb:> Hallo Daniel,>> mich würde mal interessieren ob es hier schon irgendwelche Fortschritte> in Bezug auf den Bug mit der Clusterlänge gibt, ich würde die lib gern> auf einem atmega128 einsetzen welche Version ist denn da angebracht ? Im> SVN gibt es die 0.6.1 die hatte ich mir jetzt erstmal runtergeladen und> damit mal ein paar erste Tests gemacht, das funktionierte soweit. Sollte> ich besser die 0.6.4 verwenden ? Ich habe mal den Thead quergelesen - so> ganz schlau werde ich daraus eigentlich nicht welche Version nun noch> bekannte Bugs enthält.>> @Wolfgang Sch.: Was genau hast Du denn geändert ?
Hallo A.H.
das funktioniert, weil zusätzliche Leerzeichen in der Ausgabedatei nicht
stören:
ffwrites(Messwerteintrag); //aus Puffer "Messwerteintrag"
Dateilaenge=file_.cntOfBytes;
if((Dateilaenge &1) ==0) ffwrite(0x20);
ffwrite(0xd);
ffwrite(0xa);
In einem Projekt, bei dem eine SD-Karte als Datenspeicher (FAT16 mit
SFN) werwendet wird, ist mir unangenehm aufgefallen, dass beim Löschen
einer Datei immer eine weitere Datei mitgelöscht wird. Mit einem
Diskeditor habe ich festgestellt, dass zwar der erste Buchstabe beider
Dateinamen durch 0xE5 ersetzt wird, die zur zusätzlich gelöschen Datei
gehörenden Cluster werden in der FAT aber nicht als "frei" markiert und
bleiben belegt.
Auf der Suche nach dem Grund habe ich folgende Codestelle in "file.c" ab
Zeile 484 entdeckt:
1
//////// ob ordner oder datei, der sfn und lfn muss geloescht werden!
2
fat.bufferDirty=TRUE;// damit beim laden der geaenderte puffer geschrieben wird
3
do{
4
fat.sector[row]=0xE5;
5
if(row==0){// eintraege gehen im vorherigen sektor weiter
6
fat_loadSector(fat.lastSector);// der davor ist noch bekannt. selbst wenn der aus dem cluster davor stammt.
7
fat.bufferDirty=TRUE;
8
row=512;// da nochmal row-=32 gemacht wird, kommt man so auf den anfang der letzten zeile
9
}
10
row-=32;
11
}while(fat.sector[row+11]==0x0f&&(fat.sector[row]&0x40)!=0x40);// geht durch alle reihen bis neuer eintrag erkannt wird...
12
13
fat.sector[row]=0xE5;
Die do..while-Schleife ist doch eigentlich nur für LFN gedacht, oder?
Wäre es nicht richtiger, die Schleife "andersherum" zu schreiben, also
so:
1
//////// ob ordner oder datei, der sfn und lfn muss geloescht werden!
2
fat.bufferDirty=TRUE;// damit beim laden der geaenderte puffer geschrieben wird
3
while(fat.sector[row+11]==0x0f&&(fat.sector[row]&0x40)!=0x40)// geht durch alle reihen bis neuer eintrag erkannt wird...
4
{
5
fat.sector[row]=0xE5;
6
if(row==0){// eintraege gehen im vorherigen sektor weiter
7
fat_loadSector(fat.lastSector);// der davor ist noch bekannt. selbst wenn der aus dem cluster davor stammt.
8
fat.bufferDirty=TRUE;
9
row=512;// da nochmal row-=32 gemacht wird, kommt man so auf den anfang der letzten zeile
10
}
11
row-=32;
12
}
13
14
fat.sector[row]=0xE5;
Dann kommt man überhaupt nicht in die Schleife, falls man keinen LFN
hat. Ist meine Überlegung richtig?
@Wolfgang Sch. Danke ich habe das bei mir als bugfix erstmal auch so
eingebaut.
Mir ist beim testen ein Fehler aufgefallen der in die gleiche Richtung
zu gehen scheint. Wenn ich am PC eine Datei auf die Speicherkarte
kopiere z.B. NAME.TXT und der µC soll dann auf die gleiche Speicherkarte
in die gleiche Datei schreiben gibt es die Daten anschließend zwei mal
mit identischem Namen und Inhalt aber unterschiedlicher Größe auf der
Karte.
Wenn ich mit der Datenträgerüberprüfung von XP auf die Karte gehe wird
putzigerweise kein Fehler gefunden, Windows gibt beim löschen der beiden
Dateien einen Fehler aus (Datei nicht gefunden) anschließend sind beide
Dateien weg.
Eine mit Windows auf die Karte kopierte Datei kann ich mir ffrm nicht
löschen.
Ist das zwischen 0.6.1 und 0.6.4 schon gefixt worden ?
Hallo alle zusammen.
Ich hab grade die library runtergeladen und an meiner Hard getestet.
Scheit so weit alles zu funktionieren (riesen dank an Daniel!!!!!) ABER:
ich hab da noch n Nokia 6100 LCD, dass ueber das selbe SPI geht. Wenn
man nun zuerst die SD-karte initialisiert usw. und ne Datei liest, bevor
man etwas mit dem LCD macht, dann klappt's. Wenn man nun nach dem start
der LCD was macht, dann kommt das Programm einfach nicht weiter. Also
wie
if( MMC_FILE_OPENED != ffopen("TXT1.TXT",'r') )
{ mach etwas
}
else mach etwas anderes
macht weder etwas noch was anderes. Scheint so, als ob der CS-pin nicht
richtig tickt....
'Ne Idee was man da macht?
ja sicher doch!
momentan hab ich noch ein Software-SPI hinzugefügt, so dass der LCD da
drüber läuft. Wenn man solche unabhängige ports benutzt, ist alles OK.
man kann dateien öffnen, lesen usw. ich hab ne ATMega 64, also viele
pins, und es wäre nicht weiter kritisch, wenn ich den Software-spi
lasse, wäre aber trotz dem nicht schlecht rauszufinden, was da los ist.
leider bleiben die daten auf der karte drauf. warum auch immer. In der
Datei sind die weg, aber ich bekomme fehler wenn ich zeile 2 und 4
auslese.
Gruss
Milan
Ich tippe mal darauf, wie man es beim PC programmieren auch macht:
Man legt sich eine temporäre datei an. Schreibt da alle Zeilen rein, die
man behalten will und löscht das die orginal Datei und benennt die
temporäre Datei um, so dass sie so heißt wie die orginal Datei.
Probier das doch mal.
Grüße
Hallo Matze,
danke für den Tipp, daran habe ich auch gedacht.
Problem ist, dass die Datei bis 50MB oder mehr gross sein kann. Also 1
zu 1 kopieren geht nicht. Und so viel ich weiss kann ich nur eine Datei
aufmachen und bearbeiten.
Gruss
Milan
Jo, das stimmt. Du müsstest auslesen, bis dein Speicher voll ist und
dann dein Speicherinhalt in die temporäre Datei schreiben. Anderes ist
leider nicht möglich - so weit ich weiß.
Einfach löschen einer Zeile ist aber auch aus Gründen der Datenstruktur
nicht möglich. Beschäftige dich doch mal damit, wie eine Datei
eigentlich auf dem Datenträger aussieht. Als Ansatz: leg dir eine Datei
mit einem kurzen, definierten Inhalt an und öffne die SD- Karte dann mit
einem HEX- Editor. Suche dann mit dem HEX- Editor nach deiner
Zeichenfolge als HEX- Werte. Das kannst du auch an deinem PC machen,
musst nicht extra den µC verwenden.
Wenn du verstanden hast, wie Dateien auf der SD- Karte aussehen, weißt
du auch, daß ein anderer Weg als mit der temp. Datei echt umständlich zu
realisieren ist (bis hin zur völligen Unumsetzbarkeit)
Klar, überschreiben geht. Du musst bloß die Textstelle haben (ffseek ist
dein Freund)
Aber zu dieser Bibliothek: geplant war das mal als Datenlogger... ;)
Was hast du eigentlich genau vor und wielange brauchst du um 50MB Daten
zu schreiben?
Hallo,
wäre sehr nett, wenn mir jemand helfen könnte. Versuche nun seit ein
paar Wochen schon die Bibliothek zum laufen zu bekommen.
Verwendet einen Atmega644P und dieses Modul von Conrad als Pegelwandler
http://www.conrad.de/ce/de/product/197220/ um Hardwarefehler zu
vermeiden.
Für den 10ms Timer (TimingDelay) verwende ich Timer 1.
Dieser zählt bis 16000 bei einem 16MHz Takt und löst somit jede ms ein
Interrupt aus. Wurde im Interrupt bis 10 gezählt, so werden 10 ms
abgezogen. Das ganze funktioniert und wurde bereits getestet.
1
volatileuint8_tTimingDelay;// fuer mmc.c
2
volatileuint8_tMillisekunden_SD=0;
3
4
ISR(TIMER1_COMPA_vect)//Taktgeber 1ms
5
{
6
Millisekunden_SD++;
7
if(Millisekunden_SD==10)
8
{
9
TimingDelay=(TimingDelay==0)?0:TimingDelay-1;
10
//TimingDelay wird so lange heruntergezählt, bis TimingDelay == 0 ist.
11
Millisekunden_SD=0;
12
}
13
}
In mmc_config.h wurden folgende Änderungen vorgenommen:
1
#define MMC_MAX_SPEED FALSE
In mmc.h wurde folgende Änderung gemacht:
1
#define __AVR_ATmega644__
Verwendet wird das Hardware SPI
In der Hauptdatei wird folgender code ausgeführt:
1
if(TRUE==mmc_init())
2
{
3
Display_write_OK();
4
}
5
else
6
{
7
Display_write_Fehler();
8
}
9
10
11
if(TRUE==fat_loadFatData())
12
{
13
Display_write_OK();
14
}
15
else
16
{
17
Display_write_Fehler();
18
}
Die Initiallisierung funktioniert. Die Funktion fat_loadFatData()
liefert hingegeben ein FALSE zurück. Konkret liefert die Funktion
mmc_read_sector() in der Funktion fat_loadFatData() ein FALSE zurück.
1
TimingDelay=20;
2
do{// Wait for data packet in timeout of 200ms
3
token=spi_read_byte();
4
}while((token==0xFF)&&TimingDelay);
5
6
if(token!=0xFE){
7
returnFALSE;// If not valid data token, retutn with error
8
}
9
//token ist ungleich 0xFE
Jemand eine Idee, woran das liegen könnte?
Die Karte ist FAT32 Formatiert mit einer Blockgröße von 512 Byte. Es
handelt sich um eine 1 GB PLATINUM SD Karte.
Hallo,
ich versuche auch die Sachen zum Laufen zu bekommen.
Ich verwende folgenden Code:
while (mmc_init() !=0) // rückgabewert 0 dann ist karte
initialisiert
{
LCD_displayStringLn(Line1,20, "Initializing card faild!");
while(1)
{
nop();
}
}
if(0==fat_loadFatData()) // rückgabewert 0 dann sind die fat
daten bekannt
{
LCD_displayStringLn(Line1,20, "Karte ready...");
// rückgabewert 2 bedeutet, datei ist nicht vorhanden und wurde
grade angelegt.
//bereit zum schreiben !
if(2==ffopen(file_name))
{
LCD_displayStringLn(Line2,20, "Datei wurde angelegt!");
ffwrites((unsigned char*)"Hallo Welt");
ffclose();
}
// hier ist rückgabewerte eigentlich 1, datei ist vorhanden und
wurde geöffnet.
//bereit zum lesen !
else
{
unsigned long int seek = 0;
unsigned int temp = 0;
LCD_displayStringLn(Line2,20, "Datei bereits vorhanden!");
seek=file.length;
ffseek(2);
temp = ffread();
LCD_drawUint16(Line7,100,temp);
LCD_drawUint16(Line8,100,seek);
ffclose();
}
}
Datei anlegen funktioniert suoer. Ich will aus der Datei genau das "a"
auslesen. Aber ich komme nicht so richtig klar mit dem ffseek(). Wie
kann ich in der Datei an diese Stelle springen und genau den Buchstaben
auslesen?
Grüße, Jens
durch das file.cntOfBytes=0 fängt es immer vom 0 an. zu lesen.
Es passiert weil ich funktion in funktion gemacht habe. Und dann fängt
es da wo es bei der erster funktion aufgehört hat!
Gruss
Milan
Michael P. schrieb:> Moin,>> die meiste Arbeit haben die Routinen für das Lesen und Schreiben der> SD-Karte gemacht (wegen neu schreiben und so). Bei den FAT- und> Dateifunktionen habe ich erstmal nur die Void-Pointer (die ICC430> Version die ich nutze kann damit nicht um), die ganzen Zählvariablen> angepasst und natürlich die Funktionsaufrufe der Low-Level-Routinen> geändert. Eben um zu sehen ob es funktioniert. Und es funtkioniert.>> Weitere Anpassungen sind sicherlich noch möglich, mach ich irgendwann> auch noch.>> Michael
Ich hänge gerade auch noch daran, die Lib für MSP430 zu portieren. Magst
du vlt. schreiben, was genau du jetzt angepasst hast? Bisher habe ich
sämtliche SPI-Routinen angepasst sowie die zugehörigen Makros wie
MMC_CS_LOW, MMC_READ etc.
Wo ich Probleme mit dem Compiler bekomme, sind die Arithmetiken auf
void-Pointer wie bei "void *vsector;". Das kommt zum Glück nur zweimal
vor. Generell ist das dekr/inkr von void Pointern auch nicht
standardkonform (weder C, noch C++). Siehe dazu mein Thema hier:
http://www.c-plusplus.de/forum/p2249560#2249560
Frage an Michael P.: Wie hast du das angepasst? Frage allgemein: Sollte
man das in der Bibliothek nicht generell korrigieren?
Falls es die Hilfsbereitschaft vergrößert:
------------------------------------------
Ich bin bereit, den Quelltext meiner Portierung wenn sie läuft zur
Verfügung zu stellen. Generell wäre ich dann dafür, dass man z.B.
sämtliche SPI-Funktionen aus der mmc.h auslagert und eine spi.h o.ä. als
wirkliche Schnittstelle einführt. Entsprechend der Plattform müssten
dann nur Makros in der spi.h angepasst und die Methoden in einer
spi.c(pp) ausgeprägt werden.
hallo,
die lib vom daniel funktioniert sehr gut.
schade das ich wohl zu dumm bin einen string ins unit8_t file_name[]; zu
bekommen um den Datei Namen in der laufzeit zu generieren.
mit char file_name[10] ginge es, aber die ffopen funktion erwartet ein
uint8_t. wie macht man das wenn man nicht so en dummkopp is?
1
uint8_tfile_name[10];
2
charzahl_str[3];
3
4
// Dateinamen z.B. "Jan12.csv" aus aktuellem Datum zusammensetzen
beides war falsch.
jetz geht es aber endlich mit itoa und strcat;
das habe ich geändert:
ffopen((uint8_t*)file_name,'r')
ffwrites((uint8_t*)log_daten)
so setze ich den string file_name zusammen;
Hallo Leute,
ich möchte gerne diese Bibliothek, welche bisher einen sehr guten
Eindruck macht, für eine Art Datenlogger benutzen. D.h. es müssen
lediglich Daten an das Ende einer Datei geschrieben werden können.
Jedoch habe ich dafür nur einen Atmega16 zur Verfügung und das Hex-File
ist bei mir jedoch 17,8 KB groß. Es passt als nicht auf den Atmega16.
Dabei habe ich schon die Compiler-Optimierung auf möglichst geringe
Speichergröße gestellt und in den Config-Files nur das nötigste an
Funktionalität aktiviert. Den bisherigen Code zum Testen findet ihr im
Anhang.
Hat jemand von euch vielleicht noch eine Idee wie sich der Code
verkleinern lässt, denn eigentlich fehlt ja auch noch der Teil der die
Daten "erzeugt", welche dann auf der SD-Karte gespeichert werden sollen.
Oder ist es überhaupt möglich diese Bibliothek auf einem Atmega16 zu
verwenden?
Vielen Dank für eure Hilfe.
hm.. ohne mir deinen Quelltext angeschaut zu haben: warum nimmst du nich
einen größeren ATmega? Der ATmega32 und 64 sind doch pin-gleich, wenn
ich mich richtig entsinne...
Dann haste auch auf jeden Fall genug Platz für deine Anwendung.
Grüße,
Matze
Hi,
ich habe ein sehr seltsames Phänomen mit der lib.
Bei meinem Projekt funktioniert das Schreiben auf die Karte oft so wie
es soll. Also vom Prinzip her geht es (Das Grundgerüst von dem Projekt
besteht aus einem Vorgänger Projekt, dass seit einem Jahr nun schon
einwandfrei funktioniert). Wenn ich aber meinen Code verändere schreibt
die lib offensichtlich nicht mehr auf die Karte. Es entsteht einfach
eine leere Datei. Wenn man sich die Karte mit einem Hex Editor anschaut,
sieht man, dass der letzte geschrieben String sich auf der Karte
befindet, sonst nichts. Er überschreibt also die Daten auf der Karte
ständig.
Die lib setzt also nach dem schreiben des Strings aus irgend einem Grund
die Position innerhalb der Datei wieder auf den Ursprungswert. So werden
vorhandene Dateien nicht vergrößert und neue sind leer.
Wenn ich dann aber wieder die Änderung im Code beseitige, geht es
wieder.
Das komische ist aber, dass diese Änderungen nicht mit der lib zu tun
haben, sprich z.b. wenn ich eine bestimmte if-Abfrage entferne oder
sowas in der Art. Auf alle Fälle sind die Änderungen eindeutig und haben
definitif nichts mit der lib zu tun. Ich hatte ja auch schon meine
memcpy in Verdacht, aber selbst wenn ich die rausnehme geht es nicht
immer. Also ich gehe davon aus, dass ich nicht ausversehen eine Variable
der lib mit 0 überschreibe. Aber ich finde nun auch schon seit Tagen
nicht die Lösung von meinem Problem.
Hatte jemand von Euch so was auch schon mal?
Woran könnte es liegen?
Ich weiß nicht, ob mein Fehler wirklich weg ist, aber ich habe auf alle
Fälle doch noch einen Fehler gefunden: Der Timer war nicht auf 10 ms,
sondern auf 20 ms eingestellt (die Rache des übernommenen Grundgerüsts,
das lauft nämlich mit 16, statt jetzt mit 8 Mhz). Auf alle Fälle läuft
die Software im Moment so wie sie soll.
Kann es wirklich am Timer gelegen haben?
Hallo wie kann ich mehrere Dateien auf der SD Karte anlegen und
beschreiben?
In eine kann ich erfolgreich schreiben, diese wird anschließend
geschlossen. Auch öffnen, anhängen und schließen lässt sich
reproduzieren. Sowie ich jedoch in eine zweite Datei anlegen/beschreiben
möchte, wird diese angelegt, aber nichts wird hineingeschrieben? Was
kann ich da tun? Sie sind in keinem Fall beide gleichzeitig geöffnet.
Gruß,
Ralf
rs232_text("\nDatei konnte nicht gefunden werden");
81
WDH3224_TEXT(150,1,"Datei konnte nicht gefunden werden",1,0);
82
}
nun, das ganze hatte ich auf meinem Testboard (AT90USB1287)ausprobiert
und es lief. Jetzt habe ich es auf das Aktuelle Projekt übertragen
ATMega1284, das SD-Card Modul ist das gleiche geblieben. Nun lauft das
programm allerdings nur noch bis zu dem Punkt, wo ich "Boot...OK" lesen
kann. Danach passiert leider nichts mehr. Das einzige was noch anders
ist, ist die SD-Card und als ich das mal durchgemessen habe, das CS low
ist.
LG Chris
Hallo Leute,
es läuft jetzt fast alles.
Habe jetzt das Problem, das ich die zu lesende datei nicht komplett auf
ein Array im Controller packen kann, da dazu der Speicher fehlt.
Kann ich irgendwie mit ffseek() an eine Bestimmte Stelle in der Datei
Springen in abhängigkeit der gefundenen Absätze in der Datei am ende ist
ja immer ein 0x0D für </r>. Habe daas mit ffseek bisher so verstanden,
das man die Speicherstelle expliziet vorgeben muss...
Bsp. was ich meine.
Ich will aus Zeile 5 ETWAS LESEN, ALSO MÜSSTE 4X 0X0D ERKANNT WERDEN UND
AB DER NÄCHSTEN STELLE MÜSSTEN ALLE CHARS GELESEN WERDEN BIS WIEDER 0x0D
kommt!? Geht das ?
LG Chris
Hallo,
SurtuR schrieb:> hat keiner ne idee oder antwort für mich auf meine frage weiter oben:
Ich habe es mit zwei verschiedenen Versionen getestet. Beide
funktionieren nach dem beigelegten Code einwandfrei. Also- zwei
geöffnete Dateien einmal beschreiben und beim Zweiten öffnen etwas
anhängen.
Einmal auf Atxmega Ebene und einmal auf LPCXpresso-LPC1769 Ebene.
Code stammt aus LPC1769 Version. Ist aber kompatible mit dem Original
(AVR).
Gruß G.G.
vielen dank g.g. für die antwort.
hmm vielleicht sollte ich es noch einmal mit der neusten version der lib
probieren. ich benutzte bisher immer eine version vor der 0.6.4 (ich
glaub es war die mmc-0.6.zip. vielleicht liegt da der fehler. vielleicht
liegts auch am gering dimensionierten ram des atmega168. mal schauen.
gruß,
ralf
leider hat das ummodeln auf version 0.6.4 nichts gebracht.
ich stehe immer noch vor dem problem, das in die zweite datei nichts
geschrieben wird nachdem sie angelegt wurde.
// entsprechender Bereich mit version < 0.6.4
// Auszug Begin
else if (puffer[3]='U')
{
if ((puffer[4]=='S') && (puffer[5]=='1'))
{
sram_ledred=puffer[7];
sram_ledyello=puffer[9];
sram_ledgreen=puffer[11];
sram_var1=puffer[13];
eeprom_write_byte(&cntlogsd,sram_cntlogsd+1);
eeprom_write_byte(&ledred,sram_ledred);
eeprom_write_byte(&ledyello,sram_ledyello);
eeprom_write_byte(&ledgreen,sram_ledgreen);
eeprom_write_byte(&var1,sram_var1);
sum=0;
for (i=0;i<sizeof(puffer);i++){puffer[i]=0;}
pufflauf=0;
updateleds();
uputc(0x06);
}
else if (puffer[4]=='F')
{
// wenn ESC U F data -> speichere data auf
SD-Karte
if(MMC_FILE_EXISTS == ffopen(uptdatei))
{
ffseek(file.length);
uint8_t z;
for (z=5;z<13;z++)
{
ffwrite(puffer[z]);
}
ffclose();
for (i=0;i<sizeof(puffer);i++){puffer[i]=0;} pufflauf=0;
sum=0;
}
uputc(0x06);
}
}
// Auszug Ende
// Entsprechender Bereich mit Version 0.6.4
// Auszug Begin
else if (puffer[3]='U')
{
if ((puffer[4]=='S') && (puffer[5]=='1'))
{
sram_ledred=puffer[7];
sram_ledyello=puffer[9];
sram_ledgreen=puffer[11];
sram_var1=puffer[13];
eeprom_write_byte(&cntlogsd,sram_cntlogsd+1);
eeprom_write_byte(&ledred,sram_ledred);
eeprom_write_byte(&ledyello,sram_ledyello);
eeprom_write_byte(&ledgreen,sram_ledgreen);
eeprom_write_byte(&var1,sram_var1);
sum=0;
for (i=0;i<sizeof(puffer);i++){puffer[i]=0;}
pufflauf=0;
updateleds();
uputc(0x06);
}
else if (puffer[4]=='F')
{
// wenn ESC U F data -> speichere data auf
SD-Karte
if(MMC_FILE_ERROR == ffopen(uptdatei,'r'))
{
ffopen(uptdatei,'c');
ffclose();
}
if(MMC_FILE_OPENED== ffopen(uptdatei,'r'))
{
ffseek(file.length);
uint8_t z;
for (z=5;z<13;z++)
{
ffwrite(puffer[z]);
}
ffclose();
for (i=0;i<sizeof(puffer);i++){puffer[i]=0;} pufflauf=0;
sum=0;
}
uputc(0x06);
}
}
// Auszug Ende
also irgendwie is da doch noch n bug drin vermute ich.
ich zeichne werte auf, schon ne ganze weile -alle paar minuten. für
jeden monat wird ne extra datei angelgegt.
sobald die aktuelle zu beschreibende datei aber 76kB gross ist, lässt
sich die karte nicht mehr beschreiben. sie lässt sich zwar
initialisieren, aber sobald ein schreibvorgang gestartet wurde, wechselt
die meldung von "init-ok" auf "init-felher".
es läuft lange gut, aber warum ist nach 76kB schluß?
kann das jemand bestätigen?
am code sollte es nicht liegen, so ein seltsamer fehler...
blödkopp schrieb:> sobald die aktuelle zu beschreibende datei aber 76kB gross ist, lässt> sich die karte nicht mehr beschreiben.
Was für ein Nickname! :-)
Du hast vermutlich das Problem mit den "eben vollen" Sektoren.
Lies mal die Dateigröße aus und teile sie durch 512. Wenn's ohne
Nachkommaanteil aufgeht, dann siehe
Beitrag "MMC SD library FAT16 FAT32 read write"
dort wurde gezeigt, wie das Thema umgangen werden kann.
Und achte auf die max. Schreibgeschwindigkeit die deine Karte kann!
Ich bin da auch schon 'reingefallen.
Hallo Leute,
habe gerade das Problem, dass meine Datei nicht mehr gefunden wird.
1
if(MMC_FILE_EXISTS==ffopen("TEST000.TXT"))
2
{
3
WDH3224_CLEAR();
4
WDH3224_TEXT(3,0,"Datei wird geoeffnet",2,0);
5
6
rs232_text("\nDatei wird geoeffnet:\n");
7
8
9
// Phase 1
10
for(i=0;i<ZeilenNr-1;i++)
11
{
12
while(ffread()!='\n');
13
}
14
15
// Phase 2
16
n=0;
17
while((get_c=ffread())!='\n')
18
sd_card_string[n++]=get_c;
19
sd_card_string[n]='\0';
20
21
WDH3224_TEXT(20,0,sd_card_string,1,0);
22
rs232_text(sd_card_string);
23
rs232_text("\n");
24
rs232_text("\nEOF\n");
25
ffclose();
26
27
28
}
29
30
else
31
{
32
rs232_text("\nDatei konnte nicht gefunden werden");
33
WDH3224_TEXT(150,2," Datei konnte nicht gefunden werden ",1,1);
34
}
das init der Karte wird mit OK bestätigt und beim öffnen, springt er
gleich in die ELSE Anweisung. Habe jetzt schon zich mal den Dateinamen
gewechselt immer auf das Format 8.3 geachtet, die Karte Formatiert und
acuh mal mehrere Dateien gleichzeitig drauf gepackt zum testen, aber er
will nie eine davon öffnen. Hatte das schon jemand? oder kann mir vlt.
sagen was da falsch laufen könnte?
Thilo M. schrieb:> blödkopp schrieb:>> sobald die aktuelle zu beschreibende datei aber 76kB gross ist, lässt>> sich die karte nicht mehr beschreiben.>> Du hast vermutlich das Problem mit den "eben vollen" Sektoren.> Lies mal die Dateigröße aus und teile sie durch 512. Wenn's ohne> Nachkommaanteil aufgeht, dann siehe> Beitrag "Re: MMC SD library FAT16 FAT32 read write"> dort wurde gezeigt, wie das Thema umgangen werden kann.>> Und achte auf die max. Schreibgeschwindigkeit die deine Karte kann!> Ich bin da auch schon 'reingefallen.
also rechne ich
Ich meinte, wenn du das Eigenschaften-Fenster der Datei aufmachst, der
Wert hinter "Größe" (nicht Größe auf Datenträger, die lässt sich immer
durch 512 teilen).
Hallo,
vielen Dank zunächst mal für diesen tollen Thread.
Ich versuche gerade, die Bibliothek für ein Projekt mit einem ATMEGA128
zu verwenden. Klappt eigentlich beinahe alles auf Anhieb, ABER....
Beim Erzeugen eines Directories wird dieses auch angelegt, was jedoch
verdächtig lange dauert. Ca. 1-2 Sekunden @8MHz. Das muss eigentlich in
einigen ms erledigt sein. Wenn dann in dieses Verzeichnis gewechselt
werden soll, klappt dies nicht. Das Erzeugen einer neuen Datei findet
trotzdem im Hauptverzeichnis statt.
Wird die SD-Karte dann unter Windows gelesen, kann nicht in das
Verzeichnis gewechselt werden, obwohl es angezeigt wird. Es sei
angeblich nicht verfügbar.
Das Berechnen mit fat_getfree dauert ebenfalls sehr, sehr lang. Da
kommen schon einige Sekunden zusammen. Der errechnete freie
Speicherplatz scheint aber zu stimmen.
Ich verwende die die Version 0.6.4, AVR Studio 4.18, WinAVR-20100110.
Getestet habe ich mit einer 32MB, einer 2 GB und einer 16 GB Karte.
Verhalten ist bei allen identisch. MAX_SPEED wurde auch schon getestet.
Hat jemand noch eine Idee, woran es liegen könnte?
Das Schreiben klappt mit voller Geschwindigkeit ohne jedes Problem.
Einen Hardwarefehler kann ich eigentlich ausschliessen.
Vielen
Dank
Da ich die Bibliothek fix brauchte und ich keine Lust auf lange
Diskussionen hier hatte, hab ich die mal debuggt. (allerdings nur für
sfn und FAT 16) - ich hoffe, dass ich den Rest nicht allzu sehr kaputt
gemacht habe.
"wichtigste Bugs":
- bei cdLower wurden die zeilen nicht richtig übergeben
- beim Löschen gabs auch ernsthafte Probleme
- bei mkdir muss der Verzeichnisname exakt 11 Zeichen lang sein (auch
Leerzeichen)
Ich hänge den code mal an, vielleicht interressiert sich jemand dafür
(ich übernehme aber keinen Support und keine Haftung)
Chris schrieb:> Hallo Leute,> habe gerade das Problem, dass meine Datei nicht mehr gefunden wird.> das init der Karte wird mit OK bestätigt und beim öffnen, springt er> gleich in die ELSE Anweisung. Habe jetzt schon zich mal den Dateinamen> gewechselt immer auf das Format 8.3 geachtet, die Karte Formatiert und> acuh mal mehrere Dateien gleichzeitig drauf gepackt zum testen, aber er> will nie eine davon öffnen. Hatte das schon jemand? oder kann mir vlt.> sagen was da falsch laufen könnte?
Hallo zusammen ich habe das gleiche Problem.
kann jemand bitte helfen. ich komme nicht weiter.
Gruss
Milan
Daniel R. schrieb:> Hallo zusammen,> hab leider sehr viel um die Ohren momentan.> Lese aber schon noch mit hier.>> Muss mal sehen das ich meine Entwicklungsumgebung für den FAT kram> wieder zusammenbaue. Sollte sich das mit den geraden und speziell mit> den 2er Potenzen bestätigen gehe ich dem auf den Grund.>> Viele Grüße>> Daniel
hallo,
nach tagen oder wochen geht aufeinmal nix mehr obwohl bis dahin sauber
messdaten auf MMC gespeichert wurden. das ist echt ärgerlich, hatte ich
das thema mmc doch schon abgehackt.
hab jetzt mittlerweile mehrere mmc teiber durchprobiert und finde es
echt schade das gerade dieser anfängerfreundliche leicht zu
integrierende treiber hier noch bugs drin hat denn der is eigentlich der
beste.
gruß
fauli schrieb:> nach tagen oder wochen geht aufeinmal nix mehr obwohl bis dahin sauber> messdaten auf MMC gespeichert wurden
Hi fauli,
das Problem habe ich auch, nach vielen Monaten einwandfreiem Betrieb
schreibt der Logger auf einmal nix mehr.
Ich habe den Eindruck, dass es an meinem Kartenadapter liegt
(Kontaktproblem zur Micro-SD-Karte).
Hatte auch am PC schon Probleme mit den ausgeleierten Adaptern. Evtl.
hat da jemand Erfahrungen?
...tuts eigentlich ffrm mittlerweile ?
Habe einige Tests gemacht und es scheint keine Verzeichnisse zu löschen.
ffrm("ABCDE ");
oder
ffrm("ABCDE");
steigen beide in
file.c
// datei/ordner nicht vorhanden, dann nicht loschen...
if(FALSE==fat_loadFileDataFromDir(name)){
return FALSE;
}
aus.
Das Verzeichnis ist aber vorhanden. Es macht auch keinen Unterschied, ob
man das Verzeichnis mit dem Controller oder mit Windows anlegt...
GRuß
Tom
Hallo,
Ich benutze bibliotekido Unterstützung MMC / SD:
AVR-mmc-0.6.4.zip
Autor: Daniel R. (zerrome)
Datum: 24.07.2011 08:49
Es funktioniert gut mit MMC, hat SD-Karte nicht unterstützt. Warum?
Radek
Wie kann ich bei geöffneter Datei die FAT updaten / zur SD schreiben? Da
ich noch unkalkulierbare Zustände habe, sind alle gesammelten Daten nach
einem Reset verloren...
Schade, dass es niemanden mehr gibt, der sich wirklich aktiv um dieses
brauchbare Projekt kümmert. Daniel R. (zerrome) ist wohl ausgestiegen
:-(
Aber zur Frage: Du kannst die Änderungen mit fflushFileData() auf die
SD-Karte schreiben. Damit steigt allerdings die Schreiblast, d. h. es
gibt mehr Schreibzugriffe.
Guten Abend,
ich habe mal ne Frage. Habt ihr auch hin und wieder das Problem, dass
die SD sich nicht initialisieren lässt? Ich habe auch das Gefühl, wenn
ich voher die freien Bytes auslese hängt sie sich noch öfters auf.
Jemand Erfahrung damit, bzw. kann das jemand bestätigen?
Wie schließt ihr die SD an? Irgendwo noch extra Pullups/downs?
Viele Grüße
André
Schade, dass es niemanden mehr gibt, der sich wirklich aktiv um dieses
brauchbare Projekt kümmert. :-(
Ich schaue auch nur sporadisch hier rein, deshalb kommt die Antwort erst
mit großer Verspätung.
Ich habe Pull-Ups (75 kOhm) an CS (Chip Select) sowie an den unbenutzten
Datenleitungen DAT1 und DAT2. Beim Initialisieren, also vor dem
Umschalten auf SPI, müssen diese Leitungen die richtigen Pegel haben.
Außerdem lege ich über die Versorgungsleitungen einen keramischen
Stützkondensator mit 100 nF, und zwar möglichst nahe an der SD-Karte.
Bei mir hängt sich die SD-Karte nie auf, aber das Abfragen der freien
Bytes dauert ziemlich lange. Vielleicht interpretierst Du das nur als
"Aufhängen". Warte einfach mal länger ab, das kann durchaus Minuten
dauern.
Hallo!
Huch, hier ist ja nicht mehr so viel los. Naja, vielleicht hat ja
trotzdem jemand Lust zu Helfen:
Okay, ich hatte mal wieder ein wenig Zeit an meiner Terrariensteuerung
weiter zu basteln. Ziel war es den Temperaturverlauf auf einer SD-Karte
zu speichern.
Grundprinzip des bisherigen Programms:
4 MHz ATMega162, Interrupt über Timer1 jede Millisekunde, die ISR zählt
dann gegebenenfalls die Uhr weiter und soll sich um die
Wellenpaketsteuerung der Heizung kümmern.
Die Lichtsteuerung passiert dann im Hauptprogramm. Code-Schnipsel dazu
finden sich bei Bedarf am Ende des Posts.
Jetzt habe ich aus einem USB-Dongle mit SD-Karten-Leser die Halterung
ausgelötet und mit einem 74HC4050 an den Hardware-SPI des ATMegas
gehangen.
Ich habe versucht den Interrupt auf 10 ms zu setzen:
1
// Configure Timer 1
2
// TCCR1A = 0x00;
3
TCCR1B|=(1<<CS10);
4
OCR1AL=0x9C40;
5
TIMSK|=(1<<OCIE1A);//Allow Compare Interrupt
Als Hauptprogramm habe ich erstmal einfach das Beispielprogramm genommen
und die UART-Ausgabe durch eine Ausgabe auf das angeschlossene
LCD-Display ersetzt.
Nach etwas Rumwackeln an der Karte fing er dann auch an auf die Karte zu
schreiben. Das Ergebnis:
1
ls -l
2
total 0
3
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
4
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
5
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
6
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
7
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
8
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
9
-rw-r--r-- 1 user users 0 1. Jan 1980 TEST.TXT
Die Datei sollte nicht nochmal neu erstellt werden wenn es sie schon
gibt und eigentlich sollten die Dateien auch einen Inhalt haben. So ganz
scheint es also noch nicht funktioniert zu haben.
Ausserdem:
Was kann/muss ich tun um dieses Programm auf meinen 1 ms-Timer
anzupassen?
Wenn es ein Problem mit der Karte gibt bleibt das Programm in
irgendwelchen Schleifen hängen, was bei der Steuerung der Temperatur
oder des Lichts störend sein dürfte.
Gibt es dafür bekannte Lösungen die einfach zu implementieren sind und
zuverlässig funktionieren?
Ich möchte dieses Projekt eigentlich gerne mit einem µC weitermachen,
auch wenn es mit einem Raspberry wohl einfacher wäre ;)
Hier die versprochenen Code-Schnipsel (ich hoffe sie sind nicht zu lang
fürs Forum):
Bitte immer daran denken, dass das Problem mit dem "Sektor gerade voll"
immer noch besteht (siehe viel weiter oben). Also: Immer schön nur eine
ungerade Datenanzahl auf die Karte schreiben. Dann treten diese
komischen FAT-Geschichten (Daten weg, plötzlich mehrere Dateien mit
gleichem Namen usw.) nicht auf.
Bin grade mal durch den Thread "durchgeflogen" - wenn ich das richtig
verstehe hat der Autor die Weiterentwicklung aufgegeben? Sehr schade
falls wahr, weil das wirklich ein gutes und nützliches Projekt ist.
Selber experimentier ich grade mit 'ner etwas schrägen Anwendung:
Dateien auf einem FAT Datenträger, die Container für CP/M Disk-Images
sind. Wobei ich dann typischerweise Datenblöcke von 512 Byte Größe in
der Gegend rumschiebe.
Bei der Gelegenheit hab ich (neben allen positiven Aspekten) eine Sache
an dem Projekt-Code entdeckt der mir nicht optimal erscheint: die
Funktion ffseek lädt gleich einen 512 Byte Sektor, wenn sie die passende
absolute Adresse gefunden hat. Fühlt sich aus meiner Sicht irgendwie
nicht "richtig" an - ffseek sollte diese Adresse nur zurückliefern und
es dann anderen Funktionen überlassen, ob der Sektor gelesen oder
geschrieben werden soll.
Just my 2 cents.
Ansonsten: Klasse Projekt!
Hab gestern und heute ein wenig mit der Bibliothek experimentiert, und
dabei folgenden Fehler gefunden:
In der *main_simple.c* Beispieldatei werden für eine Reihe von
Systemtakten die Konstanten für den Timer definiert, die Definition für
20MHz Systemtakt ist fehlerhaft. Dort steht (Version 0.6.4):
Habe diese Lib auch im Einsatz und bisher mit dem Ungerade-Modus das
Problem mit den vollen Sektoren umgangen.
Wollte der Sache aber auf den Grund gehen, damit das lästige
Prüfen-und-Leerzeichen-anhängen entfällt.
Deshalb habe ich die Bibliothek mal genauer untersucht.
Zu Testzwecken habe ich immer 512 Byte auf einmal geschrieben. Wie
erwartet blieb die Datei jedes Mal bei 32kB "hängen" (Zuordnungseinheit
32768 Bytes). Beim Schreiben von ungeraden Datenblöcken waren auch
größere Dateien möglich.
Vor dem Schreiben wird ja immer zuerst ffseek() ausgeführt, um an die
akutelle Position in der Datei zu gelangen. Dabei bin ich in ffseek()
auf folgendes gestoßen:
Wenn aber der Sektor genau vollgeschrieben ist (Bytes % 512 == 0) und
keine weiteren Sektoren mehr anstehen, gab das einen Überlauf bei
chain.cntSecs -= 1;
Habe also folgendes ausprobiert:
Hallo Martin,
ich habe ja vor langer Zeit den Fehler entdeckt, aber nie Zeit gehabt,
nach der Ursache zu suchen. Mit der Beseitigung dieses Fehlers dürfte
das Projekt perfekt sein. Einige Geräte laufen bei mir seit Jahren im
ungerade-Modus fehlerfrei (LUMINARY-CPU's). Ich teste morgen und teile
das Ergebnis mit.
Danke für Deine Bemühungen!
Hallo Wolfgang,
leider scheint das auch noch nicht ganz des Rätsels Lösung zu sein.
Habe zwei Datenlogger mit der Modifikation laufen.
Einer läuft tadellos, beim anderen habe ich Sprünge in der Aufzeichnung,
wenn ein Sektor vollgeschrieben wurde. Da sind dann plötzlich ein paar
Zeilen vertauscht...
Die Sprünge laufen nach diesem Prinzip (Jede Zeile steht für einen
Eintrag)
111111
22 555555
666666
777777
22222
333333
444444
Muss auch mit dem ffseek() zusammenhängen, womit er mit dem Schreiben
wieder einsteigt...
Hast du schon was herausgefunden?
Hallo Martin,
tatsächlich ist da immer noch der Wurm drin. Ab 15.Mai habe ich etwas
mehr Zeit, da werde ich das Problem lösen. Das Hauptproblem ist, dass
man die komplette Funktionsweise der Software erst mal verstehen muss.
Ich schätze, dass ich etwa 3-4 Tage Einarbeitung benötige.
Ich melde mich wieder!
Hi,
echt cooles Projekt, hat soweit erst mal auch gut geklappt. Leider bin
ich mit der Dauer für solch einen Schreibvorgang noch nicht wirklich
zufrieden. Dauert schon ne weile, bis man seine Daten auf die SD kriegt.
Hat da jemand Tipps, wie das vielleicht schneller gehen könnte?
Hallo,
ich versuche einen Datenlogger mit einem ATmega 8A aufzubauen. Ich habe
mir den Beitrag durchgelesen und den Source-Code angeschaut. Sehr
hilfreich, danke!
Das Beispiel ist mit einem ATmega 8
http://www.mikrocontroller.net/articles/AVR_FAT32#Der_Status
Schaltung aufgebaut wie im Beispiel. Ich habe allerdings einige Probleme
mit dem Code:
Zunächst hatte ich Probleme mit den Timer-Registern, die haben im Code
andere Bezeichnungen als im Datenblatt des ATmega 8 und des 8A. Die habe
ich entsprechend des AVR-Datenblattes angepasst.
Original:
static void timer0_init(){
TimingDelay = 0; // initialisierung der zaehl variable
TCCR0A = 1<<WGM01; // timer0 im ctc mode
TIMSK0 = 1<<OCIE0A; // compare interrupt an
TCNT0 = START_TCNT; // ab wo hochgezaehlt wird,
OCR0A = TOP_OCR; // maximum bis wo gezaehlt wird bevor compare match
TCCR0B = PRESCALER;// wenn prescaler gesetzt wird, lauft timer los
sei(); // interrupts anschalten, wegen compare match
}
Angepasst:
static void timer0_init(){
TimingDelay = 0; // initialisierung der zaehl variable
TCCR1A = (1<<WGM12); // timer0 im ctc mode
TIMSK = (1<<OCIE1A); // compare interrupt an
TCNT0 = START_TCNT; // ab wo hochgezaehlt wird,
OCR1A = TOP_OCR;// maximum bis wo gezaehlt wird bevor compare match
TCCR1B = PRESCALER;// wenn prescaler gesetzt wird, lauft timer los
sei(); // interrupts anschalten, wegen compare match
}
Dann bin ich noch total erstaunt, dass der uC mir nur über eine Baudrate
von 600 antwortet, im Quelltext steht doch 9600 ?!? hatte jmd das selbe
Problem?
"// Wenn auf dem terminal "Boot... OK" zu lesen ist, ist Init OK."
Und ich bekomme immer nur "\nBoot" als Antwort, das aber in regelmäßigen
Abständen. Woran kann das liegen, bei euch funktionierts doch überall,
ich habe ja am Quelltext quasi nichts verändert. Hatte es mit drei
verschiedenen SD-Karten probiert, alle standartformatiert, immer mit dem
gleichen Ergebnis.
Hat jmd von euch Erfahrungen mit dem Source-Code "AVR Version 0.6.4" vom
oben Beschriebenen Link?
Ich danke euch im Voraus für eure Antworten.
Grüße
Johannes
Hallo ich nochmal mit einem Update,
heute habe ich das Ganze nochmal mit einem ATmega 169A probiert.
Habe 1:1 den Quelltext von
http://www.mikrocontroller.net/articles/AVR_FAT32#Einfaches_Code-Beispiel
Aktuellste Version 0.6.4 genommen. Gleiche Problematik mit der Bautrate
600 statt 9600 und dass ich nur "\nBoot" empfange.
Ich habe nichts am Quelltext verändert und benutze die
Beispeilschaltung.
Komisch ...
Bei wem geht die Software denn und was verwendet ihr für eine Hardware?
Grüße
Johannes
Hallöchen..
Benutze die Version 6.4. Auf meinem Xmega128A1 funktioniert Lesen und
Schreiben über SPI mit 8MHz problemlos. Mit 16Mhz SPI Clock laufen
leider nicht alle SD Karten (Class4). Gibt Fehler bei der
Initialisierung, könnte vlt. aber am Timer im Xmega liegen. Werde das
mal überprüfen. Ferner funktioniert der MultiBlock Modus nicht. Habe
einige Unverständlichkeiten in der Datei "mmc.c" für den MultiBlock
Zugriff gefunden wzB:
response=mmc_write_command(cmd);// cmd13, alles ok?
14
15
mmc_wait_ready();
16
17
mmc_disable();
18
returnresponse;
19
}
Compiler Error: "response=mmc_write_command (cmd);"
Hab diese Zeile ersetzt durch:
spi_write_byte(cmd);
response = spi_read_byte;
Es scheint aber noch mehr Fehler in den Routinen für den MultiBlock
Zugriff zu geben. Bin auf der Suche..
Gruß Rolf
Hallöchen..
Da bin ich nochmal schnell. Der Initialisierungsfehler mit 16MHz SPI
Clock lag an dem verwendeten Breakout Board für die SD Karte. Da sitzen
5 Volt Pegelwandler zwischen den Steuerleitungen zur SD Karte um den
Pegel von 5 Volt auf 3.3 Volt abzusenken. Auf dem Board sitzt ein
Umschalter für 5 Volt oder 3 Volt Betrieb. Dieser steht bei mir auf 3
Volt, da ich einen Xmega mit 3.3 Volt Betriebspannung verwende. Diese
Pegelwandler scheinen bei 16MHz die Signalflanken der Steuerleitungen zu
sehr abzuflachen, so dass eine sichere und gute Datenübertragung zur
oder von der SD Karte nicht mehr gewährleistet ist.
Habe jetzt die Pegelwandler überbrückt, so das die Steuerleitungen
direkt mit dem Xmega verbunden sind.
Bild: SD Karte Breakout Board
Gruß Rolf
Hallöli..
Hab leider immer noch das Problem das bei MultiBlock Read kein Byte von
der SD Karte gelesen wird. Das Programm verweilt leider dauerhaft in der
while Schleife und wartet auf ein zu empfangenes FE Byte. Hab
verschiedene SDHC Karten (Class4) ausprobiert. Woran könnte es liegen ?
Wenn man die Berichte nur mal überfliegt ist es besser sich nach einer
Alternative umzusehen die auch das tut was sie soll.
FatFs von ElmChan ist z.B. so eine.
Dem Autor war nicht mal klar was der Unterschied zwischen einer .h und
.c Datei ist wenn man sich die ersten Posts in diesem Thread anguckt.
Das spricht Bände.
Hallo Torsten
Danke für den Tip. Die Software von ElmChan habe ich mir bereits
angesehen. Macht einen sehr guten Eindruck. Allerdings müsste ich dafür
die ganzen Routine in meinem Synth Projekt ändern
(http://www.cczwei-forum.de/cc2/thread.php?postid=86316#post86316).
Dafür habe ich aber im Moment keine Zeit. Ferner weis ich nicht, wieviel
Ram für die Zwischenspeicherung der Daten im Prozessor notwenig ist.
Muss mit dem Ram sehr sparsam umgehen, da andere Funktionen in meinem
Synthesizer auch Speicherplatz beanspruchen.
Mir ist aufgefallen, dass in den Funktionsroutinen
"mmc_multi_block_start_read" und "mmc_multi_block_read_sector" beim
Warten auf das Startbyte nur 0x00 empfangen wird. Wenn ich diese
Routinen umgehe findet eine Datenübertragung statt. Allerdings sind die
ersten Bytes nur Müll. Mir scheint es so, das die SD Karte die
MultiBlock Befehle nicht versteht. Bin aber kein Experte in Bezug auf
das FAT32 System. Verschiedene aktuelle SD Karten (Class4) habe ich auch
getestet.
Mir ist auch nicht ganz klar, ob sich der MultiBlock Zugriff in meinem
Projekt lohnt. Fürs Laden eines Sound Presets von der SD Karte wird
immer auf eine 32KByte große Binär Datei zugeriffen. Diese Datei
beinhaltet die Parameter und WAV-Dateinamen für insgesammt 128 Presets
in einer Sound-Bank. Beim Laden von Sound Samples siehts ein wenig
anders aus. Ein Wav-File kann die Größe von 1KByte bis 1MByte haben.
Bild 1: Datei und Ordner-System im Synthesizer
Bild 2. Preset Menü
Gruß Rolf
Guten Tag,
ich scheitere am versuch die Version 3.1 zu kompelieren, leider bekomme
ich fünf fehler (alle Fehler sind in der Datei fat-0.3.c):
-conflicting types for 'fat_writeSector'
-conflicting types for 'fat_getNextCluster'
-conflicting types for 'fat_getFreeCluster'
-conflicting types for 'fat_setCluster'
-'superfloppy' undeclared (first use in this function)
ich verwende Atmel Studio 6.2.
Wie könnte ich diese Fehler beheben ?
Grüße
Moritz
Hallo Moritz
Ich habe mit der Version 0.6.4 auch Probleme beim kompilieren und bin
aus diesem Grund wieder zurück auf eine 5er Version glaube ich. Kanns
leider nicht genau sagen. Im Anhang die kompilierten Dateien. Einfach
die Dateien in AVR Studio 6.2 im Solution Explorer als Existen Item
"adden" bzw laden und kompilieren. Wichtig ist die initialisierung eines
Timers mit 10ms Interrupt, da sonst zeitkritische Sachen in der SD
Routine nicht funktionieren. In dem Timer wird die Variable TimingDelay"
decrementiert.
Hab dir mal den Source Code drangehangen. die zwei Dateien sd_card.c und
sd_card.h sind meine Funktionsroutinen im Programm und als Beispiel
gedacht. Ist aber alles noch etwas konfus. Ich hoffe das hilft dir
weiter :)
LG Rolf
>ich scheitere am versuch die Version 3.1 zu kompelieren,
Was willst du mit diesem uralten Kram? Alle bereits
gefundenen Fehler noch mal suchen? Nimm ne neuere Version
und klopp den Dreck in die Tonne.
In einem Datenlogger-Projekt habe ich bisher FatFs von ElmChan
verwendet, der hat aber in der aktuellen Version einige radikale
Veränderungen bei einigen Funktionsaufrufen vorgenommen und die
Konfiguration ist dank der vielen Module auch schon immer sehr chaotisch
gewesen - es ist wohl schwer, eine eierlegende Wollmilchsau auf Dauer am
Leben zu erhalten.
Hier dagegen läuft die Konfiguration dank einer zentralen .h-Datei sehr
einfach und problemfrei und ich konnte den Kode direkt und ohne Probleme
zum Laufen bringen - Version 0.6.1 vom SVN-Server ist zwar 4 Jahre alt,
ließ sich aber problemlos mit AVR-Studio 6.1 und aktueller Toolchain
kompilieren.
Testsystem: 3,3V ATmega328P und microSD SDHC von 4GByte und 8GByte.
Der Quellkode selbst ist etwas gewöhnungsbedürftig - bin dabei, den Kode
etwas aufzuräumen und zu anglifizieren.
Aber : Bei der Verwendung langer Dateinamen scheint es ein Problem zu
geben, wenn der lange Dateiname kürzer ist, als ein kurzer Dateiname -
eine auf diese Weise erstellte Datei hat plötzlich zwei Punkte im
Dateinamen und läßt sich unter Windows nicht öffnen - da sich das
vermeiden läßt, habe ich noch nicht nach dem Fehler gesucht...
Und erst jetzt sehe ich ein, daß die "aktuelle" Version auf dem SVN
eine uralte Version ist, und man sich wie immer hier im Forum durch
Gigazeilen von Kommentaren und inkrementellen Änderungen Lesen muß.
Schade eigentlich. Ich will ja nicht wirklich etwas umsonst und ohne
Arbeit haben, hatte mich ja schon daran gemacht, die Version 0.6.1
aufzuräumen, aber das macht dann ja wohl keinen Sinn mehr... Mal sehen,
och ich Version 0.6.4 ebenfalls direkt und unproblematisch zum Laufen
bekomme, auch wenn mir der eingeführte 10ms-Timer doch einiges
Kopfzerbrechen bereitet - abgesehen von Aktivitäten soll mein Logger nur
einmal pro Sekunde aufwachen, aber das läßt sich sicher irgendwie
anpassen...
Ich hoffe, ich habe jetzt schließlich die aktuelle Version gefunden...
Hat jemand von Euch erfahrungen mit dieser implementierung gemacht:
https://github.com/BizzaBoy/RFAT
Besonderes Interesse wäre wie "robust" diese Implementierung wirklich
ist. Der Autor behauptet ja es sei: "100% power fail safe."
Hallöchen..
Ich benutze die aktuelle Version der FAT32 Library.
Ich hab nun folgendes Problem. In einem Ordner befinden sich insgesamt 9
Dateien. Mit der 'ffrm()' Funktion möchte ich eine Datei aus dieser
Liste löschen. Leider werden aus der Liste immer 2 Dateien gelöscht.
Z.B. Datei-Liste mit Bezeichnung 1-9. Wenn ich die Datei '3' lösche,
dann wird die Datei '2' mit gelöscht. Wenn ich Datei '9' lösche, wird
Datei '8' auch gelöscht. Wenn ich die 1.Datei '1' lösche, wird Datei '2'
auch gelöscht. Ist nur eine Datei vorhanden und wird diese gelöschr,
bekomme ich wieder andere Dateien mit 0Byte angezeigt ????
Mein Code:
1
// set folder
2
ffcd("");ffcd("SAMPLE");
3
4
// file available ?
5
if(fat_loadFileDataFromDir(sample_name)==TRUE)
6
{
7
// delete file
8
ffrm(sample_name);
9
ffclose();
10
}
Hardware: SDHC Card 4GB SanDisk Fat32 Format
Software: Aktuelle Version FAT32
Schreib- und Lesefunktionen funktionieren problemlos. Nur das löschen
der Dateien nicht. Kann mir vielleicht jemand helfen. Danke im Voraus.
Gruß Rolf
Hallo..
Hier im Forum gabs einen Beitrag von Lukas
Beitrag "Re: MMC SD library FAT16 FAT32 read write" indem
er auf einige Fehler in der FAT32 Library hingewiesen hat.
Das Löschen von Dateien funktioniert mit der neuen 'ffrm()' Routine von
Lukas problemlos.
Im Anhang nochmal die FAT32 Library von Lukas.
Gruß Rolf
Hey,
ich hab eine Frage zur "TimeDelay" variable...die wird doch nur
benötigt, damit man in einem Fehlerfall nicht in einer Endlosschleife
steckt, oder? D.h. man braucht diese nicht unbedingt im ISR
dekrementieren. Oder liege ich da falsch?
Frage2: mmc_init()und fat_loadFatData() wird ohne Probleme(return ==
TRUE) ausgeführt. Wenn ich dann eine Datei anlege
1
if (ffopen(fname, 'c') == MMC_FILE_CREATED)
2
{
3
ffwrites((uint8_t*) "test");
4
ffwrite(0x0D);
5
}
6
ffclose;
und diese schließe, findet die Funktion ffopen(fname, 'r') die Datei
nicht.(Fehlercode: MMC_FILE_ERROR)
Hatte jemand evtl. noch dieses Problem?
Hallo Andy,
in der 'mmc_init' wird TimingDelay auch benutzt. Könnte sein, dass deine
Karten dann nicht mehr richtig initialisiert bzw erkannt werden, wenn du
es weglässt. Da ich mehrere Timer-Interrupts in meinem Synthesizer
benutze, habe ich TimingDelay mit integriert.
Ich benutze die letze Version 6.4 Datei Anlegen und Öffnen geht bei mir
ohne Probleme.
Beispiel:
(die Delays sind nur für die Textmeldungn auf meinem Display notwendig)
1
// save Preset Data ---------------------------------------------------
2
set_preset_folder();
3
4
// Data.bin file available ?
5
if(fat_loadFileDataFromDir("Data.bin")==FALSE)
6
{
7
fillrectangle(30,38,280,145,color_blue1);
8
rectangle(33,42,99,243,color_white);
9
fillrectangle(139,42,180,65,color_blue1);
10
draw_string("File 'Data.bin' not found!",42,75,6,color_white);
11
_delay_ms(1000);
12
if(MMC_FILE_CREATED==ffopen("Data.bin",'c'))
13
{
14
draw_string("create new File...",42,90,6,color_white);
15
_delay_ms(500);
16
ffwriten(0,0x8000);
17
}
18
ffclose();
19
}
20
21
22
voidset_preset_folder(void)
23
{
24
// set Preset Folder --------------------------------------------------
25
ffcd("");
26
ffcd("PRESET");
27
28
// set PRBANK Folder --------------------------------------------------
29
charfolder_temp[9];
30
strcpy(folder_temp,"PRBANK");
31
32
charxx[3];
33
sound_bank=sel_sound_bank;
34
35
itoa(sound_bank,xx,10);
36
if(sound_bank>9)
37
{
38
strcat(folder_temp,xx);
39
}
40
else
41
{
42
strcat(folder_temp,"0");
43
strcat(folder_temp,xx);
44
}
45
ffcd(folder_temp);
46
47
// Set SOUND Folder --------------------------------------------------
Bezogen auf meinen Beitrag #3769720 vom 19.08.2014 10:27 (etwas weiter
oben):
Ich habe das Datei System auf der 4GB SD Karte meines Synthesizers
geändert. Dazu gehört das abspeichern oder löschen von Samples und
Presets.
Das hört sich jetzt nicht gerade kompliziert an, aber die Arbeit steckt
mal wieder in den Details. Die Abbildung zeigt die Ordner Stuktur auf
der SD Karte.
Auf der SD Karte gibt es drei Ordner mit der Bezeichnung PRESET, SAMPLE
und SYSTEM. Im Ordner 'Preset' sind die gesamten Sound Parameter,
UserWave-Table und ggf das Sample-File für den Sound abgespeichert. Der
Ordner 'SAMPLE' beinhaltet die gesamte Sample Library. Hier kann man
Samples laden, speichern oder löschen, ohne eine Beeinflussung auf die
Preset Sounds. Dadurch kann man z.B. die komplette Sample Library auf
der SD Karte ändern oder austauschen, ohne Gefahr zu gehen, dass sich
die Preset Sounds verändern. Falls ein Preset ein Sample-File besitzt,
wird dieses immer im Preset Ordner mit abgespeichert.
Im Ordner 'SYSTEM' befinden sich System relevante Daten wzB Bilder,
Sequenzer-Daten, USERWAVE-Table und die aktuelle Midi CC Tabelle. Die
USERWAVE-Table besteht aus 128 festen Wellenformen mit 256 Byte Größe
und kann beliebig ausgetauscht werden. Damit stehen dem Benutzer
unendlich viele Möglichkeiten der Soundgestaltung zur Verfügung.
Gruß Rolf
andy schrieb:> Hey,>> ich hab eine Frage zur "TimeDelay" variable...die wird doch nur> benötigt, damit man in einem Fehlerfall nicht in einer Endlosschleife> steckt, oder? D.h. man braucht diese nicht unbedingt im ISR> dekrementieren. Oder liege ich da falsch?>> Frage2: mmc_init()und fat_loadFatData() wird ohne Probleme(return ==> TRUE) ausgeführt. Wenn ich dann eine Datei anlege>
1
if (ffopen(fname, 'c') == MMC_FILE_CREATED)
2
> {
3
> ffwrites((uint8_t*) "test");
4
> ffwrite(0x0D);
5
> }
6
> ffclose;
7
>
> und diese schließe, findet die Funktion ffopen(fname, 'r') die Datei> nicht.(Fehlercode: MMC_FILE_ERROR)> Hatte jemand evtl. noch dieses Problem?
Hi Andy
Ich glaube ich hatte mal ein ähnliches Problem.
Es könnte noch daran liegen, dass du zuerst einen Ordner anlegen musst
und dann eine neue Datei in dem Ordner erstellen kannst.
Gruß Rolf
Hey Rolf,
danke für deine Antwort. Leider hat es daran nicht gelegen. Habe jetzt
auch Timingdelay mit eingebaut, hilft auch nichts. Bin immer noch am
suchen der Lösung. Wenn ich den Fehler finde, melde ich mich ;)
Hallo Rolf,
Obwohl diese lib nicht als eine der zuverlässigsten gilt hast Du Dich
dran gemacht diese benutzbar zu machen - mutig. Und scheinbar tuts die
auch.
Beim überfliegen des obigen Quelltextes bin ich beeindruckt. Ohne von
dieser Materie allzuviel zu verstehen kann ich nur ahnen wieviel Arbeit
da drin steckt. Respekt!
Das einzige was mir nicht gefällt sind die vielen einzelnen
read_par_value() und write_par_value() Aufrufe. Vielleicht könnte man
das in ein struct packen und mit einem einfachen memcpy initialisieren
oder von der Karte lesen.
Einen guten Rutsch,
Torsten
Hallo Leute,
erstmal vielen Dank für die Library. Ich wollte einen Datenlogger bauen,
und wenn die mmc_init durchläuft funktioniert alles hervorragend. Nur
manchmal kommt er nicht durch die prozedur
1
while(FALSE==mmc_init()){
2
_delay_ms(100);
3
4
}
Egal wie lange ich warte, die init läuft nicht durch. Hingegen andere
male funktioniert es... es scheint ziemlich zufällig zu sein. Außerdem
habe ich herrausgefunden, dass wenn ich mit meinem Finger den Miso pin
berühre, dann funktieniert das meistens, kann aber ebenfalls zufall
sein. Ein Hardreset des controllers hilft auch nicht immer. Wenn Die
Spannungsversorgung an bleibt und die sd karte einmal initialisiert
worden ist und man dann den controller resettet, dann geht es fast
immer. Aber wenn diese wieder ausgeschaltet wurde, dann funktionier das
weniger oft.
Hatte jemand von euch schonmal solche probleme? Ich bin mittlerweile
wirklich ratlos.
Grüße
Nicolai
PS: ATMEGA32 16MHZ Quartz SDHC 8GB
Hallo,
Der letzte Beitrag ist ja schon etwas her...
ich habe die hardware so aufgebaut wie beschrieben und benutze auch den
Beispielcode. Leider kommt der Controller fast nie druch die MMC_Init
funktion.
Ich habe jetzt alle Einträge hier gelesen und auch weitere die man so im
Internet findet. Leider konnte mir keiner so wirklich helfen. Wenn die
karte erstmal initialisiert ist funktionier das Schreiben auch
zuverlässig mehrere Tage lang. Interessanter Weise hängt sich die
Funtkion wirklich auf...
hat jemand damit schon Erfahrung?
Viele Grüße
Nicolai
Hallo,
ich hoffe hier liest manchmal noch jemand mit. Habe die lib erfolgreich
zum laufen gebracht. Nur mit neuen SD-karten gibt es auf einmal
Probleme. Lesen und schreiben klappt nur einmal. Dann kann man zwar die
geschrieben machen auf dem PC anschauen jedoch nicht auf der MCU.
Unterscheid zu alten karten ist der "First Physical Sector". Bei den
altern Karten ist diese immer 1 bei den neuen 8192. Was hat das zu
bedeuten und kann das mein Problem sein? Wie kann man das lösen?
Grüße Peter
Das Problem hatte ich vor Jahren gefunden, aber noch keine Lösung. Ich
verwende die Software bisher in vielen Projekten völlig ohne Probleme.
Das war nur möglich, weil ich immer nur Klartext an PC zu übertragen
hatte, da störte es nicht, ein zusätzliches Leerzeichen vor dem 0d0a
einzufügen, wenn die übertragene Zeichenzahl für diese Zeile ungerade
war.
Seit der Findung des Problems liegt ein Link zu meiner E-Mail auf diesem
Beitrag. In den neuen Einträgen war bisher noch kein Lösung des Problems
dabei.
Hallo,
Seit einiger Zeit versuche ich es diese Bibliotheken einzubinden und zu
nutzen.
Im konkreten Fall geht es hier um einen Atmega48 der auf eine SD-Karte
schreiben soll.
Nun bin ich relativ ungeübt, was Bibliotheken einbinden usw angeht,
sodass ich wahrscheinlich eine deutlich detailliertere Anleitung
benötige.
Nun zum Eigentlichen Problem:
Ich arbeite derzeit mit Atmel Studio 7. Beim Erstellen eines neuen
Projektes, füge ich:
fat.c, fat.h
file.c, file.h
mmc.c, mmc.h
mmc_config.h
uart.c, uart.h
hinzu.
Danach bekomme ich diese Fehlermeldungen angezeigt(Im Anhang
fehlermeldung_anfang_sd)
Dabei ist mir aufgefallen, dass in der mmc.h kein AT_Mega48 enthalten
ist, weshalb ich den Mega8(der Pingleich ist) kopiert habe und umbenannt
habe. (Zu sehen in Aenderung1_mmc.h_)
Danach sind mehr Fehlermeldungen aufgetaucht, die so wie es ausschaut,
viel mit dem UART zu tun haben. (Zu sehen in
fehlermeldung_nachAenderung1_sd)
Da stellt sich mir die Frage, warum benötige ich diese uart.h überhaupt?
Nun bin ich mir unsicher, ob ich total auf dem Holzweg bin oder mich
langsam der Lösung des Problems nähere.
Ich würde mich über Antworten sehr freuen.
Mit freundlichem Gruß
Marius
Im Tutorial gibt es das Setting
> #define MMC_SDHC_SUPPORT TRUE
Aber in den Quelltexten von Version 0.6.4
(http://www.mikrocontroller.net/attachment/116369/AVR-mmc-0.6.4.zip)
konnte ich dieses Setting nicht finden.
Ist das Setting überflüssig geworden oder ist der Link zum Download
nicht mehr aktuell?
Wer Fehlermeldungen des Kompilers bekommt , wie
DECLARATION_AC_POWER_ON_IRGENDWAS undeclared ,
dem fehlen additionelle Header-Files , oder aber hat diese Deklarationen
in weiteren System-Headern der Compillier-Umgebung schon vorhanden .
Insbesondere wenn die Kompillierumgebung Linux ist , dann werden mit den
GCC-Bibliotheken und besonders mit dem Linux-Kernel in
/usr/include/*/linux ständig Deklarationen verändert , ausgelagert in
andere Header , oder gar vollständig entfernt , oder umbenannt .
Dieser Strang ist schon ca. 10 Jahre alt , und viele Systemheader des
GNU-Compilers , der C-Bibliotheken und des Linux-Kernels werden sehr
andersartig aussehen .
Die Kompillierumgebung hat sich sehr verändert , und man müsste sich
Linux - Betriebssystem e aus alten Zeiten besorgen , um an die Header
und Fertigkompillierten Bibliotheken zu kommen , die zum Kompillieren
und Finalem Verlinken bzw. Statischem Einbau nötig sind .