Hallo Leute,
habe den Code aus diesem Thread:
Beitrag "MMC SD library FAT16 FAT32 read write"
in verwendung um eine SD-Card auszulesen.
Klappt auch fast perfekt. Vielen dank für die Tolle arbeit schon mal.
Ich habe jetzt hier eine relativ große Textdatei mit 220 Zeilen und bis
zu 50 Zeichen. Die ganze Datei hat laut Windoof 11KB.
Wenn ich jetzt versuche die Komplette Datei einzulesen, bekomme ich über
die serielle Schnittstelle aber nur die letzten 12 Zeilen angezeigt.
Vergrößere ich jetzt das Array zum zwischenspeichern des Monsterstrins
habe ich im Programm scheinbar einen Speicherüberlauf und nichts geht
mehr.
Zudem lese ich den String nicht nur aus sondern zerlege ihn auch noch in
einzel strings, so das ich quasi alles doppelt habe.
Hier mal der entsprechende Ausschnitt aus dem Quellcode:
ändere ich jetzt sd_card_string[1] auf sd_card_string[10], macht mein
Programm schon Probleme.
Als Controller verwende ich einen ATMega1284.
Dessen Speicher belegung sieht laut AtmelStudio derzeit wie volg aus:
Program Memory Usage : 35992 bytes 27,5 % Full
Data Memory Usage : 10553 bytes 64,4 % Full
nun war meine Idee die Datei nur an der für mich Interessanten stelle
auszulesen. Aber wie mache ich das ? und geht das überhaupt?
LG Chris
Oh danke für die Hilfe....
aber hatte ich nicht erwähnt das ich auch schon sd_card_string
vergrößert habe übrigens auch schon auf die 11000Byte was 11K Zeichen
entsprechen müsste da ein char 8Bit/1Byte speichern kann und das aber
mein controller schon bei sd_card_string[10] aufgibt weil scheinbar der
Speicherüberläuft. und ich deshalb gerne die Datei nur an einer
Bestimmten stelle auslesen möchte.
LG
So eine Textdatei bearbeitet man aber nicht, indem man den kompletten
Text erst mal in den Speicher holt.
Wenn man den Speicher hat, dann holt man sich eine Zeile in den Speicher
und holt sich dann aus der Zeile die Teile raus, die man haben will.
Danach kommt die nächste Zeile drann. etc. etc.
> //Nun wird der Komplette String anhand von ; in Einzelne zerlegt
und wenn du überhaupt zeilenübergreifend anhand der ';' deinen Text
zerlegst, dann musst du das Einlesen und das Zerlegen ineinander
geschachtelt gleichzeitig machen.
Dann klappt das auch auf einem kleinen µC.
So lange ist das noch nicht her, dass übliche Computer keine 2GByte
Hauptspeicher hatten, sondern nur lausige 64K. Und trotzdem konnte man
damit schon umn einiges größere Texte als 64KByte bearbeiten (und in den
64K musste das Programm auch noch mit drinnen sein).
Das ist nur heute auf PC so, dass man mit dem Hauptspeicher nicht mehr
haushalten muss und den einfach mal zuballert. Hat man den Speicher
nicht, dann muss dann da eben ein wenig intelligenter rangehen.
Martin Wende schrieb:> geh mit seek zur zeile die du brauchst.
seek ist gut habe ffseek() in file.c gefunden allerdings habe ich jetzt
noch nichts gefunden was mir den offset meiner gesuchten zeile liefert.
Ich müsste wenn ich Zeile 5 lesen will ja erst mal rausfinden ab welcher
Stelle diese anfängt und wo sie endet. Für den Zeilenanfang müsste ich
ja irgendwie das 4. 0x0D finden für </r> und dann noch einen sektor
drauf rechnen, für das ende so lange lesen bis 0x0D kommt
also so in etwa:
suchen??
mit ffseek() den pointer auf die richtige Startadresse setzen? und
lesen:
Chris schrieb:> Martin Wende schrieb:>> geh mit seek zur zeile die du brauchst.>> seek ist gut habe ffseek() in file.c gefunden allerdings habe ich jetzt> noch nichts gefunden was mir den offset meiner gesuchten zeile liefert.
Gibts auch nicht.
Vergiss den Vorschlag.
Wenn deine Zeilen nicht gleich lang sind, bleibt dir nichts anderes
übrig als das File von vorne bis hinten Zeile für Zeile (oder Zeichen
für Zeichen) zu lesen.
Mit seeken kommst du nur weiter, wenn deine Datei eine Struktur aus
gleich lange aufgebauten Records hat oder du vorher erst mal das File
einmal durchliest um festzustellen, wo die einzelnen Zeilen anfangen.
Das erste hast du nicht
Das zweite willst du nicht, denn wozu soll es gut sein, das File erst
mal durchzulesen nur um dann nachher erst recht wieder von vorne bis
hinten Zeile für Zeile zu bearbeiten.
Karl Heinz Buchegger schrieb:> Wenn deine Zeilen nicht gleich lang sind, bleibt dir nichts anderes> übrig als das File von vorne bis hinten Zeile für Zeile (oder Zeichen> für Zeichen) zu lesen.
"Lesen" heißt hier aber nicht "im Speicher aufheben"!
Karl Heinz Buchegger schrieb:> Wenn deine Zeilen nicht gleich lang sind, bleibt dir nichts anderes>> übrig als das File von vorne bis hinten Zeile für Zeile (oder Zeichen>> für Zeichen) zu lesen.
ok also mache ich das etwa so
1
for(inti=0;i<zeile;i++)
2
{
3
unsignedintn=0;
4
do
5
{
6
sd_card_string[n]=ffread();
7
n++;
8
9
}while(ffread()!=0x0D);
10
11
}
und der letzte sd_card_string der übrig bleibt, ist der gesuchte?
LG
Nein.
Du liest solange, bis Du ein Zeilenendezeichen erkennst. Jedes gelesene
Byte wirfst Du sofort weg.
Hast Du ein Zeilenendezeichen erkannt, weißt Du, das die folgenden Bytes
bis zum nächsten Zeilenendezeichen zur zweiten Zeile gehören.
Da Du die fünfte Zeile lesen willst, wiederholst Du den Vorgang solange,
bis Du das vierte Zeilenendezeichen gelesen hast.
Erst dann musst Du Dir die gelesenen Bytes aufheben -- der Puffer
dafür muss natürlich ausreichend dimensioniert sein.
Rufus Τ. Firefly schrieb:> Nein.>> Du liest solange, bis Du ein Zeilenendezeichen erkennst. Jedes gelesene> Byte wirfst Du sofort weg.
Jaein.
Das kommt jetzt drauf an, was eigentlich das Ziel des ganzen ist.
ALso:
Was ist eigentlich gefordert? Wo soll die Reise eigentlich hingehen?
Für mich sieht es so aus, als ob die Datei in 'Wörter' aufgeteilt werden
soll, wobei zwischen den Wörtern ein ';' steht.
Die nächste Frage lautet jetzt: Was hat es mit diesen Wörtern auf sich,
was muss damit passieren?
Man liest ja eine Datei nicht einfach nur so zum Spass, sondern mit dem
Inhalt soll ja irgendwas gemacht werden.
(Ich denke nämlich, das das Zwischenziel die n-te Zeile zu bestimmen,
eigentlich für die eiegentliche Aufgabenstellung vollkommen irrelevant
ist. Da hat er sich einfach nur in etwas verrannt)
Karl Heinz Buchegger schrieb:> ALso:>> Was ist eigentlich gefordert?
Die Datei beinhaltet mehrer Zeilen Text.
Ich brauche aber nur den Text aus einer bestimmten zeile.
Hatte die Semikolon nur eingefügt, damit ich diese Später besser
zerlegen kann, wird ja aber für das jetzige Vorhaben nicht mehr benötigt
da nach dem Zeilenendezeichen gesucht wird.
Was ist den an meiner for schleife so falsch ausser das sd_card_string
nicht komplett überschrieben wird wenn die vorige zeile > der folgenden.
LG Chris
Chris schrieb:> Karl Heinz Buchegger schrieb:>> ALso:>>>> Was ist eigentlich gefordert?>> Die Datei beinhaltet mehrer Zeilen Text.> Ich brauche aber nur den Text aus einer bestimmten zeile.
ok.
Na dann.
2 phasiges Vorgehen.
1. Phase
********
Alle Zeilen vor der interessierenden überlesen
2. Phase
********
Die Zeichen dieser Zeile komplett einlesen
> Hatte die Semikolon nur eingefügt, damit ich diese Später besser> zerlegen kann
Genau das hat mich nämlich verwirrt.
(Es gibt nämlich auch Fileformate, bei denen der ; das Trennzeichen
zwischen 'Befehlen' ist. Zb HPGL)
> Was ist den an meiner for schleife so falsch ausser das sd_card_string> nicht komplett überschrieben
wozu willst du denn überhaupt die Zeichen zwischenspeichern, wenn du sie
eh nicht brauchst?
Das kostet nur Zeit und du läufst Gefahr, dass du mal auf eine Zeile
stösst, die länger als der Buffer ist, den du für eine Zeile
bereitstellen musst.
Also: Wenn du zur n-ten Zeile willst, dann einfach vom Beginn des Files
so lange dahinlesen, bis n-1 mal ein \n aufgetaucht ist.
Und du darfst natürlich nicht 2 mal ffread aufrufen, so wie du das
gemacht hast. Und ein wenig Fehlerbehandlung musst du auch betreiben.
Wenn ich in einer Datei mit 20 Zeilen die 40-te lesen lasse, dann wird
das bei dir nicht gut gehen.
IM Prinzip und ohne Fehlerbehandlung
1
charsd_card_string[240];
2
3
//
4
// Phase 1
5
for(i=0;i<ZeilenNr-1;i++)
6
{
7
while(ffread()!='\n')
8
;
9
}
10
11
// Phase 2
12
n=0;
13
while((c=ffread())!='\n')
14
sd_card_string[n++]=c;
15
16
sd_card_string[n]='\0';
Jetzt würds mich aber doch interessieren, wozu man auf einem µC die n-te
Zeile aus einem Textfile braucht.
Karl Heinz Buchegger schrieb:> Jetzt würds mich aber doch interessieren, wozu man auf einem µC die n-te> Zeile aus einem Textfile braucht.
Ich baue gerade für unsere Abteilung einen etwas komfortableren
Durchgangsprüfer für größere Kabelsätze. Dazu wird der Kabelsatzt an
mein Gerät angeschlossen, wo in wirklichkeit ein Steuergerät sitzen
würde.
Dann nimmt man eine Prüfspitze und geht zu dem Stecker und dem Pin von
dem man wissen möchte was er ist. Das Gerät schiebt mittels
Schieberegister eine 1 durch, in meinem Fall, 240 Kontakte und erhält
das Gerät die 1 an einem I/O zurück spuckt es einem anhand der
mitgezählten Schritte die passende Bezeichnung von Stecker,Pin und
dessen Bedeutung aus.
Und vorrausgesetzt ich habe keinen Fehler in der Schaltung wird noch der
übergangswiderstand der Leitung gemessen.
Habe solch ein gerät schon mal in klein gebaut mit Daten für nur einen
Kabelsatztypen, das hat auch so weit ganz gut Funktioniert, nur ist man
damit halt kein Stück flexiebel und eine Widerstandmessung war auch
nicht drin.
Zur Zeit wird das für die meisten Kabelsätze noch von Hand gemacht,
sprich; Multimeter auf Durchgang, 1.Messleitung in den Stecker/Pin von
dem man wissen will, wo er hin ghet und was er macht und mit der
2.Messleitung alle 240 Kontakte der Gegenseite durchklingel, wenn es
piepst in den Kabelsatzplan schauen was man da gefunden hat.
Darum jetzt mit SD-Card um mehr Infos speichern zu können.
Danke für die Hilfe und LG
Chris
Moin Moin,
habe jetzt Karl Heinz Beispielcode übernommern, habe jetzt nur das
Problem das er die zu öffnende Datei nicht mehr findet... Wie kann das
denn sein? Es wurde an der Art der Dateiöffnung nichts verändert nur das
daraufvolgende auslesen wurde angepasst. Habe Testweise noch mal das
alte .hex File von gestern geflasht und auch dort wird die Datei nicht
geöffnet. Jetzt habe ich zu guter letzt die SD-Card noch mal formatiert
aber auch das hat nichts gebracht.
LG
Chris schrieb:> habe jetzt Karl Heinz Beispielcode übernommern, habe jetzt nur das> Problem das er die zu öffnende Datei nicht mehr findet...
Ja, dann wirst du wohl erst nochmal einen Schritt zurück machen
müssen, und schauen, ob wenigstens der Code von gestern noch
funktioniert.
Und dann mal (wenigstens) versuchen, das zu verstehen, was du da
gerade tust...
Chris schrieb:> daraufvolgende auslesen wurde angepasst. Habe Testweise noch mal das> alte .hex File von gestern geflasht und auch dort wird die Datei nicht> geöffnet. Jetzt habe ich zu guter letzt die SD-Card noch mal formatiert> aber auch das hat nichts gebracht.
Kabel gerissen, Kurschluss irgendwo, ....
gibt da ein paar Möglichkeiten.
Danke für die Erläuterung.
Ja. So macht das natürlich Sinn.
Chris schrieb:> Ich baue gerade für unsere Abteilung einen etwas komfortableren> Durchgangsprüfer für größere Kabelsätze. Dazu wird der Kabelsatzt an> mein Gerät angeschlossen, wo in wirklichkeit ein Steuergerät sitzen> würde.> Dann nimmt man eine Prüfspitze und geht zu dem Stecker und dem Pin von> dem man wissen möchte was er ist. Das Gerät schiebt mittels> Schieberegister eine 1 durch, in meinem Fall, 240 Kontakte und erhält> das Gerät die 1 an einem I/O zurück spuckt es einem anhand der> mitgezählten Schritte die passende Bezeichnung von Stecker,Pin und> dessen Bedeutung aus.> Und vorrausgesetzt ich habe keinen Fehler in der Schaltung wird noch der> übergangswiderstand der Leitung gemessen.
Ich würde diese Aufgabe etwas anders lösen:
Deine Messschaltung wird über USB-seriell an einen Laptop angeschlossen.
Wenn erforderlich, erledigen zwei Optokoppler in RX und TX die
galvanische Trennung. Die Messschaltung weiß nichts über die Kabel, sie
liefert nur die Nummer des verbundenen Anschluß und den
Überganswiderstand zum Laptop. Dort kann man sich dann austoben, bunte
Oberflächen malen, alle Kabel mit allen Varianten verwalten, Statistiken
erstellen und zum Schluß alles in die Warenwirtschaft einpflegen.
MfG Klaus
Hallo Klaus, ja das mit den Daten an den Laptop hatten wir auch schon
überlegt und das Gerät verfügt auch über einen USB <---> Seriell Wandler
um Messprotokolle zu generieren. Aber wir wollten es auch Stand Alone
machen damit man nicht immer gleich nen Laptop oder Desktoprechner
braucht.
Karl Heinz Buchegger schrieb:> Kabel gerissen, Kurschluss irgendwo, ....
Nee leider nicht der Fall.
1
while(PIND&=(1<<PD7))// fragt CDI ab, liegt an Masse, wenn eine Karte eingesteckt ist
2
{
3
rs232_text("\nkeine Karte eingesteckt");
4
WDH3224_TEXT(180,8,"SD-Karte ?",2,0);
5
}
6
7
WDH3224_TEXT(180,8," ",2,0);
8
rs232_text("\nBoot");
9
WDH3224_TEXT(180,8,"Boot...",2,0);
10
11
// Versuch Karte zu Initialisieren, bis es klappt.
12
// Unbedingt so, weil die Initialiesierung nicht immer
13
// auf Anhieb klappt.
14
while(FALSE==mmc_init())
15
{
16
nop();
17
}
18
19
rs232_text("...");
20
21
22
// Fat initialisieren. Nur wenn das klappt sind weitere
23
// Aktionen sinnvoll, sonst endet das Programm.
24
if(!fat_loadFatData())
25
return-1;
26
27
// Wenn auf dem terminal "Boot... OK" zu lesen ist, ist Init OK.
28
// Jetzt kann man Schreiben/Anhängen/Lesen.
29
rs232_text("Ok\n");
30
WDH3224_TEXT(180,29,"OK",2,0);
31
if(MMC_FILE_EXISTS==ffopen("TEST0000TXT"))
32
{
33
WDH3224_CLEAR();
34
WDH3224_TEXT(3,0,"Datei wird geoeffnet",2,0);
35
36
rs232_text("\nDatei wird geoeffnet:\n");
37
38
39
// Phase 1
40
for(i=0;i<ZeilenNr-1;i++)
41
{
42
while(ffread()!='\n');
43
}
44
45
// Phase 2
46
n=0;
47
while((get_c=ffread())!='\n')
48
sd_card_string[n++]=get_c;
49
sd_card_string[n]='\0';
50
51
WDH3224_TEXT(20,0,sd_card_string,1,0);
52
rs232_text(sd_card_string);
53
rs232_text("\n");
54
rs232_text("\nEOF\n");
55
ffclose();
56
57
58
}
59
60
else
61
{
62
rs232_text("\nDatei konnte nicht gefunden werden");
63
WDH3224_TEXT(150,2,"Datei konnte nicht gefunden werden",1,1);
64
}
Er gibt mir Datei konnte nicht gefunden werden raus, das Heisst eine
Karte ist eingesteckt und konnte auch initialisiert werden.
LG
Passt schon.
Hab mir die Lib angesehen. Die will ihre 8+3 Filenamen in diesem Format
haben. Nichts desto trotz muss sie bei dir im Windows als "TEST000.TXT"
aufscheinen.
Karl Heinz Buchegger schrieb:> im Windows als "TEST000.TXT">> aufscheinen.Beitrag melden Bearbeiten Löschen
Habe ich eben gerade noch mal ausprobiert, aber auch so klappt da leider
nichts. Ich versteh das nicht wie kann das denn sein das er von einen
auf den anderen tag die datei nicht mehr finden kann?
Ich stolper echt von einem Problem ins nächste... echt mühselig im
Moment
Danke noch mal für die Hilfe