Forum: Mikrocontroller und Digitale Elektronik über SPI in Flash Daten ablegen


von Steff (Gast)


Lesenswert?

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

von so nicht (Gast)


Lesenswert?

Steht doch im Datenblatt des Flashbausteins wie die signale zu sein 
haben. Welcher Flash denn ?

von Steff (Gast)


Lesenswert?

naja, beschrieben wird das nicht so besonders gut. zumindest für einen 
anfänger

von Route_66 (Gast)


Lesenswert?

Such doch mal nach SD-Card-Interface! Die Karten haben Flash intern und 
damit sind die Daten "transportabel".

von Steff (Gast)


Lesenswert?

Hättest du nicht evtl ein Beispiel wie so eine Übertragung geschrieben 
wird?

von Helmut R. (heru01)


Lesenswert?

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

von Steff (Gast)


Lesenswert?

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

von so nicht (Gast)


Lesenswert?

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.

von Steff (Gast)


Lesenswert?

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?!

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

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.

von let (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Steff (Gast)


Lesenswert?

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;
}

von Steff (Gast)


Lesenswert?

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

von Matthias N. (vbchaos)


Lesenswert?

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.

von Steff (Gast)


Lesenswert?

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*

von Steff (Gast)


Lesenswert?

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?

von let (Gast)


Lesenswert?

> 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.

von Steff (Gast)


Lesenswert?

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

von Steff (Gast)


Lesenswert?

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ß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.