FRAM Speicher bis 512 kBit
Wer in seiner Anwendung die Vorteile eines EEPROMs nutzen, sich aber über die maximale Anzahl von Schreibzyklen keine Sorgen machen möchte, der sollte sich die Verwendung von FRAMs überlegen. Mit bis zu 1 Billionen (10 hoch 12) Schreibzyklen schlägt es das EEPROM (ca. 1 Million Schreibzyklen) um den Faktor 1 Million. Das bedeutet, dass z.B. bei einem Schreibvorgang alle 10 ms ein EEPROM weniger als 3 Stunden lang beschrieben werden kann, ein Flash-Speicher (maximal 100.000 Schreibzyklen) weniger als 0,3 Stunden und ein FRAM 300 Jahre(!!) lang. Neuere FRAMs geben sogar 10 Billionen (10 hoch 13) Schreibzyklen an. Eine vielfach höhere Schreibgeschwindigkeit, einem Bruchteil des Stromverbrauches (bei Schreibvorgängen) und eine höhere Resistenz gegenüber Strahlung (z.B. bei Überprüfung des Gepäcks auf Flughäfen) sind weitere Vorteile gegenüber dem EEPROM. Die Retention der Daten (Datenerhalt) soll bei Raumtemperatur mindestens 200 Jahre und bei 85 °C immerhin noch 10 Jahre betragen (meine Ur-Ur-Ur-Enkel werden dann im Jahr 2217 berichten).
Bild: FRAM-Breakout Boards von Adafruit mit I2C-Schnittstelle (oben) und SPI-Schnittstelle (unten)
Die von mir verwendeten Breakout Boards von Adafruit sind mit FRAMs der Firma Fujitsu Semiconductor der Serie MB85Rxxxx bestückt, das I2C-Board mit einem 256 kBit Chip MB85RC256V und das SPI-Board mit einem 64 kBit Chip MB85RS64V.
Datenblätter zu den Chips gibt es hier: www.fujitsu.com/uk/products/devices/semiconductor/memory/fram/standalone/
Testaufbau mit I2C-Schnittstelle:
I2C-Adresse:
Die I2C-Adresse des Moduls kann durch Beschalten der Eingängen A2 bis A0 mit GND oder VCC zwischen 0x50 (A2-A0 auf GND) und 0x57 (A2-A0 auf VCC) eingestellt werden. Ohne Beschaltung liegen bereits die Adresseingänge durch interne Pulldown-Widerstände auf logisch Null, daher ist für die Adresse 0x50 keine Beschaltung erforderlich.
Verwendete Bauteile:
- 1 Arduino Nano
- 1 FRAM Breakout Board 256 kBit von Adafruit
Anschluss des FRAM (I2C-Adresse 0 0x50) an Arduino Uno/Nano und Mega:
Arduino FRAM-Breakout Board (I2C)
Uno/Nano Mega
5V 5V -> VCC
GND GND -> GND
A5 D21 -> SCL
A4 D20 -> SDA
GND GND -> A2
GND GND -> A1
GND GND -> A0
Nicht verwendet: WP 1)
1) WP = "Write Protect"-Pin, intern auf Pull-Down gesetzt. Durch HIGH-Setzen des Pins wird der Schreibschutz des FRAM-Speichers gesetzt!
Testaufbau mit SPI-Schnittstelle:
Verwendete Bauteile:
- 1 Arduino Nano
- 1 FRAM Breakout Board 64 kBit von Adafruit
Anschluss des FRAMs an Arduino Uno/Nano und Mega:
Arduino FRAM-Breakout Board (SPI)
Uno/Nano Mega
5V 5V -> VCC
GND GND -> GND
D13 D52 -> SCK (CLK)
D12 D50 -> MISO
D11 D51 -> MOSI
Dx Dx -> CS
Nicht verwendet: HOLD und WP 1)
Dx: Während die Pins für CLK, MISO und MOSI am Arduino fix vorgegeben sind (Hardware-SPI), kann der CS-Pin (Chipselect) softwaremäßig frei vergeben werden. Im nachfolgenden Beispiel wird für Dx der Pin D10 verwendet.
1) WP = "Write Protect"- Pin. Durch LOW-Setzen des Pins wird nur der Schreibschutz des Status-Registers des FRAM gesetzt. Der Schreibschutz des FRAM-Speichers selbst, wird softwaremäßig gesetzt!
Library MyFRAM_I2C und MyFRAM_SPI:
Für Arduino habe ich für FRAMs - mit Speichergrößen bis 512 kBit (= 64 kByte) - mit I2C- und (Hardware-)SPI-Schnittstelle zwei Libraries mit folgenden Funktionen geschrieben:
Mit I2C-Schnittstelle:
- Abfrage, ob der Baustein ansprechbar ist
- Schreiben eines Byte
- Schreiben einer Folge von Bytes (max. 30)
- Vergleichen eines Speicherbereichs mit einem Array
- Festlegen der FRAM-Startspeicherstelle für Float- und Integer-Zahlen 1)
- Schreiben einer Integer-Zahl (im long-Format) 1)
- Schreiben einer Float-Zahl 1)
- Lesen eines Byte
- Lesen einer Folge von Bytes (max. 30)
- Lesen einer Integer-Zahl (im long-Format) 1)
- Lesen einer Float-Zahl 1)
- Löschen eines Bytes
- Löschen eines Bereiches
- Löschen des gesamten FRAMs
Mit SPI-Schnittstelle:
- Setzten/Rücksetzen des Schreibschutzes
- Schreiben eines Byte
- Schreiben einer Folge von Bytes
- Vergleichen eines Speicherbereichs mit einem Array
- Festlegen der FRAM-Startspeicherstelle für Float- und Integer-Zahlen 1)
- Schreiben einer Integer-Zahl (im long-Format) 1)
- Schreiben einer Float-Zahl 1)
- Lesen eines Bytes
- Lesen einer Folge von Bytes
- Lesen einer Integer-Zahl (im long-Format) 1)
- Lesen einer Float-Zahl 1)
- Löschen eines Bytes
- Löschen eines Bereiches
- Löschen des gesamten FRAMs
1) Es können derzeit maximal 255 Float- und/oder Integer-Zahlen, die mit Variablennamen ansprechbar sind, im FRAM gespeichert werden! Die Zahlen werden, sofern nicht anders angegeben, ab der FRAM-Speicherstelle 0 gespeichert. Mit der Funktion "setStartAddress32Bit" kann diese "Startspeicherstelle" geändert werden (siehe nachfolgendes Programmbeispiel 1).
Die Libraries habe ich bisher nur mit FRAMs auf Adafruit Breakout Boards getestet, die mit Chips der Firma Fujitsu Semiconductor der Serie MB85Rxxxx bestückt sind, das I2C-Board mit einem 256 kBit Chip MB85RC256V und das SPI-Board mit einem 64 kBit Chip MB85RS64V. Inwieweit diese Chips mit FRAM-Chips anderer Hersteller kompatibel sind, habe ich bisher nicht geprüft!
Die maximale Speichergröße der FRAMs darf derzeit maximal 512 kBit (= 64 kByte) betragen. Größere FRAMs, die, soweit mir bekannt, heute mit bis zu 4 MBit (= 512 kByte) erhältlich sind, werden von den Libraries wegen der unterschiedlichen Speicherplatzadressierung (24 Bit anstelle von 16 Bit) derzeit nicht unterstützt. Sollte ich einmal ein FRAM Breakout Board mit mehr als 512 kBit erwerben, werde ich die Libraries entsprechend anpassen.
Erkennen der Speichergröße bei FRAMs mit SPI-Schnittstelle:
Aus vielen FRAM-Speicherchips mit SPI-Schnittstelle der Firma Fujitsu Semiconductor kann die Speichergröße mit dem Kommando (= OP-Code) "RDID" (Read Device ID) ausgelesen werden, z.B. bei den Chips:
- MB85RDP16LX
- MB85RS16
- MB85RS16N
- MB85RS64V
- MB85RS128B
- MB85RS256V
- MB85RS512T
- MB85RS1MT (wird derzeit von der Library nicht unterstützt)
MB85RS2MT (wird derzeit von der Library nicht unterstützt)
Bei diesen Chips kann eine neue Instanz ohne Angabe der Speichergröße erfolgen, z.B.:
MyFRAM_SPI fram;
Nicht ausgelesen werden kann die Speichergröße z.B. aus dem Chip:
- MB85RS64
Hier muss die Speichergröße angegeben werden, z.B.:
MyFRAM_SPI fram(64) //FRAM mit 64 kByte
Die Libraries können hier heruntergeladen werden:
Sollte die Library jemand verwenden oder testen, würde ich mich über eine Rückmeldung sehr freuen!
Version 1.2 Version 1.3
Für FRAMs mit SPI-Schnittstelle: Für FRAMs mit I2C-Schnittstelle:
MyFRAM_SPI.cpp.txt MyFRAM_I2C.cpp.txt
MyFRAM_SPI.h.txt MyFRAM_I2C.h.txt
Leider kann ich hier keine "cpp"- oder "h"-Files hochladen, daher zum Verwenden der Libraries das Suffix ".txt" aus diesen Dateinamen entfernen und in neuen Verzeichnissen mit dem Namen "MyFRAM_SPI" bzw. "MyFRAM_I2C" im Sketchbook-Ordner im Ordner "libraries" speichern.
Zur Auflistung der Funktionen der Libraries geht es hier: Funktionen
Ein FRAM-Mini-Monitor für FRAMs mit I2C- oder SPI-Schnittstelle zum Anzeigen und Löschen des Speicherinhaltes ist im nachfolgenden Programmbeispiel 2 ersichtlich!
Programmbeispiel 1 MyFRAM_SPI:
Im Beispiel 1 werden Float-Zahlen, die nicht im SRAM des Arduino, sondern im FRAM gespeichert sind, für eine Flächenberechnung verwendet. Dabei können bis zu 255 Float- oder Integer-Zahlen (im long-Format) ab einer definierbaren FRAM-Speicherstelle gespeichert werden, ohne sich dabei um die Speicheradresse der einzelnen Variablen kümmern zu müssen. Die Variablen werden über Namen angesprochen, die im Deklarationsteil des Programms mit #define-Anweisungen definiert werden, z.B.:
#define breite 2
In diesem Beispiel ist der Name der Variable "breite" und die "2" ist die Identifikationsnummer ID (diese kann 1 bis 255 betragen). Die ID sollte, um den vorgesehenen FRAM-Speicher optimal auszunutzen, beginnend mit "1" aufsteigend sein und darf nicht doppelt oder mehrfach vergeben werden.
Der Sinn, Float- und/oder Integer-Variable im long-Format in den FRAM-Speicher zu legen, liegt darin, dass z.B. beim Arduino Uno oder Nano (bzw. Mikrocontroller mit Atmega328P-Pozessor) der SRAM-Speicher nur 2 kByte beträgt und oft sehr schnell knapp wird, während im Programmspeicher (Flash-Speicher) noch Platz ist, um die Library zu verwenden.
//Programmbeispiel für FRAM mit SPI-Schnittstelle
//Code fuer Arduino
//Author Retian
//Version 1.1
#include <MyFRAM_SPI.h>
//Wenn aus dem FRAM die Speichergröße ausgelesen werden kann:
MyFRAM_SPI Fram;
//Wenn aus dem FRAM die Speichergröße nicht ausgelesen werden kann:
//MyFRAM_SPI Fram(64); //FRAM mit 64 kBit
//Startadresse für die 4-Byte Variablem im FRAM
//Hier werden die letzten 256 Bytes im FRAM für 4-Byte Variablen vorgesehen.
//Ohne Angabe würde die Startadresse die FRAM-Adresse 0 sein!
#define startAdresse 7936
//Definiere FRAM-Variable mit Identifier (1-255) für Float- und/oder Long-Zahlen
#define laenge 1
#define breite 2
#define flaeche 3
void setup() {
Serial.begin(115200);
Fram.begin(10); //Digital-Pin 10 ist Chip Select Pin
Fram.setWriteEnableBit(1); //Schreibschutz Aus
//Frage des Schreibschutzstatus ab
if (Fram.getWriteEnableBit()) Serial.println("Schreibschutz Aus");
else Serial.println("Schreibschutz Ein");
//Setze startadresse fuer 4-Byte Variable im FRAM
Fram.setStartAddress32Bit(startAdresse);
Serial.print("Speichergröße des FRAM: ");
Serial.print(Fram.framSize);
Serial.println(" Byte");
//Speichere Zahlen im FRAM
Fram.writeFloat(laenge, 45.2);
Fram.writeFloat(breite, 26.1);
//Berechnen der Flaeche und speichern im FRAM
Fram.writeFloat(flaeche, Fram.readFloat(laenge) * Fram.readFloat(breite));
//Ausgabe
Serial.println("\nFlaechenberechnung:");
Serial.print("Laenge: ");
Serial.println(Fram.readFloat(laenge));
Serial.print("Breite: ");
Serial.println(Fram.readFloat(breite));
Serial.print("Flaeche: ");
Serial.println(Fram.readFloat(flaeche));}
void loop() {
}
Programmbeispiel 2:
Mini-Monitor für FRAMs mit I2C- und SPI-Schnittstelle
Der Mini-Monitor dient zur einfachen Überprüfung und Löschung des FRAM-Inhaltes. Nach Programmstart muss die Speichergröße (in kByte), sowie die Art der Schnittstelle I2C oder SPI angegeben werden. (Für die I2C-Schnittstelle ist die Adresse 0x50 und für die SPI-Schnittstelle der CS-Pin mit 10 im Programm vorgegeben.) Danach stehen derzeit die folgende Funktionen zur Verfügung, die über Zifferneingabe aufgerufen werden können:
- Anzeigen des gesamten FRAM-Inhalts
- Anzeigen eines FRAM-Bereiches
- Löschen des gesamten FRAMs
- Löschen eines FRAM-Bereiches
Je nach Bedarf werde ich den Funktionsumfang noch erweitern.
Der Monitor kann hier in der Version 1.2 heruntergeladen werden:
FRAM_Mini-Monitor.ino.txt
Leider kann ich hier keine "ino"-Files hochladen, daher zum Verwenden des Programms ".txt" aus dem Dateinamen entfernen und in einem neuen Verzeichnis mit dem Namen "FRAM_Mini-Monitor" dort speichern, wo eure anderen Programme gespeichert sind.
Der Mini-Monitor benötigt neben meinen Libraries MyFRAM_I2C V1.2 und MyFRAM_SPI V1.2 auch meine Library MySerialRead, die hier zu finden ist: Serieller Monitor
Bild: FRAM-Mini-Monitor Programmstart und Anzeige des FRAM-Inhalts partiell mit Angabe des Adressbereiches