while((Flash_impl_readFlashStatus(me)&0b00000001))//warten bis ready
33
;//wenn bereit, dann weiter
34
35
SS_FLASH=0;
36
spi(READ_ARRAY);
37
spi((unsignedchar)(0x00));
38
spi((unsignedchar)(0x07));
39
spi((unsignedchar)(0XD0));
40
spi(0);
41
temp=spi(0);
42
putchar1(temp);
43
temp=spi(0);
44
putchar1(temp);
45
temp=spi(0);
46
putchar1(temp);
47
temp=spi(0);
48
putchar1(temp);
49
temp=spi(0);
50
putchar1(temp);
51
temp=spi(0);
52
putchar1(temp);
53
temp=spi(0);
54
putchar1(temp);
55
putchar1(' ');
56
SS_FLASH=1;
57
58
putchar1('T');
59
putchar1(':');
60
putchar1(data);
61
}
Ich verwende den Codevisioncompiler und dort ist die Funktion spi wie
folgt definiert:
unsigned char spi(unsigned char data);
Beim obigem Code erhalte ich folgende Ausgabe:
d:s 1230abc T:s
>>wenn ich einzelne char's ins Flash speichere, so kann ich diese auch wieder
auslesen, aber nicht die übergebene unsigned char Variable "data"!!!
Schlimmer noch wird es, wenn ich statt der konstanten Adresse beim Lesen
und beim Schreiben
1
2
spi((unsignedchar)(address>>16));
3
spi((unsignedchar)(address>>8));
4
spi((unsignedchar)(address));
ersetze, dann kann ich gar nichts mehr aus dem Flash ausgeben nur \0
Woran sollte das liegen?? Ich dachte, dass es keinen Unterschied macht
ob ich
spi((unsigned char)(0x00));
spi((unsigned char)(0x07));
spi((unsigned char)(0XD0));
oder
address = 2000;
spi((unsigned char)(address >> 16));
spi((unsigned char)(address >> 8));
spi((unsigned char)(address));
schreibe. Anscheinend liege ich falsch, warum??
Hallo Stefan,
ich ab da ein paar Fragen:
- Wann löscht du das Flash? Flash Speicher kann nämlich nicht so
beschrieben werden wie ein RAM -> siehe Datasheet.
- Wenn du debuggst, kannst du dir den Inhalt von Variablen ja ansehen,
probier doch mal:
1
unsignedlongintaddress=2000;
2
unsignedchartest;
3
4
test=(unsignedchar)address>>16;
5
spi(test);
6
test=(unsignedchar)address>>8;
7
spi(test);
8
test=(unsignedchar)address;
9
spi(test);
Was steht in test, jeweils vor Ausführung des spi Befehls? das
"Erwartete"?
- Was ist SS_FLASH?
- Um welche CPU handelt es sich? Bei Compiler (bzw ev. IDE) um welche
Version?
Grüße
Hallo Bernhard,
das ist ja das komische, wenn ich mir dir die test-Variablen ausgebe,
erhalte ich
00 07 D0
als char-Werte. Also genau das was ich erwartet habe. Und selbst die
data-Variable die sowieso schon vom Typ unsigned char ist bekomme ich
nicht richtig wieder, kommischerweise einzelne konstante Zeichen wie 'a'
schon.
Löschen kann ich den Baustein, mache ich dazwischen aber nicht. Das
externe Flash wird über SPI aufgerufen und SS_FLASH ist das ChipSelect
dafür. Ich kann auch die ID des Bausteins auslesen, die grundsätzliche
Kommunikation funktioniert also.
Ach ja und der Mikrocontroller zum Ansteuern ist ein Atmega128.
- Was passiert, wenn du die test Variable an die spi Funktion als
Adresse übergibst? Verhält sich die Kommunikation dann auch "falsch"?
- Zum Thema löschen: wenn du an die Stelle 0x07D0 im Flash 0x00
schreibst, kann diese Stelle bis zum nächsten löschen nicht mehr
beschrieben werden. Wie stellst du sicher, dass beim Beschreiben des
Flash der "Ziel" Speicherblock gelöscht ist? Wenn du nämlich im 2.
Durchgang an die Stelle 0x07D0 0x10 schreiben willst, wird dort
weiterhin 0x00 stehen -> bis nach dem Löschen (das "setzt" den Speicher
auf 0xFF).
Hallo
ist das mit dem Beschreiben wirklich so? Ich wollte das externe Flash
als Ringspeicher nutzen, doch diese Anwendung wäre ja dann nicht
möglich!
Ist es nur bei dem Wert 0x00 so, oder kann ich generell ein Byte nicht
mehr überschreiben ohne es vorher zu löschen??
Wenn ich z.B. die Zelle vorher mit 0x0F beschrieben habe, kann ich sie
dann mit 0xF0 überschreiben??
Stefan schrieb:> Wenn ich z.B. die Zelle vorher mit 0x0F beschrieben habe, kann ich sie> dann mit 0xF0 überschreiben??
Nein. "Schreiben" bezeichnet immer nur einen der beiden möglichen
Bit-Wechsel (in der Regel von 1 nach 0). Die andere Richtung nennt sich
dann "Löschen". Von 0x0F nach 0xF0 beinhaltet aber beide Richtungen.
Stefan schrieb:> Ist es nur bei dem Wert 0x00 so, oder kann ich generell ein Byte nicht> mehr überschreiben ohne es vorher zu löschen??
Du kannst ein Bit durch schreiben nur von 1 auf 0 setzen. Von 0 auf 1
geht nur duch löschen. Einmal 0, bleibt es auch nach x mal 1 drauf
"schreiben" 0....einen Flash als Ringspeicher ist natürlich ziemlich
daneben. Nimm seriellen SRAM, den gibts mittlerweile. Zum Beispiel hier:
http://www.ipsilog.com/content/index.php?id=5 oder hier:
http://www.onsemi.com/PowerSolutions/parametrics.do?id=2206
Flash hält Daten auch stromlos zur Verüfung und wird daher meist zum
Ablegen des Programmcodes oder von statischen Daten verwendet. Sollen
Daten wie ein Ringbuffer verwendet werden ist ein Flash das denkbar
ungünstigste Bauteil *).
Wenn die Daten im Buffer einen Stromausfall/ein Abschalten überdauern
sollen, kannst du auch z.b. ein (serielles) FRAM verwenden, ansonsten
eben ein (serielles) SRAM.
*) er "hält" auch nur für eine gewisse Anzahl Löschzyklen, danach können
einzelne Zellen ausfallen.
Man kann Flash-Speicher durchaus als (Ring-)Speicher z.B. für einen
Datenlogger verwenden. Ob diese Art Speicher geeignet ist oder nicht,
hängt hauptsächlich vom Datenaufkommen ab, da für Flashspeicherzellen
bzw. -seiten nur eine begrenzte Zahl möglicher Schreib-/Löschzyklen
garantiert wird (oft 10000). Programmierung der Speicherveraltung ist
wegen der üblichen seitenweisen Organisation von Flashspeicher nicht
ganz trivial, aber zu machen.
Was möchtest du denn genau machen?
Bei einem Ringbuffer kannst du so vorgehen (allgemeiner RB
vorausgesetzt):
Block/Seite/Page: kleinste Einheit im Flash, die gelöscht werden kann
Blockgröße/Seitengröße/Pagesize: von Flash zu Flash verschieden - siehe
Datenblatt
- Initialisierung (= Blöcke löschen) - Bsp. mit mehreren Blöcken
- Daten beginnend von der Startaddresse reinschreiben
- Ist ein Block voll wird in den nächsten geschrieben
- erreicht der Lesepointer das Blockende, wird der Block gelöscht
- ist der Schreibpointer "hinter" dem Lesepointer und im selben Block
wie dieser, ist der Buffer (zusätzlich zu den Bedingungen des normalen
RB) voll.
Der eigentliche Unbterschied zu einem normalen RB wäre die Prüfung auf
einen vollen Buffer und dass der RB (vernünftigerweise) nicht kleiner
als 2 Blöcke sein soll.
Problem: du solltest versuchen alle Blöcke des Flash gleichermaßen zu
verwenden, da sonst Teile des Chips schneller altern (Löschzyklen).
Daher kann es vorteilhaft sein, jeweils am Anfang des Blockes einige
wenige Bytes Verwaltungsinformation zu speichern, die dir sagen wie oft
der Block gelöscht wurde und ob er voll oder leer ist. Es kann auch
geschickt sein, für die Verwaltungsinformation*) ein verhältnismäßg
teures, aber kleines NV-RAM zu verwenden und das Flash für die
eigentlichen Daten.
*) in diesem Falle Daten zu den Speicherblöcken und Buffer-Pointer