Hey Daniel,
sehr nett, dass du nachfragst. Aber leider funktionierts noch nicht
zufriedenstellend. Habe mir mal den Beispielcode geschnappt und
stückchenweise modifiziert. Die Idee war dann tatsächlich mit ffwrite
(ohne s) wegzuschreiben und zwar auf knopfdruck == trigger.
Es bleiben dabei zwei Probleme: Ich habe es immernoch nicht geschafft
ausser beim Beispielcode eine Datei nach dem entnehmen der Karte und
neuinitialisierung wieder zu öffen und zu beschreiben.
Das zweite Problem ist mehr eine Frage. Ich konnte nicht ganz ausmachen,
an welcher Stelle des Codes wirklich echt vom RAM auf die Karte
geschrieben wird. Denn ich würde gern auf Knopfdruck ebenfalls den rest
der im RAM steht, auf die Karte schreibt, sodass man sie entnehmen kann.
Wenn ich das recht sehe, dann tut das ffclose nicht allein, sondern
setzt nur die Flags null.
Am besten poste ich mal wie ich den Beispielcode modifiziert habe.
Vielleicht ist da was schief gelaufen, was ich nicht seh...
Was du da siehst, ist meine "wunsch-Konfiguration". Sie funktioniert
nicht. Habe vorher Stückchenweise ausprobiert und sobald ich das ffclose
auf knopfdruck aufrufe, funktionierts nicht mehr. Die Datei kann nicht
gelesen werden unter windows (beschädigt) es wird aber eine realistische
größe angezeigt.
1
while(1)
2
{
3
if(!((PINC&0x01)==0x01))
4
{
5
if((PINC&0x01)==0x01)//<<---- Erst beim Loslassen schreiben.
6
{
7
// Datei existiert, also anhaengen !
8
if(MMC_FILE_EXISTS==ffopen(file_name))
9
{
10
11
// bewusst kein ffseek, weil ja, nicht geschlossen und Flags noch gesetzt
12
13
// schreibt "String" Alternativ While Schleife
14
ffwrite(48);
15
ffwrite(49);
16
ffwrite(50);
17
ffwrite(51);
18
ffwrite(52);
19
ffwrite(53);
20
ffwrite(54);
21
ffwrite(55);
22
ffwrite(56);
23
ffwrite(51);
24
25
26
27
// neue Zeile in der Datei
28
ffwrite(0x0D);
29
ffwrite(0x0A);
30
31
/// Bewusst kein ffclose, da erst auf knopfdruck schließen soll
32
33
}
34
}
35
36
}
37
if(!((PINC&0x04)==0x04))// <<--- Kontroll LED
38
{
39
ffclose();
40
PORTD=0xCC;
41
}
42
}
Aber Fortschirtte gibts schon. Das ganze soll ein Wasserzähler werden
der kalt und Warmwsser loggt. Die alte ochsentour mit dem
selbstdefinirtem RAM hat ja einigermaßen fuktioniert, sodass ich ihn
schon 24h hab laufen lassen können. Hab mal das Histogramm angehängt ;-)
Gruß, Fiete
Hallo.
>Ich habe es immernoch nicht geschafft>ausser beim Beispielcode eine Datei nach>dem entnehmen der Karte und>neuinitialisierung wieder zu öffen und zu beschreiben.
Ich vermute mal, dass Du bevor Du die Karte entfernst nicht ffclose
aufrufst. Mach es doch so, dass Du eine LED einschaltest wenn Du ffopen
aufrufst und aus, wenn du ffclose aufrufst. So kannst Du genau sehen ob
die Datei geöffnet oder geschlossen ist.
>Ich konnte nicht ganz ausmachen,>an welcher Stelle des Codes wirklich>echt vom RAM auf die Karte...
Bei einem fflushFileData() wird alles was aktuell im Ram ist auf die
Karte geschrieben. Zudem wird der Dateieintrag geupdatet. Das ist
prinzipiell ein ffclose(), nur dass die Datei danach nicht neu geöffnet
werden muss um weiter zu schreiben. Sollte aber so selten wie möglich
aufgerufen werden, da viele Schreiboperationen auf der Karte gemacht
werden.
Sind die Taster ordentlich entprellt? Vielleicht geht da einiges
durcheinander.
So wie ich das sehe, öffnest Du die Datei mehrfach, bevor Du sie
schließt.
Versuch mal das:
1
if(MMC_FILE_EXISTS==ffopen(file_name))
2
{
3
// Datei existiert, also zum Ende spulen
4
ffseek(file.length);
5
6
// hier Status LED an
7
}
8
9
while(1)
10
{
11
// Pin1 gedrückt?
12
if(!((PINC&0x01)==0x01))
13
{
14
// hier warten bis Taste losgelassen wird!
15
while(!((PINC&0x01)==0x01));;
16
17
// schreibt "String" Alternativ While Schleife
18
ffwrite(48);
19
ffwrite(49);
20
ffwrite(50);
21
ffwrite(51);
22
ffwrite(52);
23
ffwrite(53);
24
ffwrite(54);
25
ffwrite(55);
26
ffwrite(56);
27
ffwrite(51);
28
29
// neue Zeile in der Datei
30
ffwrite(0x0D);
31
ffwrite(0x0A);
32
}
33
34
// Pin4 gedrückt?
35
if(!((PINC&0x04)==0x04))
36
{
37
ffclose();
38
39
// Status LED hier aus, alles OK. Karte kann entfernt werden!
40
41
break;// um aus endlosschleife zu kommen
42
}
43
44
}
Ohne den Code so laufen zu lassen, denke ich sollte das gehen.
Hoffe irgendwas hiervon hilft :)
Viele Grüße
Daniel
Hey Daniel, danke für deine Antwort. Ich werds gleich heute abend mal
ausprobieren.
Zum Prellen: ich habe mir eigentlich entprellte Taster besorgt. Lese
gerade, dass man da noch Vorkehrungen treffen muss. Ich bin bisher immer
davon ausgegangen, das es bei entprellten tastern kein Problem ist...
Vielleicht hat er bei ffclose deshalb probleme bekommen...
Zu Kontroll LEDs: Ja, hab kontroll LEDs eingefügt, bei denen ich seh, wo
er grad ist. Ich konnte sogar sehen, dass er auf die Karte geschrieben
hat, weil er dann läger im ffwrite war und so die LED nen bissel länger
geleuchtet hatte. In dem code den ich dir schickte, sind die LEDs nur
noch zum teil drin. Ich schiebe die immer rum im code, um zu gucken, wo
er grad "hängt".
Zu ffclose: Stört es, wenn ffclose mehrfach aufgerufen wird? Weil die
Verrenkung dass er erst beim Losassen aus der Schleife steigt, hab ich
mir bei ffclose gespart.
Zu fflushFileData: Muss man danach noch ffclose aufrufen? Wenn ichs
recht sehe ja.
Kann es eventuell sein, dass die Karte einen knacks hat?
Ich werde wie gesagt mich heute Abend mal damit auseinander setzen und
bericht erstatten.
Danke nochmal.
Gruß, Fiete
Hallo.
>...Verrenkung dass er erst beim>Losassen aus der Schleife steigt...
Die Verrenkung ist doch nur ein "break;" um aus der Schleife raus zu
kommen. Ob jetzt bei Taste gedrückt oder losgelassen ist ja nur die
Abfrage im if...
>Stört es, wenn ffclose mehrfach aufgerufen wird?
Eigentlich nicht, ist aber unnötig. Muss halt so programmiert werden das
es nicht vor kommt :)
>Zu fflushFileData: Muss man danach>noch ffclose aufrufen? Wenn ichs>recht sehe ja.
fflushFileData ist eigentlich dazu gedacht, dass wenn ein Gerät z.B.
über Tage läuft und Daten loggt, man zwischendurch mal zur Sicherheit
fflushFileData aufruft. So hat man die Daten bis dahin schonmal
gesichert, falls der Strom ausfällt oder ähnliches. Dadurch spart man
sich ein ffclose und ffopen.
Funktioniert die Karte denn unter Windows noch ordentlich? Also
beschreibbar, lesbar und keine Fehler beim Formatieren? Wenn es da keine
Probleme gibt, sollte die Karte noch OK sein.
Viele Grüße
Daniel
Hallo.
Ich bin hier neu im Forum und habe bis jetzt nicht so viel Erfahrung mit
AVRs. Deswegen bitte sich nicht über meine dummen Fragen ärgern.
Ich werde mein Atmega32L mit 3,3V versorgen und mit 8MHz takten. Meine
Karte hat 2GB. Ich möchte Fat32 benutzen.
Soll sie zuerst mit dem PC mit FAT32 formatiert werden oder macht das
dein Programm?
Kanst du mir bitte sagen an welche Pins des Atmega32 ich die SD Karte
anschliesen muss?
Wo soll ich im Code eine Umstellung von Fat16 auf Fat32 machen?
Mit welcher Funktion wird eine neue Datei erzeugt?
Mit welcher Funktion wird eine Datei beschrieben?
Grüße,
Lukas
Hey Lukas,
also das mit den SD-Karten ist nicht so ganz ohne. Du solltest schon
mindestens nen bisschen C mitbringen und das AVR Tutorial wäre auch
nicht schlecht, einfach, damit du nen bissel weißt, was du tust. Es ist
jedenfalls im seltensten Fall so, dass man es einschaltet und alles
funktioniert. Guck dir mal in der Artikelübersicht
http://www.mikrocontroller.net/articles/MMC-_und_SD-Karten da steht
schonmal ne Menge drin.
Gruß, fiete
Hallo.
Man verwendet Belegung wie sie in der "mmc-0.2.H" Datei angegeben ist.
Habe ich das richtig verstanden? Warum wird denn der SPI-Port für den
Anschluss verwendet. Das ist doch unpraktisch, jedesmal die Karte
auszustecken um zu programmieren??
Hast du deine Karte auch an PORTB abgeschlossen?
Grüße,
Lukas
Der SPI-Port stehllt das Protokoll bereit, das mit der Karte
kommuniziert. Das ist eine Bus-Kommuikation. Es können also mehrere
Bauteile angeschlossen werden und nur das, welches aktivirt ist, fühlt
sich auch angesprochen. Aktivirt wird wenn ichs richtig im kopf hab wenn
pin 0 auf high gezogen wird...
Ich versuche gerade die Software mit Keil µVision4 auf einen LPC2148 zu
portieren. Der Compiler spuckt aber Fehler aus. Da soll wohl noch was
umgecastet werden?
1
fat.c(120): error: #852: expression must be a pointer to a complete object type
2
fat.c: vsector+= 6;
3
fat.c: ^
4
fat.c(123): error: #852: expression must be a pointer to a complete object type
5
fat.c: vsector+=2;
6
fat.c: ^
7
fat.c(422): error: #852: expression must be a pointer to a complete object type
8
fat.c: *(unsigned char*)vsector++ = 0x00;
9
fat.c: ^
10
fat.c(431): error: #852: expression must be a pointer to a complete object type
Hallo,
versuch mal "#define MMC_ENDIANNESS_LITTLE FALSE" in der config.h
Damit fliegen überall die void Pointer raus. Ist aber evtl. nicht so
schnell dann.
Es gibt da mit mehreren Kompilern Probleme wegen void Pointern. Verstehe
ich nicht ganz, weil das eigentlich normaler C Standard sein sollte...
Viele Grüße
Daniel
Hi,
ich hab da auch mal wieder ne Frage.
Ich will mit der neuen Version (0.6.1) einen Ordner anlegen. In der
Config.h ist #define MMC_LFN_SUPPORT TRUE. So weit, so gut!
Aber wenn ich nun alle:
ein Verzeichnis anlegen will, dann geht das nicht. Windoofs will da wohl
am ende der Eingabe noch ein abschließedendes Zeichen haben. Kann mir
bitte jemand verraten, welches das ist?
Und mit einem HEX-Editor kann ich leider kein Verzeichnis öffnen... Bei
normalen Dateien kann man ja "spicken" wie bestimmte Steuerzeichen
aussehen. Bei Ordner geht das nich...
Danke für alle guten Tipps!
Matze
Danke Daniel. Das lesen von Dateien geht jetzt ohne Probleme. Aber beim
fclose nach dem schreiben in eine Datei bleibt er hängen. Ein Hardware
Problem schließe ich aus, da das lesen funktioniert. Timing Probleme
dürften es auch nicht sein da ich den Prozessor bis auf 12MHz
runtergetaktet habe.
Im Anhang ist das komplette µVison Projekt, lauffähig mit debug
Ausgaben, und die debug Meldungen. Er bleibt ganz am Schluss zwischen
Kontrollpunkt D und E hängen, obwohl er vorher mehrmals korrekt bis E
durchläuft.
Ich höffe es ist einigermaßen verständlich was ich meine. ;-)
Mfg,
Kurt
PS: Ich habe die Software auch auf einem Mega32 mit 18,x MHz getestet,
da funktionieren lesen und schreiben wunderbar!
Leider waren doch meine SPI (SSP) Funktionen falsch! Also bitte meine
beiden letzten Beiträge ignorieren.
ABER: In der fat_loadSector() ist anscheinend ein return FALSE zuviel?
Mfg,
Kurt
Hallo zusammen.
Wunderbar, dass sich hier alles von selber erledigt :)
Hm, das FALSE da ist wirklich überflüssig... da kommt man ja garnicht
hin.
Wird geändert.
Viele Grüße
Daniel
Hallo,
erstmal: Super Arbeit!
Leider läuft das Schreiben auf die SD-Karte nur sehr langsam.
Ca. 4kB/s! Auf dem Osi sieht man, dass er manchmal 200ms brauch um auf
die Karte zu schreiben.
Aber die Datei wird fehlerfrei geschrieben.
Hat jemand eine Ahnung wodran das liegen könnte, ich verzweifle dran?
Habe schon verschiedene SD-Karten ausprobiert, Takt geändert, immer das
gleiche Problem!
Daten:
Atmega88 @7.3728Mhz @3,3V
das problem hab ich auch manchmal. versuch mal ne andere SD-Karte.
Wenn ich mal ausversehen die SD-Karte im Slot habe, wenn der ISP dran
is, dann kriegt sie wohl einen "Schaden". In anderen Geräten geht sie
dann noch, aber am µC nich mehr. Ich weiß auch nicht, woran das liegt.
Is halt mein "Word-Around"... Nich schön, weil auf dauer teuer, aber was
will man machen ;)
Hmm... habe mich wohl geirrt! Sorry!
Ich hatte ja das selbe Problem: mals liefs und mal nicht. Ich habe immer
mit WinAVR compiliert und bin gestern einfach mal spaßeshalber in das
AVR Studio gewechselt und habe da den selben Code compiliert - jetzt
geht alles und zwar immer... also, wenn du mit dem WinAVR arbeitest:
wechseln ;)
Hallo,
kann mir eigentlich nur vorstellen, dass es mit Kompiler Optionen zu tun
hat oder etwas in dieser Richtung. Vielleicht ist es aber auch wenn das
nur bei einer Karte auftritt eine extrem langsame. Habe hier auch eine
16MB Karte die extrem langsam ist.
Grüße
Daniel
Naja, ich habe am Versuchsaufbau nichts geändert! Sogar die selbe Karte
benutzt. Mit dem ARV Studio geht es nun aber flüssig und vor allem
immer.
Is komisch, ist aber so.
Hallo,
danke für die Anregungen.
Ich arbeite nur mit Avr Studio, also daran lag es nicht.
Habe mal ne ganze Menge an Karten ausprobiert und gemessen. Habe
festgestellt, dass die Noname Karten am Besten funktionieren.
Habe die Benchmark bißchen umgeschrieben. Schreibe 196k-Datein und davon
100 Stück und messe die einzelnen Zeiten! Folgende Ergebnisse:
ScanDisk SD 2Gb (neu):
3.2s für die 1.Datei
10s für die 100. Datei
SD-Formel1 256Mb (hab ich irgendwo ausgegraben):
2,6s für die 1.Datei
2,4s für die 100. Datei
NONAME SD-micro 2Gb (aus meinem Handy)
3.6s für die 1.Datei
3.4s für die 100. Datei
CN Memory SD 8Gb mit SD_HC Support (neu)
3.2s für die 1.Datei
25s für die 100. Datei
Hab da noch paar Karten getestet. Manche werden halt sehr lahm! Hab
keine Ahnung wodran das liegt, benutze einfach die Karten die durchweg
schnell schreiben. Das sind die Karten die sich mit FAT 16k formatieren
lassen. Keine Ahnung, ob das damit zusammen hängt??? Bin noch Laie auf
dem Gebiet!
Welche Karten würdet ihr denn empfehlen? Sind MMC Karten schneller?
Hallo,
stimmen diese Daten?
>SD-Formel1 256Mb (hab ich irgendwo ausgegraben):>2,6s für die 1.Datei>2,4s für die 100. Datei>NONAME SD-micro 2Gb (aus meinem Handy)>3.6s für die 1.Datei>3.4s für die 100. Datei
Die werden schneller bei 100 Dateien?!?
Zeig mal den Benchmark Code !
Ja MMC Karten sind deutlich schneller, keine Ahnung wieso.
Fat16 zu Fat32 macht bei mir keinen so großen Unterschied. Ist im
einstelligen KB Bereich.
Ob ich Multiblock ein/aus schalte macht deutliche Unterschiede.
Deine maximale SPI Geschwindigkeit ist f_cpu / 2 also 7,3728 MHz / 2 =
3,6864 MHz. Das ist jetzt nicht so wahnsinnig schnell. Die Karten sind
für 25 MHz ausgelegt.
Was willst Du denn eigentlich speichern? Muss das so schnell sein?
Viele Grüße
Daniel
Hey,
hab jetzt noch paar MMC Karten getestet, lassen sich so mit 77kB/s
beschreiben. Ich glaub ich werde nun nur MMC benutzen! Funktionieren
alle durchgehend gut.
Daniel R. schrieb:> Die werden schneller bei 100 Dateien?!?> Zeig mal den Benchmark Code !
Hab die benchmark angehängt.
Fand ich auch komisch. Dies tritt nur auf, wenn die Karte formatiert und
relativ alt ist. Sind da schon Daten drauf, schreibt sie durchgehend
konstant. Kann sein das die ersten Sektoren schon beschädigt sind!?
Hab mir jetzt mal ein größeren Controller bestellt. Wird mir hier
einbisschen eng auf dem Atmega88. Dann drehe ich auch die Frequenz auf
16MHz.
Daniel R. schrieb:> Was willst Du denn eigentlich speichern? Muss das so schnell sein?
Muss Strom und Spannung mit 2.5kS/s abtasten und ablegen. Desto
schneller ich speichern kann, desto weniger muss ich Puffern.
Bis dann und vielen Dank für den bereitgestellten Code!
Hallo,
das ist eine verkürzte Schreibweise für eine Abfrage. Wenn C=254 wird c
der Wert hinter dem Fragezeichenzugewiesen. Wenn nicht der Wert hinter
dem : Allerdings bin ich der Meinung, dass es am Ende :c++ heissen
müsste. Ich kenne das Programm nicht, aber das soll wohl eine
Zählvariable sein. Kann aber auch sein, dass sie woanders im Programm
verändert wird. Dann macht diese Art der Abfrage allerdings weniger
Sinn...
Gruß
Bad Urban
>Ich habe mal in der Quelltext geschaut, das müsste wirklich ":c++;">heißen.
Nö.
> ffwrite(c++);> c = c==254 ? 0 : c;
Fällt euch was auf?
Das ist eine kryptische Schreibweise für ein if{}else{}
Sowas gehört in kein C Programm.
Ok, das "ffwrite(c++);" hab ich übersehen. Mein Fehler.
Aber warum sollte ein "c = c==254 ? 0 : c;" nicht in ein c-Programm?
Vorallem die Begründung, daß es kryptisch sei halte ich für arg
schwammig. Ich denke, ich werde es zu meinem Standart für solche Fälle
erklären. Warum sollte ich das nicht dürfen?! Ich finds kurz und
prägnant.
Hey,
hab die defines auf mein CPU Takt angepasst!
Ansonsten, wie gesagt, kaum was an deiner Benchmark verändert.
#define TOP_OCR 0x7A
#define START_TCNT 0x06
#define PRESCALER 0x03
Bis dann!
Hallo,
also mein Timer Rechner sagt mit einer Frequenz von 7.3728 MHZ müssen
die Werte bei einem Überlauf von 1 ms:
1
#define TOP_OCR 0x72
2
#define START_TCNT 0x8D
3
#define PRESCALER 0x03
sein. Der Fehler ist dann 0.174%
Ich benutze dazu diesen Rechner:
http://www.b9.com/elect/avr/kavrcalc/index.html
welcher auch unter Linux mit Wine läuft.
Zur Not könnte man auch die Tick Zeit mal mit einem sleep vergleichen...
Viele Grüße
Daniel
Hey,
hab den Test noch mal mit den genaueren Werten durchgeführt. Fehlmessung
von ca. 1%. Also, danke noch mal für den Tipp!
Noch ne Frage!
Welche Karten (SD und MMC) akzeptieren MMC_MULTI_BLOCK? Hab bisher noch
keine gefunden.
Bis dann!
Hi,
ich benutze auch die Lib hier, hab aber ein Problem. Ich schreib alle 5
Minuten auf die Karte alle 5 Sekunden 2 Werte. Nach ungefaehr 2 Stunden
bricht das schreiben ab, weil entweder der Schreibvorgang hängenbleibt
oder die er beim öffnen der Datei hängen bleibt. Vielleicht einer eine
Idee, woran das liegen könnte? Die Schaltung wird über einen Lf33cf mit
3,3 v versorgt, also auch stabil. Hab mal die main angehangen, ist im
Grunde nur eine Erweiterung des beigefügten Beispiels im svn. Ach so µC
ist ein Atmeg644p.
Grüße Peter
Hallo,
sehe ich das richtig, dass der Atmeg644p 4k Ram hat? Weil eigentlich
würde ich auf Ram Probleme tippen.
Läuft das Programm ohne schreiben auf die SD Karte normal durch?
Versuch mal die Datei einfach geöffnet zu lassen.
Du legst nicht alle 5 Minuten eine neue Datei an oder?
Hab grad nicht die Zeit mir das Programm im Detail anzuschauen, mach ich
aber am Wochenende.
Viele Grüße
Daniel
Hi,
danke für die Antwort, jo der Atmega644p hat 4kb Ram, nur öffnen geht
über viele Stunden, hab es dann irgendwann einfach abgebrochen. Nein ich
öffne nur die existierende Datei immer wieder, schreib rein und
schliesse sie.
Ich teste jetzt erstmal ohne die Datei immer zu öffnen, ob das schreiben
dann über einen längeren Zeitraum funktioniert.
Mfg
Peter
Hallo,
also so nochmal auf die schnelle...
Bist Du Dir sicher, dass nur wirkliche Strings mit ffwrites geschrieben
werden? Wenn da irgendwo das '\0' fehlt geht das schief.
Grüße
Daniel
Hi!
Ich möchte mir einen Datenlogger mit SD bauen.
Gibt es da irgendwelche Beschränkungen?
Also wie groß darf die SD- Karte maximal sein und was für einen µC
braucht man mindestens?
Danke und Gruß
Tobias
>Ich möchte mir einen Datenlogger mit SD bauen.
Wofür?
>Gibt es da irgendwelche Beschränkungen?
Ja. 4GB pro Datei maximal bei FAT32.
Schreibzeiten beschissen wegen sporadischen Aussetzern von
bis zu 500ms. Es sei denn du hast einen Arsch voll RAM.
>Also wie groß darf die SD- Karte maximal sein und was für einen µC>braucht man mindestens?
FAT32 kann ein paar Terabyte.
ATmega mit mindestens 2kB Ram.
>>Ich möchte mir einen Datenlogger mit SD bauen.>> Wofür?
Für eine Wetterstation
>>Gibt es da irgendwelche Beschränkungen?>> Ja. 4GB pro Datei maximal bei FAT32.> Schreibzeiten beschissen wegen sporadischen Aussetzern von> bis zu 500ms. Es sei denn du hast einen Arsch voll RAM.>>>Also wie groß darf die SD- Karte maximal sein und was für einen µC>>braucht man mindestens?>> FAT32 kann ein paar Terabyte.> ATmega mit mindestens 2kB Ram.
Also wenn ich eine 4GB SD- Karte nehme und nen atmega644 mit 4k sram
müsste das kein problem sein oder?
Hi, ich nochmal,
also die Strings die mittels ffwrite geschrieben werden, sind alle mit
\0 terminiert. Hab es jetzt ohne ständiges öffnen uns schliessen
probiert. Brachte auch keinen Erfolg. Brauch nach circa 2h bei einem
ffwrites ab.
Vielleicht haste noch eine Idee woran es liegen koennte. Danke schon
mal.
Peter
Hallo.
@obi (Gast)
Nee das sollte kein Problem sein.
@Peter (Gast)
Hm, Du versuchst das nicht Batterie betrieben oder?
Beim schreiben zieht so eine Karte mal gut strom...
Über welche Datenmenge sprechen wir denn da bei den 2 Stunden?
Viele Grüße
Daniel
Hallo.
@Peter (Gast)
Bist Du da noch dran an dem Problem?
Nur der Vollständigkeit halber, wenn man viel Strom aus einer schwächer
werdenden Batterie zieht, bricht die Spannung ein -> Kontroller Reset...
Hi,
im Grunde schon, habs erstmal nen bisschen weiter nach hinten geschoben,
genug andere Arbeit. Ne ich betreib es mit einem Netzteil, und nen
lf33cv, der sollte eigentlich genug Strom liefern. Ich glaub
mittlerweile auch nicht mehr das es an der Lib liegt, sondern eher an
der Karte, SanDisk Extreme III, hab nur leider keine andere zur Hand.
Gruesse
Peter
Guten Abend,
erstmal: Absolut genial was hier für eine Lib entstanden ist. Da muss
man schon mal den Hut ziehen !
Ich hab allerdings noch ein Problem mit dem Schreiben. Lesen
funktioniert einwandfrei.
Wenn ich ein einzelnes Byte schreiben will (die Datei ist vorhanden und
in ihr war vorher auch nur ein Byte):
1
if(TRUE==fat_loadFatData()){
2
unsignedcharfile_name_offset[]="OFFS KOM";
3
if(MMC_FILE_EXISTS==ffopen(file_name_offset)){
4
ffwrite(0x99);
5
ffwrite(0x99);
6
ffclose();
7
}
8
}
muss ich, wie ihr seht, den Befehl dazu zwei Mal geben. Wenn das zweite
ffwrite auskommentiert ist, tut sich in der Datei gar nichts.
Das Anhängen an die Datei per vorgeschobenem
1
ffseek(file.length)
funktioniert weder mit einem noch mit zwei Befehlen.
Meine Config habe ich mal angehängt.
Bin über jeden Hinweis dankbar.
Grüße Paul
MoinMoin,
es wäre gut, wenn du mal einige Konstellationen von Defines in config.h
ausprobierst! Ich wollte gerade deine Lib mit "readonly" übersetzen und
bekam einige Fehler um die Ohren gehauen. Z.B., wenn man
#define MMC_WRITE FALSE
setzt, kommt:
/home/x/work/x/sd_card/file.c:626: undefined reference to
`fat_setClusterChain'
/home/x/work/x/sd_card/file.c:627: undefined reference to
`fat_getFreeClustersInRow'
Grüße & Danke Uwe
...Zusatz:
wenn man
#define MMC_LFN_SUPPORT FALSE
setzt, stürzt das Beispielprogramm beim Schreiben der Testdatei
reproduzierbar ab...
Du solltest wirklich mal dringenst ein Codereview machen!
Grüße Uwe
Hallo,
bin gerade etwas eng mit der Zeit die ich fürs Hobby zur Verfügung habe.
Das mit dem "readonly" Fehler ist reingekommen, weil ich da die defines
umgebaut hatte.
#define MMC_LFN_SUPPORT FALSE
Das schau ich mir morgen oder die Tage mal an. Glaub ich so nicht
richtig. Läuft bei mir nämlich in anderen Projekten problemlos.
Nur bei schnellen Prozessoren kann es Probleme mit den low level mmc
Funktionen geben hab ich bemerkt. Aber das sind dann auch keine AVR
mehr...
Grüße
Daniel
MoinMoin,
meine Testumgebung ist ein Mega168 mit 16MHz getaktet, also eigentlich
deine Default-Konfiguration...
Daniel R. schrieb:> #define MMC_LFN_SUPPORT FALSE> Das schau ich mir morgen oder die Tage mal an. Glaub ich so nicht> richtig. Läuft bei mir nämlich in anderen Projekten problemlos.>
Das Fehlerbild sieht wie folgt aus: es kommen genau zwei Zeilen des
Dateiinhaltes, auch wenn mehr drin steht.
Grüße Uwe
PS.: für mich wäre es wichtig, wenn die "readonly"-Geschichte
funktioniert. Ich könnte auch selbst am Code rummachen, aber habe keine
Berechtigung, das Zeugs wieder ins SVN zurück zu laden... Deshalb würde
ich es gerne dir überlassen!
MoinMoin,
ein weiterer Fehler:
file.c --> ffls() --> lsRowsOfClust()
Ein Dateiname ist mindestens 11 Zeichen lang. Du deklarierst temp als
Array mit 11 Byte und schreibst an die 11.Stelle eine \0, als
Stringende. Damit geht das letzte Zeichen des Dateinamen verloren...
Grüße Uwe
PS.: sorry, dass ich so penetrant bin. Ich wollte eigentlich deine Lib
zum Einlesen von Basic-Programmen
(http://www.mikrocontroller.net/articles/AVR_BASIC) von einer SD-Karte
benutzen, stolpere aber derzeit leider über die Fehler in der Lib.
MoinMoin,
...siehe
Beitrag "Re: Basic-Interpreter auf einem AVR"
Grüße Uwe
PS.: eine Funktion ffeof() wäre auch ganz nett...
PPS.: aber auch Lob für deine Lib, ich bin trotz einige Ungereimtheiten
relativ schnell zum Ziel gekommen!
Tach auch.
Zuerst einmal: Eine super Bibliothek, die auf Anhieb funktioniert hat.
Top!
Allerdings bin ich nun auf ein Problem gestoßen: Wenn ich eine Datei
(zum Lesen) öffne und sie von Anfang bis Ende mit ffread() auslese, ist
es mir danach nicht mehr möglich eine neue Datei zu öffnen. Egal ob ich
die datei schließe oder nicht. Waron könnte das liegen?
Gruß Sven
Hallo,
wie äußert sich das denn. Bleibt er beim öffnen hängen oder wie?
Versuch mal testweise die Karte vor dem erneuten öffnen neu zu
initialisieren. Wie sieht die config.h aus und die Initialisierung der
FAT/Karte?
Viele Grüße
Daniel
Moin Daniel. Wenn ich die SD-Karte und die FAT neu initialisiere,
funktionierts. Er hatte zuvor gemeldet, die Datei würde nicht
existieren.
An der Initialisierung der SD habe ich nichts geschraubt und so von dir
übernommen. Hier meine config.h:
// schalter die den funktionsumfang aendern bzw, den funktionsumfang einiger funktionen :)
20
#define MMC_WRITE FALSE // TRUE, dann mit write unterstuetzung, wenn FALSE dann read only !
21
#define MMC_OVER_WRITE FALSE // TRUE und MMC_WRITE TRUE, dann kann ffwrite dateien überschreiben, wenn FALSE dann nur normales schreiben. um an eine datei anzuhaengen ist MMC_OVER_WRITE TRUE nicht noetig!
22
#define MMC_MULTI_BLOCK FALSE // TRUE und MMC_OVER_WRITE FALSE, dann werden multiblock schreib/lese funktionen benutzt. ist schneller, wird aber möglicherweise nicht von allen karten unterstützt. wenn FALSE ist normale operation
23
#define MMC_SDHC_SUPPORT FALSE // TRUE, dann mit sdhc unterstuetzung, wenn FALSE, dann nur mmc/sd karten. siehe : http://de.wikipedia.org/wiki/SD_Memory_Card#SDHC_.28SD_2.0.29
24
#define MMC_ENDIANNESS_LITTLE TRUE // TRUE, dann ist der code auf littleendian ausgelegt. AVR ist littleendian. code ist auf littleendian optimiert!! siehe: http://de.wikipedia.org/wiki/Endianness
25
#define MMC_LFN_SUPPORT TRUE // TRUE, dann mit unterstuetzung fuer lange dateinamen. kostet wenn read und write benutzt wird um die 800 bytes flash...
26
#define MMC_RM_FILES_ONLY TRUE // TRUE ,MMC_WRITE TRUE und MMC_RM TRUE, dann wird die funktion ffrm so mit kompiliert, dass sie nur dateien loeschen kann. wenn FALSE und MMC_WRITE TRUE, dann kann die funktion dateien und ordner rekursiv loeschen !
27
28
// schalter die explizit funktionen mit kompilieren oder nicht!
29
#define MMC_TIME_STAMP FALSE // TRUE, dann werden die funktionen fat_getTime und fat_getFreeBytes mit kompiliert. siehe auch abschnitt: ZEIT FUNKTIONEN, weiter unten
30
#define MMC_RM FALSE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffrm mit kompiliert.
31
#define MMC_SEEK TRUE // TRUE,dann wird die funktion ffseek mit kompiliert. mit dieser funktion kann man in einer geoeffneten datei vor und zurueck spulen. nur in kombination mit MMC_OVER_WRITE TRUE kann in einer datei ueberschrieben werden.
32
#define MMC_MKDIR FALSE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffmkdir mit kompiliert. mit dieser funktion kann man ordner anlegen.
33
#define MMC_GET_FREE_BYTES TRUE // TRUE, dann wird die funkton fat_getFreeBytes mit kompiliert. mit dieser funktion kann der freie platzt auf der karte ermittelt werden
34
#define MMC_LS TRUE // TRUE, dann wird die funktion ffls mit kompiliert. mit dieser funkion kann man die dateien auf der karte anzeigen lassen
35
#define MMC_CD TRUE // TRUE, dann werden die funktionen ffcd und ffcdLower mit kompiliert. mit diesen funktionen kann man in ein verzeichnis wechseln oder aus einem verzeichnis ein verzeichnis hoeher wechseln.
36
#define MMC_FILE_EXSISTS TRUE // TRUE, dann wird die funktion ffileExsists mit kompiliert. mit dieser funktion kann geprueft werden, ob es die datei im aktuellen verzeinis gibt !
37
#define MMC_WRITE_STRING TRUE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffwrites mit kompiliert. mit dieser funktion koennen strings auf die karte geschrieben werden.
38
39
// vorsicht, da die variable die die sektoren zählt ein short ist (MMC_MAX_CLUSTERS_IN_ROW*fat.secPerClust) !!
40
#define MMC_MAX_CLUSTERS_IN_ROW 256 // gibt an wie viele cluster am stück ohne fat-lookup geschrieben bzw gelesen werden können, wenn die fat nicht fragmentiert ist !
41
42
// wenn "#define INLINE inline" dann werden die statischen funktionen inline kompiliert. macht code groeßer, aber auch schneller!
Paul P. schrieb:> Das Anhängen an die Datei per vorgeschobenem ffseek(file.length) funktioniert
weder mit einem noch mit zwei Befehlen.
dito bei mir!!!
Hallo.
Leider habe ich momentan keine Zeit wegen dem blöden Weihnachten.
Werde aber kommende Woche dazu kommen mir das alles anzuschauen und die
Probleme zu beheben.
Viele Grüße
Daniel
docean schrieb:> Version 0.5.9 tut!
Interessant, ich habe aber in der zwischenzeit schon einen Workaround
gefunden. Mit der Funktion ffwrites() läuft es weil fat.bufferDirty =
TRUE gesetzt wird. Als habe ich mir eine kleine Funktion hingepfuscht
die das auch nach dem normalen ffwrite() erledigt. Aber mir schwant es
schon, so elegant ist das nicht ;)
Vielleicht hilft es ja bei der Fehlersuche. Schönen Feiertag noch
Hallo Daniel,
mir ist etwas merkwürdiges aufgefallen:
Ich schreibe zuerst 10kB in die Datei. Dann schließe ich sie, öffne sie
erneut und hänge nochmal 10kB hintendran.
Win XP zeigt dann auch den richtigen Inhalt mit 20kB an. Wenn ich chkdsk
laufen lasse werden aber Fehler korrigiert und die Datei hat danach
24kB!
Mega32 @ 8MHz, 5V
Guten Rutsch!
Mfg,
Kurt
Hallo Daniel,
zunächst vielen Dank für die tolle Arbeit.
Ich habe eine ganzen Tag gebraucht, um meine alten 16MB-SD-Karten zum
Laufen zu bringen.
Problem war offensichtlich, dass Windows 16MB-Karten nur mit FAT12
formatiert und diese FAT12 dann beim Schreiben durch den AVR zerstört
wird.
Wenn man in der Console dagegen "format x: /a:2048" verwendet, wird auch
die 16MB-Karte in FAT16 formatiert und nun funktioniert alles. Ein
Hinweis darauf in der Doku wäre nicht schlecht.
Oder vielleicht beim Initialisieren prüfen, ob da auf der Karte
überhaupt eine nutzbare FAT16 oder FAT32 drauf ist, bevor man da was
kaputtschreibt.
Eine andere Frage:
Vermutlich gibt es keine Möglichkeit, die 512Bytes RAM für den
Sektorbuffer irgendwie zu reduzieren?
Mein ATMEGA16 ist da zusammen mit anderen Programmteilen schon extrem
voll und ich hab da ein bissel Angst vor einem Stack Overflow, bei dem
ich dann ewig den Bug suche.
Michael
Michael R. schrieb:> Vermutlich gibt es keine Möglichkeit, die 512Bytes RAM für den> Sektorbuffer irgendwie zu reduzieren?
Bei Flash-Speichern müssen immer 512Byte auf einmal geschrieben werden.
Wenn man alles auf einen Rutsch schreiben will, braucht man eben diesen
Speicher.
Du hast jetzt 2 Möglichkeiten.
Entweder du optimierst den Speicherverbrauch, oder du steigst auf einen
ATmega32 um.
Hallo Daniel,
Ich habe hier auch noch ein seltsames Problem bezüglich Anhängen.
Wenn der AVR frisch startet und an eine bestehende Datei anhängen soll,
dann geht das schief. file.length gibt bei jedem neuen Öffnungsversuch
immer wieder den gleichen Wert zurück, obwohl ich zwischendurch bei
geöffneter Datei mit ffwrites was angehängt habe.
Also folgende Reihenfolge:
-Init-CARD/FAT
-ffopen
-ffseek(file.length) (falls MMC_FILE_EXISTS zurückkommt)
-ffwrites
-ffclose
-Init-CARD/FAT (Ich mach das jedes Mal, zur Sicherheit)
-ffopen
-ffseek(file.length)
-ffclose
Beim zweiten ffseek wird genau das gleich zurückgeliefert, wie beim
ersten ffseek. Die Datei wird einfach nicht größer
Wenn die Datei dagegen frisch angelegt wird, scheint das Verlängern
beliebig häufig zu klappen, bis ich den AVR neu starte, dann geht es
wieder nicht.
Also eine bereits vor AVR-Boot bestehende Datei wird nicht mehr
verlängert, eine gerade selbst angelegte Datei lässt sich immer
verlängern.
Die 16MB-Karte Karte ist so formatiert(chkdsk-Ausgabe):
14,1 MB Speicherplatz auf dem Datenträger insgesamt.
14,1 MB sind verfügbar.
2.048 Bytes in jeder Zuordnungseinheit
7.241 Zuordnungseinheiten auf dem Datenträger verfügbar
16 Bits in jedem FAT-Datensatz.
Irgendwie sieht das so aus, als wird irgendwas nicht richtig
initialisiert.
Michael
Zu dem Anhängen-Problem:
Ich habe mal ein bisschen weiter gewühlt:
Beim Anhängen werden die Daten richtig auf die Karte geschrieben und
sind mit einem Hex-Editor auffindbar. Ändert man mit dem Hex-Editor die
Dateigröße, dann werden die geschriebenen Daten auch für das normale
Windows Notepad sichtbar.
Beim Schließen der Datei wird scheinbar der FAT-Eintrag nicht richtig
aktualisiert. Mindestens die Dateigröße wird falsch geschrieben.
Ich habe zwar die Funktionsaufrufe beim flush bis runter zum
mmc_write_sector( fat.currentSectorNr,fat.sector );
nachvollzogen, konnte aber nicht rausfinden, warum die Dateigröße nicht
oder nicht richtig geschrieben wird. (Habe keinen Debugger, ist sehr
mühsam).
Michael
Soo,
noch ein Stück weiter:
Wenn der AVR die Datei in der aktuellen Sitzung nicht selbst erstellt
hat,
dann enthält "fat.currentSectorNr" beim Aufruf von "fat_loadSector "in
der "fflushFileData" immer 0.
fflushFileData:
1
// dafuer sorgen, dass der sektor mit dem geaenderten dateieintrag geschrieben wird, beim neuladen. datensektor der datei neuladen, falls noch weitere bytes geschrieben werden.
2
fat.bufferDirty=TRUE;
3
fat_loadSector(save_currentSectorNr);
Das führt dazu, dass "fat_loadSector" versucht, die aktuellen Daten nach
Sektor 0 zu speichern:
1
mmc_write_sector(fat.currentSectorNr,fat.sector);// schreiben von sektor puffer
Glücklicherweise geht das wohl irgendwie schief und dem Bootsektor
passiert dadurch offenbar nichts.
Warum "fat.currentSectorNr" nicht die Sektornummer des FAT-Eintrags hat,
kann ich aber nicht mehr nachvollziehen, das wird mir dann zu
unübersichtlich.
Michael
Hallo zusammen,
bei meiner SanDisk SD 2GB 2 tut es leider nicht.
Genaueres:
Bei meiner alten Karte(SanDisk Extreme III) hat es noch getan. Leider
ist diese abgeraucht. Ich habe mir dann die oben gesagte gekauft. Init
läuft durch. Jedoch beim Lesen des 1. Sector gibt es dann einen Zonk.
Unter Windows tut die Karte (FAT32).Im Anhang ist ein Log.
Ich werde mal sehe ob ich noch was rausfinde. Leider habe ich keine 2
Karte zum gegentesten.
Teste gerade die Lib mit verschiedenen Karten.
Bis jetzt funktionieren:
- Sandisk Sd-Card 2 GB
- Kingston SD-Card 256 MB
- Hama SD-Card 256 MB
- Sandisk Mikro-SD 2GB
- Sandisk Mobile Ultra Micro-SDHC 4GB
Mit Verzeichnisse anlegen habe ich noch nichts gemacht. Mir ging es erst
einmal um das Speichern und Lesen von Daten.
Gruß Gerd
Moin,
Meine MMC/SD Ansteuerung verhält sich sehr komisch...
Mit einem AtMega16/8MHz hat es mit einer 4GB/SDHC plötzlich funktioniert
(ein Datenloggen über zwei Stunden ohne Probleme), nachdem ich den LFS
eingeschaltet hatte...
Wegen zu wenig Speicher hab ich den ATMega16 gegen den pinkompatiblen
Atmega32 getauscht. Leider habe ich zwischenduch den Code mal etwas (was
auch immer) modifiziert...
Nach drei Abenden werd ich wohl jetzt frustriert aufgeben:
* mmc_init und load_fat funktionieren
Öffne ich ne Datei in meinem Code mit ffopen ohne was anderes zu tun,
zeigt mein PC die Datei mit 0 Byte an, gut so.
Öffne ich die Datei und schließe sie direkt wieder mit ffclose, dann
gibt es keine Datei, aber der PC kann die Karte noch lesen.
Öffne ich die Datei und schreibe ich etwas mit ffwrites wird die FAT
zerschossen. Egal ob mit oder ohne ffclose.
SPI wird nicht hochgesetzt, ich versorge die Karte mit 3.3V aus einem
Labornetzteil, der ATMega arbeitet allerdings auf 5V mit
Spannungsteilern.
Ich hab mit nem Scope die Signale nachgemessen, alle da und für die
Geschwindigkeit ausreichende Signalintegrität.
Eine andere Karte 2GB/SD läuft gar nicht.
Gruß ka-long
Hallo,
ka-long schrieb:> Ich hab mit nem Scope die Signale nachgemessen, alle da und für die> Geschwindigkeit ausreichende Signalintegrität.
insbesondere die Clock-Flanken bei SPI sind extrem kritisch. Wenn man
keinen integrierten Pegelwandler verwenden möchte, kann man auch einen
kapazitiven Spannungsteiler parallel zum normalen Spannungsteiler
schalten. Folgende Kombinationen sollten funktionieren:
Oberer Kondensator | unterer Kondensator
22p | 12p
27p | 15p
33p | 18p
39p | 22p
47p | 27p
56p | 33p
Wenn ein Tastkopf dranhängt stimmt das Verhältnis wegen der
Tastkopfkapazität aber nicht mehr. Man sieht also nicht mehr das
gleiche, wie die Karte ohne Tastkopf sieht. Man muss sich auf die
Mathematik verlassen.
Michael
Hallo Michael,
Sind die Anstiegs- und Fallzeiten denn irgendwo definiert ?
Ich werd mal auf mmc-lib Sektor-Ebene Daten lesen und schreiben und
schauen, ob es da zu Fehlern kommt oder obs in einer der höheren
Schichten passiert.
So kann ich vielleicht die HW als Ursache ausschließen...
Gruß ka-long
ka-long schrieb:> Sind die Anstiegs- und Fallzeiten denn irgendwo definiert ?
Wenn Du eine matschige CLK-Flanke hast und da noch Rauschen oder
sonstige Spikes drauf sind, kann es passieren, dass der Empfänger 2
Flanken kurz nacheinander sieht und dann auch 2 Bits einliest, obwohl
nur eine Flanke gesendet wurde. In wie weit Doppelflanken unterdrückt
werden, steht vielleicht im Datenblatt der Karte. Wenn die Karte aber
z.B. 50MHz SPI unterstützt, dann muss sie Flanken im Abstand 10ns
erkennen können. Wenn Deine Anstiegszeit aber z.B.100ns ist, dann hält
sich der Pegel doch einige Zeit im kritischen Bereich auf und kann eine
Doppelflanke auslösen, wenn Rauschen/Spikes überlagert ist.
Vernünftig entwickelte Clk-Eingänge haben Schmitt-Trigger-Eingänge und
intelligente digitale Filter drin, die das Problem entschärfen. Aber
gerade das ist wohl selten spezifiziert.
Die Flankensteilheit der Datenleitungen ist dagegen weniger kritisch,
der Pegel muss nur zum Zeitpunkt der jeweiligen CLK-Flanke eindeutig
high oder low sein.
Michael
Hallo,
erstmal Danke für die gute Arbeit. Ich teste seit ein paar Tagen die
Version 0.6.1 mit einem mega644. Leider läuft die main_simple.c nur dann
durch, wenn ich den µC resete.
Schaltet man VCC aus und wieder ein bleibt das Programm in der
fat_loadFatData(); hängen und zwar beim ersten Aufruf von
loop_until_bit_is_set(SPSR,SPIF);" in der mmc_write_byte Funktion
(mmc.c).
Was ich schon getestet habe:
- Verzögerung mit _delay_ms --> ohne Erfolg
- Verschiedene 1 GB sd-Karten --> ohne Erfolg
- Brummspannung auf VCC < 20 mV (Die ganze Schaltung inkl. µC läuft mit
3,3 V)
Ich glaube nicht, dass es ein Hardwareproblem ist.
Komisch ist, dass vor "fat_loadFatData();" noch die mmc_init();
problemlos aufgerufen wird, ohne das das Programm in mmc_write_byte fest
hängt?!
Vielleicht könnt Ihr mir einen Tipp geben, was ich noch versuchen kann,
damit die main_simple.c direkt durchläuft.
Danke.
Gruß
Andi
Hallo zusammen,
ich bin da gerade immer mal wenn ich etwas Zeit habe dran am arbeiten.
Ich habe jetzt einen stm32 mit jtag Debugger, damit arbeitet sich
wesentlich leichter als mit einem avr und Debug Ausgaben über die
Konsole :)
Was wohl auf jeden Fall geändert werden wird, sind die Delay schleifen
in der mmc.c, die werden auf einen Timer umgestellt werden müssen.
Die Initialisierung der Karten wird auch geändert sowie der Ablauf von
den schreibe und lese Funktionen. Also quasi der ganze Unterbau wird
geändert. Zudem noch die Datei öffnen Funktion.
Bitte um etwas Geduld...habe bald Semesterferien, die letzten :) da wird
das wohl spätestens was werden....
Viele Grüße
Daniel
Hallo Daniel,
wenn Du das Timing auf einen Timer umstellst, wird das Einbinden in
verschiedene andere Projekte deutlich schwerer oder unmöglich. Ich habe
Deine lib in einem Projekt drin, in dem keine Timer mehr verfügbar sind.
Super wäre es, erstmal eine stabile weitgehend bugfreie Version zu
schaffen, denn derzeit ist das definitiv nicht der Fall.
Ansonsten finde ich Deine Arbeit echt super, eine Lib, die wenig
Resourcen braucht und einfach einzubinden ist.
Michael
Hallo.
>wenn Du das Timing auf einen Timer umstellst
Genau da ist beispielsweise einer der Bugs. So eine Karte genehmigt sich
schon mal bis zu 200 ms um Daten zu speichern oder um einen Block zu
lesen. Da rasselt man dann einfach aus den warte Schleifen raus,
zumindest so wie die momentan sind.
Ich hab mir das so vorgestellt, dass man einfach eine bestimmte Funktion
im 10 ms Takt aufrufen muss.
Im Beispielcode würde ich dann ein Timer Beispiel machen, wie das dann
letztendlich in einem eigenen Projekt umgesetzt wird muss dann jeder
selber schauen...
Grüße
Daniel
Hallo Daniel,
ich meinte den z.B. den Bug, dass die FAT beim Anhängen nicht richtig
geschrieben wird.
Ansonsten hat Dein Ansatz mit den Timern definitiv Vorteile, da der
Controller in den Warteschleifen nicht blockiert wird.
Du baust also keine Timerfunktionen direkt in die Lib ein sondern
erwartest ein Pollen Deiner Funktionen?
Michael
Hallo,
ich hätte mal eine Frage zur "Superfloppy"-Erkennung. Mit meiner frisch
gekauften 2GB-SD-Karte lief das AVR-FAT-Paket auf meinem Pollin net-io
mit SD-Addon zunächst tadellos. Diese SD-Karte hatte in Sektor 0 einen
MBR mit Partitionstabelle. Nun habe ich die SD-Karte in meinem
Windowsrechner neu mit FAT32 formattiert. Dadurch verschwand der MBR und
die neue Partition beginnt nun ohne Umwege direkt in Sektor 0, die Karte
hat also "Superfloppy"-Format. Wenn ich es richtig verstanden habe,
untersucht die AVR-FAT-Software den Boot-Code der Partition auf die
Zeichenkette "medi", die an der Stelle erwartet wird, wo sonst die
Anfangsadresse der 1.Partition steht. Dies funktioniert bei mir nicht.
Die Zeichenkette "medi" ist um 2 Bytes versetzt, wodurch die
Superfloppy-Erkennung scheitert und alles weitere natürlich auch. Habe
das Debugger-Listing angehängt, in dem der Versatz zu erkennen ist. Habe
ich irgendetwas nicht richtig beachtet ?
Vielen Dank für Tipps
recently
Hallo,
ich bin dazu gekommen mal ein wenig an der Lib zu arbeiten.
Als Anhang mal die frischen Dateien.
Es gibt einige Änderungen.
In der mmc.c ist aufgrund der Portierbarkeit ein eigener SPI Teil dazu
gekommen. Zum anpassen an andere Plattformen müssen jetzt nur noch die
Funktionen,
spi_init
spi_maxSpeed
spi_write_byte
spi_read_byte
und die defines,
#define MMC_CS_LOW GPIO_ResetBits(GPIOA, GPIO_Pin_4)
#define MMC_CS_HIGH GPIO_SetBits(GPIOA, GPIO_Pin_4)
angepasst werden.
Auch in der mmc.c geändert:
Die Initialisierung der SD/MMC Karten.
Die Bestimmung ob Superfloppy oder nicht.
Zeit gesteuerte delay Schleifen beim lesen/schreiben, wegen der Totzeit
der Karten bei diesen Operationen.
Ganz wichtig! Es muss irgendwo eine globale Variable
1
volatileunsignedcharTimingDelay;
geben, die in 10 ms Intervallen bis 0 runtergezählt wird!
In der file.c hat sich ffopen geändert.
Es wird jetzt nicht mehr einfach die Datei angelegt wenn sie noch nicht
vorhanden war. Hat oft zu Verwirrung geführt.
ffopen(name,'r') öffnet die Datei falls vorhanden und gibt
MMC_FILE_OPENED zurück. Oder aber MMC_NOTHING_DONE.
ffopen(name,'c') legt eine Datei an falls es die Datei noch nicht gibt
und gibt MMC_FILE_CREATED zurück. Oder aber MMC_NOTHING_DONE wenn es die
Datei schon gab...
In der fat.c hat sich das suchen nach Dateinamen geändert. Bei kurzen
Dateinamen wird von PC Betriebssystemen manchmal nur ein SFN angelegt.
Das ist jetzt in der Lib angepasst.
Es wird demnächst noch weiter gehen...
Grüße
Daniel
Mit den neuen Modulen ist bei mir nichts mehr compilierbar ... schade,
ob das jetzt wirklich ein Gewinn war ?
Gibt es denn dazu auch eine passendes "main_simple", das nach diesem
Totalaustausch der Quellen noch läuft ? Das man es wenigstens mal
ausprobieren kann ?
Hallo Daniel,
vielen Dank für die neue Version. Die Superfloppy-Erkennung sieht gut
aus. Gibt es denn auch eine AVR-Version ? Die Version im fix-zip-file
scheint für STM32-Hardware ausgelegt ?
Viele Grüße
recently
Hallo,
jetzt sollten alle Fehler behoben sein.
Hier schonmal die STM32 Version. Bisher nur mit lfn Option getestet...
Die AVR Variante braucht noch etwas Zeit,
sollte aber auch relativ einfach aus der SMT32 Version zu portieren
sein.
Viele Grüße
Daniel
Hallo Daniel,
ich beschäftige mich gerade intensiv mit dem AVR-FAT-Code und habe eine
Frage zum Element file.dir : Das Element wird in der Funktion
fat_loadFatData einmal auf 0 gesetzt und dann an verschiedenen Stellen
der Software auf 0 geprüft ... was ist die Bedeutung dieses Elements ?
Hallo,
da wird der 1. Cluster des aktuellen Verzeichnisses gespeichert. Damit
man weiß in welchem Ordner man sich befindet.
Wird nur durch ffcd() und ffcdLower() geändert. Mit ffcd() wechselt man
in ein Verzeichnis und mit ffcdLower() geht man ein Verzeichnis höher
(auch als "cd.." bekannt).
Viele Grüße
Daniel
PS: Die AVR Version ist soweit. Bin nur noch ausgiebig am testen.
Hallo zusammen,
hier jetzt mal die fertigen Sachen.
Es wäre super, wenn ein paar Leute mittesten könnten.
Es gab eigentlich nur einen Bug, den ich selber eingebaut hatte von
0.5.9 auf 0.6.1, dummerweise...
Der ist jetzt weg und es gibt neue Features...
Viele Grüße
Daniel
Hallo Daniel,
mit meinem ATMega32 (der NetIO von Pollin) mit 18.432 MHz bekomme ich
Schwierigkeiten beim compilieren ... Die Taktfrequenz wird im Header
nicht angeboten und weiterhin hat der Mega32 auch kein "TCCR0A" ...
Viele Grüße
recently
Hm, dann musst Du den Timer per Hand einstellen.
Die Timer ISR muss alle 10ms aufgerufen werden.
Für den mega32 werde ich das aber wohl auch noch einbauen...
Grüße
Daniel
Hallo,
ich werde deine Version auch testen.
Ich wollte mal fragen warum du überall "unsigned char var[]" als
Parameter nutzt.
Könnte man da nicht "char *var" nehmen dann muss man nicht immer rum
casten wenn man Standard lib Funktionen nutzt.
Also statt:
extern unsigned char ffopen( unsigned char name[], unsigned char
rw_flag);
ein:
int8_t ffopen(char *name, uint8_t rw_flag);
Vielen dank das du das hier veröffentlicht hast, wie gesagt soll nur ein
Vorschlag sein.
Servus,
Daniel R. schrieb:> Es wäre super, wenn ein paar Leute mittesten könnten.
hab mich mal mit der neuen Version beschäftigt.
Bis jetzt war ich begeistert- aber nun macht es doch erhebliche
Probleme. Insbesondere mit einem neuen Prozessor.
Die Timer-Geschichte mag zwar funktionieren ist aber gegen der
vorherigen Version komplizierter geworden.
Mit den #If, #else, #endif verliert man total die Übersicht.
Trotz alledem bin ich über Deine Vorgängerversion froh, die funktioniert
ohne Probleme auf allen Atmegas/Atxmegas.
Gruß XMEGA
Hallo,
bei der Timer Version ist das einzige komplizierte, dass es eine ISR
geben muss die alle 10ms aufgerufen wird und in der
1
TimingDelay=(TimingDelay==0)?0:TimingDelay-1;
seht.
Sonst hat sich alles nur zum Vorteil geändert.
Besonders bei sfn (short file names) ist es doch wesentlich bequemer
1
unsignedcharfile[]="test.txt";
zu schreiben als
1
unsignedcharfile[]="TEST TXT";
Aber gut, zu dem Timer Punkt werde ich mir etwas überlegen. Vielleicht
hat ja jemand eine Idee, wie man aus F_CPU und ein paar Assembler
Befehlen auch so etwas hinbekommen kann wie gezieltes warten von maximal
200 ms.
Wenn man eclipse als IDE benutze, kann man die #if die nicht benutzt
werden ausblenden lassen, oder sie grau hinterlegen lassen, das ist sehr
übersichtlich.
char * mag ich nicht als Standard Typ verwenden, weil das signed ist und
somit im 2er Komplement. Das ist nicht so Ressourcen schonend...
Viele Grüße
Daniel
Daniel R. schrieb:> char * mag ich nicht als Standard Typ verwenden, weil das signed ist und> somit im 2er Komplement. Das ist nicht so Ressourcen schonend...
Aha, ok wenn du meinst, für String Bearbeitung macht das zwar keinen
unterschied aber nun ja...
Für den Timer währe es sinnvoll wenn man per define einstellen könnte
alle wie viel ms die Zähler runtergezählt wird, so könnte man eine
Bestehende Timer Funktion verwenden.
Den Code versteh ich nicht...
Wie ist das gemeint?
Man kann doch bestehende Timer einfach mitbenutzen... es muss halt nur
TimingDelay im 10ms Takt um 1 runter gezählt werden, bis auf 0.
Um mehr muss man sich nicht kümmern.
Daniel R. schrieb:> es muss halt nur> TimingDelay im 10ms Takt um 1 runter gezählt werden
Und das ist der Punkt. wenn deine Timer mit z.B. 15ms oder 5ms laufen
kannst du sie nicht so einfach benutzen.
Bzw. musst du selber im Timer schauen das du z.B (5ms) nur jedes zweite
mal dekrementierst oder (15ms) jedes zweite mal doppelt dekrementieren
musst.
Ok, ich dachte ja nur, dass ich ein Beispiel der Benutzung gebe.
>..wenn deine Timer mit z.B. 15ms oder 5ms laufen>kannst du sie nicht so einfach benutzen...
Wenn man das dann in ein Projekt einbaut, muss man sich genau um solche
Dinge ja Gedanken machen und ändern.
Mit der Anweisung:
Decrementiere TimingDelay im 10ms Takt um 1, bis auf 0, sollte man ja
klar kommen können.
Man kann aber auch einfach TimingDelay nach 200ms auf 0 setzten und gut
ist. Die Idee ist halt, mindestens 200ms auf die Karten zu warten.
Ich Persönlich würde ja eine Lösung ganz ohne Timer auch besser finden,
hab aber noch nicht die zündende Idee wie man das schön machen könnte.
Hallo,
Allgemeine Frage:
Funktioniert der Code mit MMCplus Karten?
Bekomme nämlich Transcend MMCplus Karten (1GB & 2 GB) nicht ans laufen!
Die Karte kann nicht initialisiert werden. Andere Karten funktionieren!
mfg
Hallo,
ist MMCplus der Standard 3.0 ? Das sollte nämlich gehen.
Wobei ich mehrmals Probleme hatte ist, wenn der MISO Pin keinen Pullup
hat. Das geht mit alten Karten meistens noch, aber mit neuen nicht mehr.
Den Initialisierungs Kram hab ich bei anderen abgeschaut, und nur noch
mal mit den Specs verglichen...
>Man kann aber auch einfach TimingDelay>nach 200ms auf 0 setzten..
Muss ich mir selber etwas widersprechen, ist nämlich einmal nach 200ms
und beim Initialisieren der Karten 1000ms...
Viele Grüße
Daniel
Leider funktioniert trotz MISO PullUP nur eine der 3 Karten. Mit der
0.5.9C hatten die alle funktioniert.
Schade dass ich keine Zeit zur Fehlersuche habe.
Aber jetzt was positives: Die Performance scheint besser geworden zu
sein. Statt 60kB/s sind es nun 80kB/s auf einem Mega32 mit 18,432Mhz.
Mfg,
Kurt
Hallo,
>..0.5.9 hatten die alle funktioniert..
das blöde ist das ich keine Karte habe mit der es nicht klappt, daher
ist das Fehlersuchen nicht möglich.
80kB/s ist aber trotzdem sehr langsam. Benutzt Du software SPI?
Mit 18,432Mhz Quarz und hardware SPI müsste das eine sehr langsame Karte
sein.
Ich hab hier SD Karten die mit 16Mhz 170kB/s machen. Auch welche mit
über 200kB/s...
Alles schreibend, lesend noch schneller...
Außerdem ist an den schreib Routinen eigentlich nichts geändert.
Viele Grüße
Daniel
Nein, ich nutze Hardware SPI.
Wahrscheinlich liegt die geringe Geschwindigkeit daran dass ich immer
nur ein einzelnes Byte schreibe?
Falls sonst niemand Probleme mit den SD Cards hat, habe ich wohl einen
Fehler eingebaut der so offensichtlich ist dass ich ihn immer übersehe.
;-)
Mfg,
Kurt
@ Kurt Bohnen (kurt)
Also wenn Du normal mit ffwrite() schreibst, puffert die Lib eh 512
Bytes zwischen. Da sollte das Problem nicht liegen.
Ach ja, wenn überschreiben an ist, ist das schreiben etwas langsamer...
@ little_man (Gast)
Ja stimmt, ist 4.x, wenn Du da eine Spezifikation findest, schau ich mir
das mal an und setzt das dann um...
Viele Grüße
Daniel
Daniel R. schrieb:> Ich hab hier SD Karten die mit 16Mhz 170kB/s machen. Auch welche mit> über 200kB/s...
Hallo Daniel,
kannst du ein paar Namen nennen?
Mfg,
Kurt
Hallo zusammen
Erstmal vielen Dank fuer die tolle Library. Bin ziemlich neu in der Welt
von uC. Trotzdem habe ich es geschaft dank der Library auf die SD-Karte
zu speichern. Das spricht wohl fuer sich. (super super Sache das)
Ein Problem habe ich aber noch.
1
ffseek(file.length);
Dauert am Anfang ca. 5ms 30min. spaeter 28ms (Datei ist dann 2.85MB
gross)
Habe weiter oben beim Eintrag vom 17.9.2010 gesehen das ffseek nicht
durchgefuehrt werden muesste wenn File nicht geschlossen wird.
Funktioniert bei mir aber leider nicht. (Auf dem SPI-Bus sind noch
andere Teilnehmer. Sollte aber doch nichts ausmachen)
Um meine Frage kurz zu fassen: Wie kann ich die Zeit zum spulen
verkuerzen?
(Sollte doch moeglich sein file.length zu merken aber wie?)
Vielen Dank
@ Kurt Bohnen (kurt)
Muss ich mal nachschauen, bin grad nicht zuhause.
@ Markus K. (Gast)
Schließt Du die Datei beim schreiben immer oder wieso das ffseek?
Du könntest alternativ ein fflush machen anstelle von schließen...
Zeig doch mal ein bisschen code
Viele Grüße
Daniel
Ja ich schliesse sie nach jedem anhaengen wieder. Hab auch mal versucht
sie offen zu lassen doch dann stimmten die Eintraege nicht mehr. Ich
haenge alle 200ms ein paar Daten an.(sollte so eine xml Datei entstehen)
Verstehe ich das richtig:
fflushFileData(); anstelle von ffclose();
und dann kein ffopen(filename); mehr oder?
Vielen Dank.
Ja genau.
>Hab auch mal versucht sie offen zu lassen>doch dann stimmten die Eintraege nicht mehr.
Das müsstest Du mal genauer erklären, bzw zeigen, wie Du die lib
benutzt.
Viele Grüße
Sorry war mein Fehler hab wohl irgendwo im Code vergessen ffclose oder
ffopen auszukommentieren.
Nun funktioniert es mit dem geoeffnet halten der Datei.
Sorry
Nochmals Vielen Dank fuer deine tolle Library
Hallo Daniel.
Danke erstmal für die Lib, grad die Fat Funktionen sind super und Fat32
geht auch einwandfrei.
Ich habe aber immer wieder mit der Karteninitialisierung Probleme.
Kleine Karten < 1GB gingen vom Start weg aber die grossen, bei denen man
im Init in den SDv2-Block läuft machten Probleme.
Ausserdem habe ich einige Karten gehabt, die nicht sofort auf CMD0
reagiert haben. Und auch auf CMD16 reagieren manche nicht sofort.
Hierfür habe ich jeweils eine Schleife eingefügt.
Ich habe die Init-Fuktion etwas angepasst:
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
ty=CT_SD2|CT_BLOCK;
31
}
32
}else{// SDv1 or MMCv3
33
if(mmc_send_cmd(ACMD41,0)<=1){
34
ty=CT_SD1;
35
cmd=ACMD41;// SDv1
36
}else{
37
ty=CT_MMC;
38
cmd=CMD1;// MMCv3
39
}
40
while(TimingDelay&&mmc_send_cmd(cmd,0));// Wait for leaving idle state
41
}
42
while(TimingDelay&&(mmc_send_cmd(CMD16,512)!=0));
43
if(!TimingDelay)ty=0;
44
}else{j--;}
45
}while(j>0);
46
fat.card_type=ty;
47
mmc_disable();
48
49
if(fat.card_type==0){
50
returnFALSE;
51
}
52
#if (MMC_MAX_SPEED==TRUE)
53
spi_maxSpeed();
54
#endif
55
56
returnTRUE;
57
}
Um SDHC-Karte überhaupt zum laufen zu bewegen (besonders eine
8GB-MicroSD) musste ich die ACMD41-Schleife noch um das vorherige Senden
von CMD55 erweitern, so wie es in der Spec auch gefordert wird.
Die Abfrage auf CMD58 habe ich raus genommen, da diese von keiner meiner
Karten anders als mit 05 (Illigal Command) beantwortet wird.
Bei meinen SDHC Karten mit 4 und 8GB hat das mit
1
ty=CT_SD2|CT_BLOCK;
ganz gut funktioniert, aber jetzt habe ich eine extrememory 2GB bei der
er auch in den SDv2-Block läuft die nur mit
1
ty=CT_SD2;
läuft. Also die Zugriffe der FAT-Funktionen klappen sonst halt nicht
mehr.
Gibt es noch eine andere Möglichkeit als CMD58 hier eine Unterscheidung
zu machen?
Eine 1GB Platinum hingegen läuft auch in diesen Block bleibt jedoch am
ACMD41 hängen: es kommt immer 0x00 zurück, sie kommt also nie in den
Idle-State.
Any Ideas? Gerade bezüglich des CT_SD2 bzw. CT_BLOCK, weil wenn dann nur
noch die Platinum Karte nicht ginge wäre das zu verschmerzen...die
scheinen ja eh etwas tricky zu sein.
Gruß
Fabian
Noch eine Ergänzung:
wenn ich die CMD58 Abfrage vor der CMD55->ACMD41 Kombination sende
bekomme ich eine "Antwort". Die Karten senden dann nicht mehr 05
(Illegal Command) sondern immer 01 (Idle State). Wenn ich danach noch 4
Byte lese bekomme ich für das CCS Bit aber immer 0, egal ob SDHC oder
nicht HC.
Es muss doch noch eine Möglichkeit geben SDv2 von SDHCv2 Karten zu
unterscheiden?!
Gruß
Fabian
Hallo,
hatte gerade mit meinem 8MHz-System Probleme, die SD-Karte zuverlässig
zu initialisieren. Nachdem ich den SPi-Prescaler von 128 auf 64 geändert
habe, gehts jetzt offenbar zuverlässig. Die Initialisierungs-SPI-Clock
wird in der MMC.C fest mit fCPU/128 gesetzt.
Vielleicht wäre es sinnvoller dass diese in Abhängigkeit vom CPU-Takt
gesetzt wird, der in irgendeinem h-file definiert wird.
Laut einigen Quellen müssen die Init-Takte mit 100-400kHz erzeugt
werden, was beim 128er Teiler erst ab 12,8Mhz zutrifft. Vielleicht wäre
es auch sinnvoller, beim AVR standardmäßig den 64er-Teiler zu nutzen.
Das deckt besser die typischen Taktfrequenzen ab.
Michael
Hallo zusammen.
@ Fabian B. (fabs)
Hast Du einen PullUp an MISO?
Wie schnell ist dein Kontroller?
Die Init Routine hab ich selber nur abgeschaut,
die die ich selber geschrieben hatte ist raus geflogen,
obwohl die gut war...vielleicht mach ich das wieder rückgängig.
@ Michael R. (Gast)
Ja werde ich ändern.
Viele Grüße
Daniel
@Daniel: Ich hab noch einen gravierenden Fehler in der Soft gefunden.
Jetzt geht auch CMD58. Alle Karten initialisieren nun korrekt, soweit so
gut.
Nur auf meiner MicroSDHC (8GB) kann ich zwar die Fat initialisieren und
auch ffopen gibt ein Ok, aber ich bekomm keine Dateiinfos (filesize oder
Daten). Dabei ging die Karte vorher ... ich find das aber noch raus
(morgen) und werde die Routine dann posten.
Gruß
Fabian
So.
Ich habe habe jetzt die Init soweit dass alle meine Karte initialisiert
werden. Getestet wurden:
- Canon SD 16MB
- Nokia MMC 32MB (2x)
- extrememory MMC 256MB (mit FAT16 und FAT32)
- Platinum SD 1GB (meldet sich als SDv2)
- extrememory SD 2GB (meldet sich als SDv2)
- SanDisk SDHC 4GB (Ultra II)
- SanDisk MicroSDHC 8GB (2x)
- Noname MicroSDHC 8GB
Hierfür musste ich zwei Änderungen an der mmc.c vornehmen.
Bei den Definitions ganz oben im File war das define für ACMD41 falsch.
Korrekt ist:
1
#define ACMD41 (41) // SEND_OP_COND (SDC)
vorher war dort (0x80+41) definiert.
Ich denke auch bei ACMD13 und ACMD23 müsste dieses (0x80) weg, aber da
ich diese Kommandos nicht selbst brauchte und bisher keine Fehler
diesbezüglich feststellte hab ich das erstmal so gelassen.
Die zweite Modifikation betrifft die Funktion mmc_init. Wie oben schon
geschrieben hatte ich ein paar Karten die nicht sofort auf CMD0
antworten, also habe ich hier eine Schleife drum gelegt. Auch bei
anderen Kommandos war dies notwenig (CMD55->ACMD41, CMD58, CMD16).
Ich poste hier einfach mal die ganze Funktion:
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
while(TimingDelay){// Wait for leaving idle state (ACMD41 with HCS bit)
24
mmc_send_cmd(CMD55,0);
25
if(!mmc_send_cmd(ACMD41,1UL<<30))
26
break;
27
}
28
29
while(TimingDelay){
30
if(mmc_send_cmd(CMD58,0)==0x00){// Check CCS bit in the OCR
31
for(n=0;n<4;n++){
32
ocr[n]=spi_read_byte();
33
}
34
ty=(ocr[0]&0x40)?CT_SD2|CT_BLOCK:CT_SD2;// SDv2
35
break;
36
}
37
}
38
}
39
}else{// SDv1 or MMCv3
40
if(mmc_send_cmd(ACMD41,0)<=1){
41
ty=CT_SD1;
42
cmd=ACMD41;// SDv1
43
}else{
44
ty=CT_MMC;
45
cmd=CMD1;// MMCv3
46
}
47
while(TimingDelay&&mmc_send_cmd(cmd,0));// Wait for leaving idle state
48
}
49
if(ty!=(CT_SD2|CT_BLOCK)){
50
while(TimingDelay&&(mmc_send_cmd(CMD16,512)!=0));
51
}
52
if(!TimingDelay)ty=0;
53
}else{j--;}
54
}while(j>0);
55
fat.card_type=ty;
56
mmc_disable();
57
58
if(fat.card_type==0){
59
returnFALSE;
60
}
61
#if (MMC_MAX_SPEED==TRUE)
62
spi_maxSpeed();
63
#endif
64
65
returnTRUE;
66
}
Was mir noch auffiel:
Laut Spec muss ein ACMD immer auf ein CMD55 folgen. Im SDv1 or MMCv3
block wird nur so direkt ein ACMD41 versucht. Ich vermute, dass hier
eigentlich auch ein CMD55 vorher noch sein müsste, da ich aber mit keine
Karte, die diesen Block durchläuft Probleme hatte lass ich es so.
Vielleicht kannst du, Daniel, diese Funktion so bei dir einpflegen und
mal testen.
Nicht direkt als Bug zu bezeichnen: ich hatte noch eine
Unregelmässigkeit.
Bei den SanDisk MicroSDHC 8GB konnte ich die Karte korrekt
initialisieren, Fat initialisieren und auch Fileopen lieferte ein Ok,
die Datei hatte laut file.length jedoch eine grösse von 0 und auch ein
"blindes" ffread() lieferte nur Schrott. Da auf der Karte auch vorher
schon Daten waren habe ich sie dann mal formatiert und die Datei wieder
drauf kopiert und dann ging's einwandfrei.
Gibt es da vielleicht Zugriffprobleme auf Dateien ab einer bestimmten
"Position auf der Karte", also weit hinten? Und wäre es vielleicht
sinnvoll ffopen failen zu lassen wenn die Dateigrösse 0 ist?
Ich verwende:
At90Can128, 10MHz, HC4050 als Pegelwandler, 3V3 Regler für SD Karte,
HW-Spi
Gruß
Fabian
Hallo,
ich habe ein Problem mit dem neuen Code:
Wenn ich das richtig verstehe, wartet die Funktion mmc_wait_ready
lediglich solange, bis auf der Miso-Leitung H-Pegel anliegt:
1
staticunsignedcharmmc_wait_ready(void){
2
3
TimingDelay=50;
4
5
do{
6
if(spi_read_byte()==0xFF)returnTRUE;
7
}while(TimingDelay);
8
9
returnFALSE;
10
}
Zur Aktivierung der Karte wird also zunächst CS auf 0 gesetzt und dann
getestet, ob Miso auf H-Pegel geht (oder bereits ist):
1
staticunsignedcharmmc_enable(){
2
3
MMC_CS_LOW;
4
if(!mmc_wait_ready()){
5
mmc_disable();
6
returnFALSE;
7
}
8
9
returnTRUE;
10
}
Das funktioniert bei mir leider nicht. Meine Karte(n) liefert vor
Absendung des CMD0 Kommandos immer L-Pegel. Aus diesem Grund kommt es
bei mir nicht zur CMD0 Absendung. Habe die mmc_wait_ready erstmal
auskommentiert, wäre für eine Erläuterung dankbar ...
Viele Grüße
recently
Hallo.
>getestet, ob Miso auf H-Pegel geht (oder bereits ist)
Miso sollte H sein, weil da ein PullUp dran sein sollte.
Ich muss das im Wiki unbedingt mal ändern.
Damit sollte das dann klappen.
Viele Grüße
Daniel
Hallo Daniel,
vielen Dank für die schnelle Antwort. Habe den Schaltplan von meinem
Pollin Net-IO mit SD-Karten-ADD-On untersucht und finde dort keinen
Pullup.
Bin ein wenig irritiert, die Hardware funktionierte ja mit der alten
Software, auf dem Oszilloskop sieht das Miso-Signal auch normal aus,
schön rechteckig und ungefähr zwischen 0 und 3V. Aber es ist 0V, wenn
die Karte herausgezogen oder gerade hereingesteckt wurde.
Was für ein Widerstand sollte da eingelötet werden ?
- recently -
Das kann auch ein Effekt der der Karte sein, dass die die Leitung
schwach auf low zieht wenn sie eingesteckt wird und direkt Saft bekommt
(evtl. noch mit Prelleffekten auf der Versorgung). Da ich die Versorgung
der Karte bei mir immer erst einschalte, wenn die Karte im Slot
detektiert wurde, konnte ich dieses Verhalten bei inzwischen ca. 15
getesteten Karten nicht feststellen.
@Daniel R: hast du den mmc_init mal testen können?
Gruß
Fabian
Leider nein, hab diese Woche noch 2 Klausuren und es war Karneval :)
Komme ich aber bald dazu, danke das Du da soviel Mühe mit rein
Investiert hast.
Viele Grüße
Daniel
Hallo Daniel,
habe den 10k Widerstand eingebaut ... Unterschied wie Tag und Nacht. Die
Initialisierung funktioniert jetzt sauber und reproduzierbar (ohne
Pullup hatte ich mehrere CMD0-Wiederholungen, jetzt immer genau 1x).
Sollte man Pollin mal mitteilen ... :-)
Vielen Dank für den Tipp !
Viele Grüße
recently
Haloo,
Ich bin nur Anfänger und ich möchte nur einfacher Programm machen.
Programm macht neue Datei – zum Beispiel „1.txt“ und schreibt jede 10
Sekunden Temperatur (es ist in string format). Jede Temperatur an neue
Zeile. Zuerst möchte ich nur library 0.6.2 testen.
Ich habe SD-Karte, ATMega 168 – es ist durch MISO, MOSI, SCK und CS
verbinden.
Jetzt teste ich Version 0.6.2. Ich habe AVR Studio 4.18, ich öffne
main_simple.c, dann gebe ich Project -> Configuration Options – ich
schreibe Frequency 16MHz (ich habe 16 MHz Krystal). Und dann
programmierte ich den Prozessor. Ich lasse den Programm etwa 10 sekunden
laufen. Aber es macht nichts. Die Karte ist leer. Mache ich etwas
schlecht ? Muss ich noch etwas machen ? Die Karte ist normal formatiert
in Windows – FAT.
Können Sei mir bitte helfen ? Vielen Dank.
Hallo,
läuft der ATMega 168 mit 3,3 Volt?
Läuft das Beispielprogramm ohne irgendwelche Änderungen?
Wie sieht die Schaltung aus?
Versuch immer in kleinen Schritten etwas auszuprobieren, bis es läuft
und erweitere es dann erst.
Viele Grüße
Daniel
Atmega hatte 5Volt, jetzt läufte mit 3,3V aber es geht auch nicht.
Ich mache keine Änderungen - nur frequency.
Die Schaltung ist wie hier
(http://www.mikrocontroller.net/articles/AVR_FAT32), aber keine HC4050
(ich habe 3,3 Volt).
Hallo,
dann mach doch mal noch einen PullUp an MISO vom Kontroller.
Beziehungsweise an DO der Karte.
Dann könntest Du noch mal versuchen in der mmc_config.h
1
#define MMC_MAX_SPEED FALSE
zu setzen.
Und eventuell die mmc_init() zu benutzen die in folgendem Link
angesprochen wird.
Beitrag "Re: MMC SD library FAT16 FAT32 read write"
Falls das alles nichts hilft, müsstest Du mal ein Foto vom Aufbau machen
und hochladen, damit man sich eventuell ein bild von möglichen
Fehlerquellen machen kann.
Du solltest auch mehrere Karten ausprobieren ob vielleicht nur eine
bestimmte nicht funktioniert.
Viele Grüße
Daniel
Hallo zusammen
Ich habe ein Problem mit der AVR Fat32 Library
http://www.mikrocontroller.net/articles/AVR_FAT32
Zur Hardware:
Ich verwende einen Atmega16 mit 12MHz Quarz
Am Hardware SPI Hängt die SD Karte (micro SD)
Der Atmega wird mit 3,3V Betrieben.
Nun das Problem
Die Library funktioniert grundsätzlich sehr gut... Ich habe die Dateien
1:1 übernommen uns es klappte auf anhieb.
Doch ich habe das problem, das wenn ich z.B. die Datei bild.bmp öffnen
lassen will mit der Lib, dann verwende ich folgenden Code
1
while(FALSE==mmc_init()){//Karte Initialisieren
2
nop();
3
}
4
Out1_1;
5
if(TRUE==fat_loadFatData()){
6
unsignedcharfile_name[9]="bild.bmp";
7
8
if(MMC_FILE_EXISTS==ffopen(file_name)){
9
Out1_0;
10
// Setzen einer Variable und dann runterzaehlen geht am schnellsten !
11
seek=file.length;
12
// Lesen eines chars und Ausgabe des chars.
13
// Solange bis komplette Datei gelesen wurde.
14
while(ucBufferCounter!=56)//Daten auslesen
15
{
16
ucBuffer[ucBufferCounter]=ffread();
17
--seek;//Byte Zähler
18
ucBufferCounter++;
19
}//56Bytes Buffer auslesen
20
}
21
22
}
nicht von den 56Bytes irritieren lassen... das spielt derzeit keine
rolle!
Doch wenn ich diesen Code ausführen lasse, dann meldet der Code das Die
Datei existiert jedoch erstellt er selbige auf der Karte.
Wenn ich Die karte also in den PC einschiebe, befindet sich zweimal die
Datei bild.bmp im Root verzeichniss... Windows motzt nun also und ich
muss die Karte formatieren...
Wass jedoch prblemlos geht, ist eine von der Lib erstellte Datei lesen
oder zu erweitern... Auch mit dem Computer... Aber es kann ja nicht
sein, das ich immer mit dem AVR eine Datei erstellen muss und diese Dann
am Computer bearbeiten muss. Dies geht sowiso nur bei txt dateien.
Getestet habe ich den Code mit mehreren Karten. An dennen liegt es also
nicht! An der Lib config habe ich nichts verändert!
Was auch merkwürdig ist, das bei dem Beispielcode von hier
http://www.mikrocontroller.net/articles/AVR_FAT32#Der_Code
steht beim Filename "man beachte die Grossbuchstaben" aber es hat im
beispiel nur kleinbuchstaben.
Hat jemand eine idee wo hier der wurm drinn sein könnte?
Hallo,
ich komme grad nicht dazu ne neue Version zusammen zu packen in der auch
die neue Initialisierungsfunktion ist und auch die neue
fat_loadFiledataFromCluster.
unsignedshortrow;// um durch zeilen zu gehen, eigentlich erstes byte einer reihe...
9
unsignedcharsectors;// um durch sektoren zu zaehlen, sectors+sec = tatsaechliche sektornummer (absoluter sektor)
10
unsignedchari;// um durch eine zeile/reihe zu laufen
11
unsignedcharj;// laufvariable fuer sfn
12
13
// diese variablen muessen statisch sein, weil ein lfn eintrag auf 2 cluter aufgeteilt sein kann !
14
staticunsignedcharchecksum=0;// die kurze dateinamen checksumme, die ausgelesene.
15
staticenumflags{wait=0,start,readout}lfn_state;
16
staticunsignedcharmatch=0;// treffer bei datei namen vergleich zaehlen
17
18
constunsignedcharmap[13]={1,3,5,7,9,14,16,18,20,22,24,28,30};// index von map ist index des zu pruefenden bytes und inhalt ist index des zu pruefenden bytes in der reihe
19
constunsignedcharname_length=strlen((char*)name)-1;// es wird die laenge des dateinamen zum vergleichen benoetigt!
20
21
sectors=0;
22
23
// 5 moegliche zustaende im inneren der beiden schleifen...
24
do{// sektoren des clusters pruefen
25
row=0;// neuer sektor, dann reihen von 0 an.
26
mmc_read_sector(sec+sectors,fat.sector);// laed den sektor sec auf den puffer fat.sector
27
fat.lastSector=file.currentSectorNr;// sichern der alten sektor nummer
28
file.currentSectorNr=sec+sectors;// setzen des aktuellen sektors
29
do{// reihen des sektors pruefen
30
// 1.) nach einem eintrag mit 0x00 kommt nix mehr => restlicher cluster leer!
31
if(fat.sector[row]==0x00){
32
returnFALSE;
33
}
34
// 2.1) ist eintrag ein lfn eintrag? siehe: http://en.wikipedia.org/wiki/File_Allocation_Table#Long_file_names
35
if((fat.sector[row]&0x40)==0x40&&fat.sector[row+11]==0x0F&&fat.sector[row]!=0xE5){// ist lfn eintrag, jetzt pruefen...
match=0;// vergleich index zurueck setzen, damit nicht wieder in diesen zustand gewechselt wird.
78
checksum=fat.sector[row+13];// checksumme sichern zum vergleich mit der errechneten anhand des kurzen dateinamens. in naechstem zustand vergleich.
79
}
80
}
81
// 4.) gesuchte reihe auf stuct file laden zum weiter verarbeiten. das ist der sfn eintrag, mit dem firstCluster, der laenge usw...
82
if(lfn_state==readout&&fat.sector[row+11]!=0x0F){
83
lfn_state=wait;
84
fat_loadRowOfSector(row);
85
file.row=row>>5;// reihe sichern, ist fuer ffrm wichtig
86
if(checksum==fat_lfn_checksum(&fat.sector[row])){// pruefen ob checksumme stimmt...wenn ja alles klar :)
87
file.entrySector=file.currentSectorNr;// sichern des sektors in dem der sfn dateieintrag steht.
88
returnTRUE;
89
}
90
}
91
92
}while((row+=32)<512);// mit row+32 springt man immer an die 1. stelle einer reihe (zeile) und das durch einen ganzen sektor
93
}while(++sectors<fat.secPerClust);// geht durch sektoren des clusters
94
95
returnFALSE;// datei nicht gefunden, zumindest in diesem cluster...
96
}
Diese Funktion solltes Du mal test weise in der fat.c austauschen.
>man beachte die Grossbuchstaben
Die Kommentare in den Sourcen sind nicht immer aktuell ^^
Sag mir mal ob in der mmc_config.h
Daniel R. schrieb:> Die Kommentare in den Sourcen sind nicht immer aktuell ^^
Kein Problem :)
Vielen Dank für die Antwort
Ich habe LFN Support auf True
und auch MMC File Exists auf True
Ich verwende übrigens die neuste Version aus dem SVN
habe besagten Code ersetzt jedoch kommen nun folgende Meldungen
../fat.c:195: error: 'struct Fat' has no member named 'lastSector'
../fat.c:195: error: 'struct File' has no member named 'currentSectorNr'
../fat.c:196: error: 'struct File' has no member named 'currentSectorNr'
../fat.c:255: error: 'struct File' has no member named 'currentSectorNr'
Anscheinend ist das Struct geändert worden von dir :)
Variable im Programm geben die in 10 ms Intervallen runtergezählt wird
bis 0. Wenn Du Dich an der main_simple.c orientierst sollte das kein
Problem werden.
Ich habe mit deiner Neusten Version ein sehr merkwürdiges aber
reproduzierbares verhalten entdeckt.
Ich möchte auf der Speicherkarte überprüfen ob die Datei logfile.txt
existiert...
Das mache ich wie folgt:
1
unsignedcharfile_name_2[]="logfile.txt";
2
3
if(ffileExsists(file_name_2))
4
{
5
text_neu("OK",90,90,1,0,0,255);
6
}
7
else
8
{
9
text_neu("ERROR",90,90,1,255,0,0);
10
}
Problem -> Die funktion liefert immer Error zurück obwohl die Datei auf
der Speicherkarte liegt (habe auch grossklein schreibung geachtet!) LFN
ist aktiviert.
Prüfe ich hingegen ob die Datei test.bmp existiert, klappt der test
einwandfrei. Beide Dateien beinhalten etwas. sind also nicht 0Byte
gross!
Nun das ganz spezielle...
Möchte ich nun also die Datei Lesen (logfile.txt) wass ja eigentlich
nicht gehen sollte, so wird diese angelegt und es befinden sich wieder
zweimal die selben dateien auf der Karte. Wichtig hier zu beachten ist,
das die Lib die neue Datei mit Grossbuchstaben erstellt egal ob ich der
Funktion kleibuchstaben übergeben habe.
Könnte dies ein hinweis darauf sein, das in dieser funktion nicht auf
LFN geachtet wird?
Vielleicht sagt dir meine Fehlerbeschreibung ja etwas...
Ansonsten keine Probleme :)
Hallo,
ja klingt irgendwie danach:
Beitrag "Re: MMC SD library FAT16 FAT32 read write"
Ersetze die Funktion in der fat.c durch die Funktion aus dem Post.
Benutzt Du die Version 0.6.2 ? Da sollte wenn Du die Datei zum lesen
öffnest auf jeden Fall keine zweite Datei mit dem selben Namen angelegt
werden.
Viele Grüße
Daniel
Hallo Daniel
Ja ich habe die Funktion ersetzt... Ja ich verwende die Version 0.6.2
Ich habe das Problem gefunden...
Es scheint so, als ob die Funktion File Exists nur mit kurzen Dateinamen
klar kommt...
Dies stört mich nicht weiter, da ich ja darauf achten kann...
Aber wollte dir halt dennoch den hinweis geben :)
Dann ist es allerdings etwas merkwürdig das LFN nicht unterstützt wird
obwohl ich den Schalter auf True habe. Das selbe ist es mit SDHC karten
Ich habe den schalter auf True
Aber 8GB Karten werden nicht initialisiert.... (FAT)
Daniel R. schrieb:> Das kann nicht sein. In der 0.6.2 ist der Schalter für SDHC raus> geflogen.
Ohhh.... schande... Tut mir leid... ja du hast recht... ich habe auch
keinen.
Daniel R. schrieb:> Hast Du die hier gepostete mmc_init Version benutzt?> Beitrag "Re: MMC SD library FAT16 FAT32 read write">> Hast Du die hier gepostete fat_loadFileDataFromCluster Version benutzt?> Beitrag "Re: MMC SD library FAT16 FAT32 read write">> Damit geht das auf jeden Fall.>> Viele Grüße
Ich habe diese Version von der du mir den link gesendet hast.
Ok, Du brauchst die Version 0.6.2 hier aus dem Thread und dann musst Du
die beiden Funktionen austauschen. Die Beiden Funktionen aus den Links
die ich gepostet hab. Dann wird es klappen. Bin wie gesagt noch nicht
dazu gekommen die einzubauen und das ins SVN hochzuladen.
Viele Grüße
Daniel
Ok
Vielen Dank
Ich werde die Anpassungen vornehmen und eventuelle probleme wieder
fragen wenn ich darf :)
Ich denke das ich dann auch mit den Verzeichnissen arbeiten kann... Das
klappt mommentan auch noch nicht
Hallo,
die Tabelle ist so zu lesen:
Pin 1 der SD/MMC Karte soll an Pin 15 des ATmega168
Pin 2 der SD/MMC Karte soll an Pin 17 des ATmega168
...
...
Bei der DIP Version des ATmega168 sieht man im Datenblatt, dass Pin 15
des IC der Port B1 des Kontrollers ist.
>Und hast du in library behandelt Ergennung>der Karte und Schutz von Überschreibung ?
Du meinst ob eine Karte im Slot steckt und der Hardware Schreibschutz an
ist?
Ja da ist was in der Lib, weiß aber nicht genau ob das auf Anhieb
funktioniert.
Viele Grüße
Daniel
Kurt Bohnen schrieb:> Leider funktioniert trotz MISO PullUP nur eine der 3 Karten. Mit der> 0.5.9C hatten die alle funktioniert.> Schade dass ich keine Zeit zur Fehlersuche habe.
Heute hatte ich Zeit. Das Problem war wohl, das ich "alten" Code aus dem
SVN genommen hatte. Mit dem aktuellen Code und den Patches aus dem
Thread hier funktionieren jetzt alle Karten!
Ein Problem bleibt immer noch:
Ich schreibe 921600 Byte auf die Karte. Kontrolle mit Win XP: Dateigröße
und Inhalt OK. Dann nach checkdisk: Datei ist 4kB größer weil Datenmüll
am Ende angehängt wurde.
Das passiert aber nur bei FAT32 formatierten Karten. Bei FAT16 gibt es
keine Probleme. LFN hat keinen Einfluss.
Mfg,
Kurt
Moin! Ich verzweifel hier mal wieder an der Ansteuerung einer
MicroSD-Karte (habe schon zwei verschiedene probiert). MCU ist ein
AT90CAN128, Pegelwandler ein MAX3002. Die Verdrahtung habe ich schon
hundertmal geprüft. MISO-Pullup (10k) habe ich auch.
Ich schaffe nicht einmal die mmc_init(). spi_read_byte() gibt immer nur
0 zurück. Nach dem Timeout wird dann abgebrochen. Was kann ich noch
machen, bin völlich ratlos?
Ich habe die neueste Version im Einsatz inkl. den Modifikationen aus den
Posts hier.
Hm, mach doch mal ein Foto vom Aufbau.
>habe schon zwei verschiedene probiert
Wenn das nicht total außergewöhnliche Karten sind sollten die schon
gehen.
>Nach dem Timeout wird dann abgebrochen.
Also die Timer Einstellungen sind richtig? Ist vielleicht der Timer zu
schnell eingestellt? Überprüf mal ob die Zeiten des Timers stimmen.
Ich mache die Einstellungen um nicht nachdenken zu müssen mit
http://clsql.med-info.com/download.html>Ich schaffe nicht einmal die mmc_init()
Klingt für mich irgendwie nach Hardware Problem
Viele Grüße
Daniel
Daniel,
hast du eine Idee wo mein Problem liegt oder sonst jemand? Ich bin doch
wohl nicht der einzige, der seine Karten mal mit chkdsk geprüft hat?
Mfg,
Kurt
Hallo Kurt,
also ich würde mal vermuten, dass da die 2. Fat dran schuld ist.
Hast Du die Möglichkeit die Karte mal so zu formatieren, dass nur eine
Fat angelegt wird?
Sonst kann ich mir das eigentlich nicht erklären. Besonders, weil es nur
bei Fat32 auftritt. Bis auf die Fat Einträge selbst ist Fat16 und Fat32
nämlich identisch.
Unter Linux würde formatieren mit nur einer Fat so aussehen:
1
mkdosfs -v -F32 -f1 -s4 -I /dev/sdb
Der Befehl erstellt ein Fat32 Dateisystem mit nur einer Fat und 4
Sektoren pro Cluster auf dem Device sdb.
Viele Grüße
Daniel
So ich habe jetzt mal alle Signale vor (5V, high) und hinter (3V, low)
dem Pegelwandler aufgenommen. Herausgekommen ist der Anhang. Die kurzen
Puls bei MISO low sind etwa 10ns lang. Kann jemand bei der Deutung des
Bildes helfen?
So ich habe jetzt mal je einen SPI Interpreter auf die low und high side
gepackt. Auf der low side können auch Bytes entziffert werden -
natürlich nicht auf der high side. Machen die Bytes Sinn? Ist der
Pegelwandler defekt?
Jetzt fall ich gleich vom Glauben ab: Wenn der LogicAnalyser
angeschlossen ist, funktioniert scheinbar alles, d.h die Test-Datei wird
geschrieben (obwohl die aufgezeichneten Kurven anderes schließen
lassen), ziehe ich ihn ab, geht nix mehr. Wodurch lässt sich so ein
Verhalten erklären?
Ich habe spontan an das hier gedacht:
http://www.eevblog.com/2011/03/11/eevblog-155-itead-studio-pcb-prototype-goof/
Aber ein Massefehler kann ich eigentlich ausschließen. Irgendwelche
Ideen?
Vielen Dank im Vorraus und entschuldigung für die vielen Posts in Folge.
Gruß Sven
Wenn ich die Karte mit dem SD Formatter 3.0 formatiere tritt das Problem
nicht mehr auf. Aber gibt es nicht einen Workaround für die Firmware?
Mfg,
Kurt
Hallo.
@ Sven S. (schwerminator)
Hast du abblock Kondensatoren an allen IC's?
Was benutzt Du als Pegelwandler?
@ Kurt Bohnen (kurt)
Es wird dafür keinen Workaround geben. Das würde nämlich bedeuten, dass
alle Fat Operationen zwei mal gemacht werden müssten. Die zweite Fat ist
eigentlich gedacht um zu schauen ob es einen Unterschied gibt. Gibt es
den muss wohl ein Fehler vorliegen. Korrigieren kann man den dann aber
noch nicht.
Eventuell eine Alternative zu dem normalen check disk suchen.
Viele Grüße
Daniel
Abblockkondensatoren sind reichhaltig verbaut. Als Pegelwandler benutze
ich einen MAX3002. Einen solchen habe ich schonmal erfolgreich mit einer
SD-Karte betrieben, allerdings ohne MISO-Pullup, ich werde das Gefühl
nicht los, dass sich MAX3002 und der Pullup aus welchen Gründen auch
immer nicht vertragen. In meiner jetzigen Schaltung ist der Pullup mit
10k dimensioniert auf der 3V-Seite des Wandlers, was jedoch
grundsätzlich richtig sein müsste...
Gruß Sven
Daniel R. schrieb:> @ Kurt Bohnen (kurt)>> Es wird dafür keinen Workaround geben. Das würde nämlich bedeuten, dass> alle Fat Operationen zwei mal gemacht werden müssten. Die zweite Fat ist> eigentlich gedacht um zu schauen ob es einen Unterschied gibt. Gibt es> den muss wohl ein Fehler vorliegen. Korrigieren kann man den dann aber> noch nicht.>> Eventuell eine Alternative zu dem normalen check disk suchen.
OK. Dann muss ich diesmal zu Elm Chans lib wechseln. Die ist zwar
deutlich größer aber in dieser Hinsicht toleranter.
Trotzdem vielen Dank!
Mfg,
Kurt
In Chans Lib wird die zweite Fat auch nicht beschrieben, da hast Du das
gleiche Problem.
Das hat ja auch nix mit Tolerant zu tun. Sondern mit dem Unsinn zwei Fat
Tabellen führen zu müssen anstelle von ordentlichen Codes um Fehler zu
beheben. Die Idee einfach alles doppelt da hin zu schreiben ist ein
Repetition Code und ne ganz große Glanzleistung von MS...
Du hast ja geschrieben, dass die Daten korrekt sind und nach einem check
disk erst falsch. Vielleicht sind die ja schon vorher falsch? Poste doch
mal die Änderungen die du gemacht hast, vielleicht kann ich dann mehr
dazu sagen.
Viele Grüße
Daniel
Ich bin mir jetzt fast sicher dass das FAT32 Problem bei Chan nicht
auftritt, werde das aber nochmal prüfen.
Daniel R. schrieb:> ganz große Glanzleistung von MS...
Da gebe ich dir Recht!
Ich kann nicht ausschließen dass jemand mein Projekt benutzt der seine
SD-Card mit FAT32 und Windows formatiert. Wenn er dann aus welchem Grund
auch immer checkdisk laufen lässt und die neu angelegten Dateien mit
Müll volgestopft werden ist das weniger schön...
Daniel R. schrieb:> Poste doch> mal die Änderungen die du gemacht hast
Keine, nur die Portdefinitionen. Dann einfach eine neue Datei erstellen,
900kB reinschreiben und schließen.
Ich melde mich später nochmal mit mehr Details.
Mfg,
Kurt
Hallo.
@ JVogel (Gast)
Kannst auch an andere Pins hängen, musst dann aber software SPI benutzen
und einschalten in der config. Zudem musst Du dann natürlich auch die
richtigen Pins einstellen in der mmc.h
Hallo nochmals. Ich habe noch ein paar Tests gemacht:
- Auch ohne Pullup klappts nicht ohne LogicAnalyser
- Zusätzlicher 100n bringt ebenfalls nicht den gewünschten Erfolg
- Folgende Leitungen auf der High-Side des Pegelwandlers müssen an den
LA geklemmt sein, damit es funktioniert: CS, SCK und MOSI (+ GND) -
sprich alle Leitungen in Richtung der SD. Die Eingangsimpedanz des LA
ist wie folgt: 200K Ohms, paralleled by <5pF.
Welche Schlüsse kann ich aus der Information ziehen?
Bei mir hängt das programm bei mmc_enable(); nach dem SPI_INIT
mmc_send_cmd(CMD0, 0)
->if ( FALSE == mmc_enable() )
dort bleibt es hängen woran kann das liegen?
Hab einen Atmega32@16mhz
Timer :
1
TCCR0=(1<<CS02)|(1<<CS00)|(1<<WGM01);
2
TCNT0=START_TCNT;
3
OCR0=TOP_OCR;
4
5
ISR(TIMER0_COMP_vect)
6
{
7
TimingDelay=(TimingDelay==0)?0:TimingDelay-1;
8
9
}
mmc.h
1
#define MMC_Write PORTC //Port an der die MMC/SD-Karte angeschlossen ist also des SPI
2
#define MMC_Read PINC
3
#define MMC_Direction_REG DDRC
4
5
#if defined (__AVR_ATmega32__)
6
#define SPI_MISO 3 //Port Pin an dem Data Output der MMC/SD-Karte angeschlossen ist
7
#define SPI_MOSI 2 //Port Pin an dem Data Input der MMC/SD-Karte angeschlossen ist
8
#define SPI_Clock 1 //Port Pin an dem die Clock der MMC/SD-Karte angeschlossen ist (clk)
9
#define SPI_SS 0 //Port Pin an dem Chip Select der MMC/SD-Karte angeschlossen ist (CS)
// schalter die den funktionsumfang aendern bzw, den funktionsumfang einiger funktionen :)
5
#define MMC_WRITE TRUE // TRUE, dann mit write unterstuetzung, wenn FALSE dann read only !
6
#define MMC_OVER_WRITE FALSE // TRUE und MMC_WRITE TRUE, dann kann ffwrite dateien ueberschreiben, wenn FALSE dann nur normales schreiben. um an eine datei anzuhaengen ist MMC_OVER_WRITE TRUE nicht noetig!
7
#define MMC_MULTI_BLOCK FALSE // TRUE und MMC_OVER_WRITE FALSE, dann werden multiblock schreib/lese funktionen benutzt. ist schneller, wird aber moeglicherweise nicht von allen karten unterstützt. wenn FALSE ist normale operation
8
#define MMC_ENDIANNESS_LITTLE TRUE // TRUE, dann ist der code auf littleendian ausgelegt. AVR ist littleendian. code ist auf littleendian optimiert!! siehe: http://de.wikipedia.org/wiki/Endianness
9
#define MMC_LFN_SUPPORT FALSE // TRUE, dann mit unterstuetzung fuer lange dateinamen. kostet wenn read und write benutzt wird um die 800 bytes flash...
10
#define MMC_RM_FILES_ONLY TRUE // TRUE ,MMC_WRITE TRUE und MMC_RM TRUE, dann wird die funktion ffrm so mit kompiliert, dass sie nur dateien loeschen kann. wenn FALSE und MMC_WRITE TRUE, dann kann die funktion dateien und ordner rekursiv loeschen !
11
12
// schalter die explizit funktionen mit kompilieren oder nicht!
13
#define MMC_TIME_STAMP FALSE // TRUE, dann werden die funktionen fat_getTime und fat_getFreeBytes mit kompiliert. siehe auch abschnitt: ZEIT FUNKTIONEN, weiter unten
14
#define MMC_RM FALSE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffrm mit kompiliert.
15
#define MMC_SEEK TRUE // TRUE,dann wird die funktion ffseek mit kompiliert. mit dieser funktion kann man in einer geoeffneten datei vor und zurueck spulen. nur in kombination mit MMC_OVER_WRITE TRUE kann in einer datei ueberschrieben werden.
16
#define MMC_MKDIR FALSE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffmkdir mit kompiliert. mit dieser funktion kann man ordner anlegen.
17
#define MMC_GET_FREE_BYTES FALSE // TRUE, dann wird die funkton fat_getFreeBytes mit kompiliert. mit dieser funktion kann der freie platzt auf der karte ermittelt werden
18
#define MMC_LS FALSE // TRUE, dann wird die funktion ffls mit kompiliert. mit dieser funkion kann man die dateien auf der karte anzeigen lassen
19
#define MMC_CD FALSE // TRUE, dann werden die funktionen ffcd und ffcdLower mit kompiliert. mit diesen funktionen kann man in ein verzeichnis wechseln oder aus einem verzeichnis ein verzeichnis hoeher wechseln.
20
#define MMC_FILE_EXSISTS FALSE // TRUE, dann wird die funktion ffileExsists mit kompiliert. mit dieser funktion kann geprueft werden, ob es die datei im aktuellen verzeinis gibt !
21
#define MMC_WRITE_STRING TRUE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffwrites mit kompiliert. mit dieser funktion koennen strings auf die karte geschrieben werden.
22
#define MMC_WRITEN FALSE // TRUE und MMC_WRITE TRUE, dann wird die funktion ffwriten mit kompiliert. mit dieser funktion koennen mehrere zeichen auf die karte geschrieben werden!
23
24
// vorsicht, da die variable die die sektoren zaehlt ein short ist (MMC_MAX_CLUSTERS_IN_ROW*fat.secPerClust) !!
25
#define MMC_MAX_CLUSTERS_IN_ROW 256 // gibt an wie viele cluster am stueck ohne fat-lookup geschrieben bzw gelesen werden können, wenn die fat nicht fragmentiert ist !
Moin, bei irgend einem cmd an die Karte kann man als Parameter die
Spannung mit angeben. Die Karte antwortet dann positiv oder nicht. Weiß
aber grad nicht aus dem Kopf welches cmd das ist.
3,3 Volt wäre schon besser und erwarte nicht zu viel von den
Spannungsteilern.
@ Sven S. (schwerminator)
Probier mal 1k Widerstände längst den Leitungen, quasi als Terminator...
Was sagt denn das Datenblatt vom MAX3002 zu korrekten Beschaltung?
Viele Grüße
Daniel
Ok dan kram ich mal lieber in meiner kiste irgendwo hab ich noch ein
Spannungsregler au 3V, oder ich bau mir einen Spannungseiler der mit ca
3.3V gibt. Was denkt ihr ist die bessere Wahl?
Daniel R. schrieb:> In Chans Lib wird die zweite Fat auch nicht beschrieben, da hast Du das> gleiche Problem.
HELLO1.TXT wurde mit Chans Lib erstellt. TEST1.TXT mit deiner, Daniel.
Danach habe ich die Karte auf Fehler prüfen lassen. Wie man sieht ist
HELLO1.TXT unverändert, TEST1.TXT ist genau um 4kB gewachsen.
Daher würde ich vermuten das irgendeine Variable falsch initialisiert
wird oder falsch abgefragt, <,>,<=,>=...
Das Problem ist mir schon in früheren Versionen vor der 0.6.2
aufgefallen.
Mfg,
Kurt
Hallo ich habe das gleiche problem wie jvogel. Auch an einem atmega32
ich habe ihn auf 3.3v laufen und den timer von ihm kopiert ist der timer
falsch? Und oder geht nur. Soft spi nicht? Sry schreibe vom handy aus
dh vielleicht buchstaben drwher etc
Hallo.
@ Kurt Bohnen (kurt)
Tatsächlich, glaube es gibt da ein Problem in der Fat.
Es wird ein Cluster zu viel verkettet. Was erstmal an den Daten nichts
ändert, da die Dateilänge ja stimmt. Es wird aber Platz verschenkt.
Bin das gerade am ändern.
@ marvin (Gast)
Welche Werte nimmst Du denn?
Viele Grüße
Daniel