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
Steht doch im Datenblatt des Flashbausteins wie die signale zu sein haben. Welcher Flash denn ?
naja, beschrieben wird das nicht so besonders gut. zumindest für einen anfänger
Such doch mal nach SD-Card-Interface! Die Karten haben Flash intern und damit sind die Daten "transportabel".
Hättest du nicht evtl ein Beispiel wie so eine Übertragung geschrieben wird?
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ß
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.