Hallo,
Kennt sich hier jemand mit SPI und Flash aus?
Hab einen uC, der seine Daten über i2c von einem Überwachungsbeustein
bekommt.Die Daten, die der uC bekommt sollen in einem Flash über SPI
abgelegt werden.
hab leider noch nie was mit SPI und Flash zu tun gehabt. Kann mir da
jemand weiterhelfen?
wäre sehr dankbar
Hallo Steff,
bitte Details wie:
welcher µC, 'seine Daten' = welche Daten, wieviel?
wo willst Du die Daten stehen haben - welcher Flashbaustein?
muss das unbedingt im Flash abgelegt werden?
So kann Dir schlecht geholfen werden....
Besser ist z.B.:
ich verwende z.B. einen ATMega16 mit xxy ext Baustein über I2C
angebunden.
Diese Daten von Baustein xxy (1k) will ich speichern. Da internes E2Prom
zu langsam ist will ich über SPI auf einen externen Flashbaustein, z.B.
yyyy zugreifen.
etc etc
Gruß
Helmut
Hab nen lpc und das flash ist ein at45db.
will dort daten, wie temperatur, gemessene spannung usw ablegen.
Ja das muss ein flash sein.hab den lpc jetzt mal die pins für SPI
zugewiesen. Mehr aber auch nicht. hab das leider noch nie gemacht.
Ich hoff du kannst mit weiterhelfen
Ja. ein Atmel Datenflash hat RAM speicher, das schreibt man die Daten
rein, und wenn das RAM voll ist wird ins flash kopiert. Man hat 2 RAM
Seiten, sodass man abwechseln kann, resp ein RAM schreiben, waehrend das
andere kopiert wird.
Wie geschieht denn das kopieren vom RAM ins Flash?Machts das
automatisch?
Wie sehen denn solche Routinen aus um ins RAM was reinzuschreiben und
was auszulesen?und die ganze Abfragen zwecks welche Flags gesetzt werden
sollen und welche nicht?
Bin wirklich überfragt. Mit 12c routinen hat das ja garnichts zu tun?!
Steff wrote:
> Wie geschieht denn das kopieren vom RAM ins Flash?Machts das> automatisch?
Zumindest einige Dataflash haben eine Funktion Main Memory Page Program
Through Buffer". Schränkt aber evtl. eher die Möglichkeiten ein.
> Wie sehen denn solche Routinen aus um ins RAM was reinzuschreiben und> was auszulesen?und die ganze Abfragen zwecks welche Flags gesetzt werden> sollen und welche nicht?
Ein paar Ideen kann man sich aus dem Beispielcode der AVR Butterfly und
dem Code zur Application-Note Audio-Recorder with Dataflash (o.ä.)
abschauen. Es gibt auch Beispiele für Dataflash+AT91SAM im AT91
software-package. Sollten zusammen mit dem Datenblatt des DF und der
"Using Dataflash" Application-Note für den Einstieg reichen (alles bei
atmel.com zu finden).
> Bin wirklich überfragt. Mit 12c routinen hat das ja garnichts zu tun?!
Kenne keine DF mit I2C Interface. Habe bisher nur welche über SPI
angesteuert.
Hier mal etwas Code für den Flash Baustein AT45DB041. Ich benutze den
schon eine Weile und bislang ist mir kein Fehler aufgefallen.
Die Routinen sind für einen asynchronen Betrieb ausgelegt d.h.
die Schreibfunktion 'at45_writeBlock()' setzt nur ein paar
Variablen. Geschrieben wird dann über 'at45_doSomeWork()'.
Das mache ich aus folgendem Grund:
Allein das Schreiben der Daten für eine Seite (264 Bytes) dauert bei
8MHz SPI Takt >250µs. Das ist mir zu viel um es innerhalb einer ISR
zu machen. Als lagere ich das aus. Das hat auch den Nebeneffekt
das man sich um Seitengrenzen keine Gedanken zu machen braucht.
Vielen dank für eure Hilfe
Hab aus dem Netz mal folgendes Beispiel gezogen.
Weiß trotzdem noch garnicht wie ich vorgehn soll. Wenn ich die Daten
Tabellenförmig ablegen will(geht das überhaupt?)und die Daten
reinschreib oder rauslesen will. Was wäre denn das notwendigste was ich
da bräuchte ohne viel schnick schnack drumm rumm.
#define SPI_CSB 0x04 // This is PB2 at the port
#define SPI_PORT PORTB
// Function takes in the 8-bit register address and returns 8-bit
register //value.
int CMA3000_Read(unsigned int Address)
{
int result;
result = 0;
Address = Address << 2; // RW bit is set to zero by shifting the bit
// pattern to left by 2
SPI_PORT = SPI_PORT & (~SPI_CSB); // Set CSB to zero
SPDR = Address; // Write command to SPI bus
while(!(SPSR & (1 << SPIF))); // Wait until data has been sent
SPDR = 0x00; // Send dummy data to enable next 8 bit
clocking
while(!(SPSR & (1 << SPIF))); // Wait until data has been sent
result = SPDR; // Get the result
SPI_PORT = SPI_PORT | SPI_CSB; // Set CSB to one
return result;
}
Kannst du mir evtl sagen woher oder warum die folgende Zeile so
schreiben kann?
#define AT45_writeBlock spi0_writeBlock
Wie setzt sich denn die 84 zusammen?
#define CMD_BUFFER_WRITE 0x84
man bin ich überfordert
Ja bist du, und die Aufgaben die du dir stellst, bzw. von denen ich
mittlerweile ausgehe, dass sie dir gestellt werden, ueberschreiten
deinen momentanen Horizont, sowohl was die Programmiersprache angeht als
auch die Kenntnisse von Hardware bzw. der uCs.
Du solltest zuerst mal ein C-Buch lesen, dann wuerden sich dir solche
Fragen wie oben bezueglich des #defines schonmal nicht mehr stellen.
Dann solltest du mal ein paar Uebungsaufgaben aus den Tutorials
durcharbeiten und vielleicht mit einem nicht ganz so maechtigen
Controller anfangen. Es macht keinen Sinn und hat etwa den Lerneffekt
von NULL, wenn du dir Beispiele und fertigen Code aus dem Netz
zusammenklaubst und dann krampfhaft versucht, ihn zu verstehen.
Andersrum macht es Sinn: Datenblatt lesen und verstehen, und dann selber
Code erarbeiten. Das ist am Anfang zwar frustrierend, aber bei eigenem
Code und "selbst" gebauten Fehlern wirst du hier von Vornherein schon
mehr Hilfe bekommen als wenn du den Leuten irgendwas Fremdes vorsetzt.
Nebenbei schult das ganze deinen Programmierstil in Bezug auf
Formatierung, Lesbarkeit, Struktur usw...
Zu deinen Fragen:
1
#define AT45_writeBlock spi0_writeBlock
Der Compiler ersetzt VOR dem eigentlichen Uebersetzen (daher
PRE-Prozessor Anweisung) alle "AT45_writeBlock" im Quellcode mit
"spi0_writeBlock" Nicht mehr, nicht weniger.
Woher die HEX 84 kommen, kann dir ausser dem Autor vermutlich keiner
sagen. 0x84 ist ein recht krummer Wert. Wird aber sicherlich seine
Berechtigung haben.
Ja danke, du hast schon recht.
Hab mir das ganze nicht selbst zur Aufgabe, sondern muss es einfach
irgendwie hinbekommen, obwohl mir sehr viele Vorkenntnisse fehlen.Die
i2c Kommunikation hab ich auch irgendwie hinbekommen.
Das mit: Der Compiler ersetzt VOR dem eigentlichen Uebersetzen (daher
PRE-Prozessor Anweisung) alle "AT45_writeBlock" im Quellcode
mit
"spi0_writeBlock" Nicht mehr, nicht weniger.
hab ich schon gewusst. Nur nicht was in spi0_writeBlock drinn steht
nicht.
Oder ist damit nur gewollt, das man sowohl spi0_writeBlock, als auch
AT45_writeBlock schreiben kann?
Es ist halt auch sehr schwer irgendwas zu lesen(Datanblätter usw.) und
daraus irgendwas zu programmieren, ohne irgendwann mal was davon gesehn
zu haben. Das ist bei dem SPI genau mein Problem. Wenn ich so ein
Datenblatt seh, kann ich nicht all so viel damit anfangen. Müsste
wenigstens mal ein Beispiel oder so dazu gesehn haben. Glaub da geht es
vielen so.Jetzt hab ich mich wiederholt*g*
Kannst mit evtl nur sagen wie ich die Initialisierung von dem SPI
vorhehm?
Also ich meine nicht das du mir das alles ausrechnest oder was da alles
zu tun ist. Wäre nett wenn du mir einen Anhaltspunkt geben könntest, wie
man da am besten vorgeht.
Wird zuerst SPI initialisiert und dann noch eine read und eine write
routine?
> Kannst du mir evtl sagen woher oder warum die folgende Zeile so> schreiben kann?> #define AT45_writeBlock spi0_writeBlock
Ich bin einfach schreibfaul um habe keine Lust Code jedesmal
neu zu erstellen nur weil ich einen andere Schaltung oder
einen anderen Controller verwende (AVR/ARM/PIC).
Der Code verwendet für hardwareabhängige Dinge Makros, manchmal
auch Funktionen, anstatt direkt auf irgendwelche Platformabhängigen
Teile zuzugreifen. Wenn ich den Code portieren will muß ich
nur diese Makros oder hal_xxx() Funktionen anpassen und das war es
dann (eigentlich).
An der Stelle von 'AT45_writeBlock' wird eine Funktion erwartet
die Daten an den Speicher schicken kann. Wie sie das anstellt/welches
Protokoll verwendet wird ist dabei egal.
> Wie setzt sich denn die 84 zusammen?> #define CMD_BUFFER_WRITE 0x84
Das steht im Datenblatt zum Flashbaustein. Damit sagt man
ihm das als nächstes Daten für den internen 264 Byte Puffer
folgen.
Flash kann nur in Blöcken beschrieben werden, wobei schreiben
bedeutet das Bits auf '0' gesetzt werden. Man kann aus einer
'0' keine '1' machen. Daher muß der entsprechende Block erst
gelöscht werden (page erase - setzt alles auf '1') bevor man
ihn beschreibt. Man beschreibt also den Puffer und teilt dem
at45 anschließend mit dem 'buffer to page' Befehl mit den
Pufferinhalt in den angegebene (und hoffentlich vorher gelöschten)
Block im Flash zu schreiben.
Die SPI Einheit wird in spi1_init() in spi1.c initialisiert.
Der Aufruf erfolgt in der main() Funktion:
1
spi1_init(MODE_0,BITS8,false,4);
Bei meiner Konfiguration (SSP_PCLK = PCLK = CCLK) führt das
zu einer Taktrate von 18MHz.
Kann mir hier jemand sagen wie das mit den einzelnen Bits der Register
aussieht?
Sind die Bits, z.B. CPHA und CPOL vom SPI Control Register Bits zum
abfragen oder muss ich die je nach belieben einfach nur setzen oder auch
nicht?
Komme bei der Initialisierung immer noch nicht weiter. Was sind denn die
wichtigsten Punkte was man dabei beachten muss und dabei vorgeht? Aus
den ganzen Beispielen kann ich irgendwie nichts auf meine
Aufgabenstellung ableiten.
Was fang ich denn mit VICVectAddr0 an? Was stell ich denn dort ein?
Danke schonmal
Hallo,
hätte nochmal eine Frage wegen dem Flash.
Das beschreiben und auslesen vom Flash müsste jetzt soweit
funktionieren.
Geb beim lesen und schreiben einen zähler mit. Wie kann ich denn dem
Flash z.B. nachdem er 500mal beschreiben wurde, das er dann wieder von
neuem anfängt. Wird der Flash dann automatisch überschreiben oder muss
ich die vorhandenen Werte darin löschen?
Kann mir da jemand weiterhelfen?
Wie mach ich denn das das ich die Daten timergesteuert in das Flash
schreibe, z.B. alle 3 Minuten oder so?
gruß