INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
FRAM am Arduino
06.09.2016, 22:46 (Dieser Beitrag wurde zuletzt bearbeitet: 07.09.2016 00:01 von ardu_arne.)
Beitrag #1
FRAM am Arduino
Ein FRAM (Ferroelectric Random Access Memory) ist kurz beschrieben ein nichtflüchtiger Schreib-Lese-Speicher.
Im Vergleich zu einem EEPROM kann ein FRAM aber schneller und öfter beschrieben werden.

Ein paar Links zu gängigen FRAM-Typen:
FM24C04B 4-Kbit (512 × 8) Serial (I2C) F-RAM
FM24C16B 16-Kbit (2 K × 8) Serial (I2C) F-RAM
FM24C64B 64-Kbit (8 K × 8) Serial (I2C) F-RAM

FRAMs sind mit I²C-, SPI- und Parallel-Interface erhältlich.
Die o.g. Typen haben alle ein I²C-Interface und sind deshalb leicht am Arduino zu verwenden.

Entstanden ist diese Thema aus Einzelbeiträgen zu einem Beitrag über die I²C Buffergrösse.
Folgend werden als Einstieg die relevanten Beiträge aus dem anderen Thema verlinkt.

Gruß
Arne

(04.09.2016 18:44)ardu_arne schrieb:  
(04.09.2016 17:29)Mathias schrieb:  ...
Ich werde am besten das Problem umgehen, in dem ich mehrere Pakete schicke.
Das ist sicher die beste Lösung wenn das machbar ist.

Dennoch Dank an dich dass du diese Frage gestellt hast, sonst wäre ich bald in das gleiche Messer gelaufen. Smile
Ich bin gerade dabei ein FRAM via I²C an den Arduino zu klemmen.
Ein-, Zwei- und Vierbyte-Variablen schreiben und lesen geht schon. Die Bytes werden dabei einzeln verarbeitet.

Das FRAM hat aber auch einen "Multi-Byte Write" Modus. Dazu sendet man erst eine Startadresse und dann Datenbytes, theoretisch bis der Speicher voll ist. Man könnte also den Inhalt einer struckt-Variablen mit z.B. 100 Byte komplett am Stück wegschreiben. Mit der jetzt erkannten Einschränkung auf 32 Byte kann ich den Versuch dann begraben.

Gruß
Arne

(04.09.2016 19:46)Tommy56 schrieb:  
(04.09.2016 18:44)ardu_arne schrieb:  Dennoch Dank an dich dass du diese Frage gestellt hast, sonst wäre ich bald in das gleiche Messer gelaufen. Smile
Ich bin gerade dabei ein FRAM via I²C an den Arduino zu klemmen.
Ein-, Zwei- und Vierbyte-Variablen schreiben und lesen geht schon. Die Bytes werden dabei einzeln verarbeitet.

Welches FRAM hast Du? Bei mir liegen ein paar FM24C16B rum, um die ich mich irgendwann mal kümmern will.
Machst Du eine Lib draus? Wenn ich die Winzlinge auf eine Platine gelötet bekomme, könnte ich testen.

Gruß Tommy

(04.09.2016 21:05)ardu_arne schrieb:  Ich habe ein FM24C04B, ein FM24C16B und ein FM24C64B zum testen hier. Adapterplatinchen habe ich verwendet um die "Kleinen" auf DIP8 Format zu bringen.
Eine Lib bauen will ich nicht, habe keine Ahnung davon. Confused

Am einfachsten zu handhaben ist ein FM24C64B. Der erhält per I²C eine 16 Bit Adresse für die Speicherzelle und damit kann man den von 0x0000 bis 0x1FFF linear durchadressieren.

Beim FM24C04B und FM24C16B wird über I²C nur eine 8 Bit Adresse für die Speicherzelle übertragen. Deshalb muss man dort zusätzlich die Adresspins A0, A1, A2 für ein Pageselect bedienen. Das kostet zusätzliche Pins am Arduino.

Für die gängigen Datenformate läuft inzwischen alles auch mit 400kHz I²C-Takt. Smile
Ich will mir zum Testen mal die FM25C160B besorgen die per SPI bedient werden.

Gruß
Arne

(05.09.2016 19:35)Tommy56 schrieb:  
(04.09.2016 21:05)ardu_arne schrieb:  Am einfachsten zu handhaben ist ein FM24C64B. Der erhält per I²C eine 16 Bit Adresse für die Speicherzelle und damit kann man den von 0x0000 bis 0x1FFF linear durchadressieren.

Beim FM24C04B und FM24C16B wird über I²C nur eine 8 Bit Adresse für die Speicherzelle übertragen. Deshalb muss man dort zusätzlich die Adresspins A0, A1, A2 für ein Pageselect bedienen. Das kostet zusätzliche Pins am Arduino.

Hallo Arne,

laut meinem Datenblatt hat der FM24C16B aber keine Adresspins. Nur SDA, SCL, VCC, VSS und WP (WriteProtect). Die Pins 1-3 sind Not Connected.

Gruß Tommy

(06.09.2016 15:36)ardu_arne schrieb:  
(05.09.2016 19:35)Tommy56 schrieb:  ...

Hallo Arne,

laut meinem Datenblatt hat der FM24C16B aber keine Adresspins. Nur SDA, SCL, VCC, VSS und WP (WriteProtect). Die Pins 1-3 sind Not Connected.

Gruß Tommy

Oh Sorry,
ich hatte die Datenblätter des FM24C04B und FM24C16B nur kurz überflogen ohne tiefer hinein zu lesen. Du hast recht, der FM24C16B hat keine Adresspins.
Intern hat er 8 Pages zu je 256 Byte. Diese werden über die Slave Addresse angesprochen. Der belegt also am I²C Bus die Adressen 50...57.
Ich frage mich gerade wie es möglich wäre mehrere FM24C16B am Arduino zu betreiben, weil einen CS-Pin hat der auch nicht?

Gruß
Arne

(06.09.2016 18:58)Tommy56 schrieb:  
(06.09.2016 15:36)ardu_arne schrieb:  Intern hat er 8 Pages zu je 256 Byte. Diese werden über die Slave Addresse angesprochen. Der belegt also am I²C Bus die Adressen 50...57.
Ich frage mich gerade wie es möglich wäre mehrere FM24C16B am Arduino zu betreiben, weil einen CS-Pin hat der auch nicht?
Hallo Arne,

ich gehe davon aus, dass die 50...57 Hex sind. Das hilft mir erstmal schon weiter. die 5 als höherwertigen Teil habe ich bisher nicht gefunden/übersehen.
Da wird man wohl nur einen IC anschließen können.
Ich probiers mal aus, wenn er meine Lötung überstanden hat.

Edit: Ich habe mir das noch mal im Datenblatt angeschaut. Der Aufbau der Adresse für den FM24C16B ist noch etwas anders: Bit 7...4 = A Hex(1010 Binär). Bit 3...1 wählen die Page und Bit 0 zeigt an, ob es ein Schreibzugriff (0) oder ein Lesezugriff (1) ist.

Gruß Tommy

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.09.2016, 07:50
Beitrag #2
RE: FRAM am Arduino
Hallo Tommy,
die Adressen sind Hexadezimal also 0x50...0x57 zu verstehen.

Im Datenblatt des FM24C16B ist auf Seite 6 Figure 6 die "Memory Slave Device Address" beschrieben.
Ich muss gestehen, dass ich nicht wirklich verstehe wie die "Memory Slave Device Address" anzuwenden ist. Undecided

Aus Arduino Sicht kann ich ein FM24C16B mit folgenden Routinen von 0x000 bis 0x7FF lesen und beschreiben:
Code:
#include <Wire.h>
#define  F_RAM 0x50  // I2C Adresse des F-RAM
.
.
.
void setup() {
  Wire.begin();
.
.
.
}

void loop() {
.
.
.
}

void F_RAM_write8d (byte value, uint16_t framAddr){
  int dev_adr;
  dev_adr = F_RAM | framAddr >> 8;
  Wire.beginTransmission(dev_adr);
  Wire.write(framAddr & 0xFF);
  Wire.write(value);
  Wire.endTransmission();
}

byte F_RAM_read8d (uint16_t framAddr){
  int dev_adr;
  dev_adr = F_RAM | framAddr >> 8;
  Wire.beginTransmission(dev_adr);
  Wire.write(framAddr & 0xFF);
  Wire.endTransmission();
  Wire.requestFrom(dev_adr, 1);
  return Wire.read();
}
Demnach steht der höherwertige Teil der Speicheradresse (also der Page Select) als "dev_adr" rechtsbündig als Parameter in Wire.beginTransmission(dev_adr);.
Aber das hat nichts mit dem zu tun was in "Memory Slave Device Address" beschrieben ist. Auch mit dem Bit 0 (lesen/schreiben) kann ich nichts anfangen.

Ich verstehe das Datenblatt an der Stelle nicht. Was ich mit meinen Schreib- und Leseroutinen mache entspricht nicht dem was im Datenblatt steht, aber es funktioniert. Huh

Warum Funktioniert mein Sketch und wie ist das Datenblatt zu verstehen?
Laut Datenblatt gibt es auch ein "Multi-Byte Write" und "Sequential Read".
Mit einem FM24C64B wende ich beides bereits an, aber da gibt es keine Pages.
Wie verhält sich aber ein FM24C16B bei "Multi-Byte Write" und "Sequential Read" wenn dabei Pagegrenzen überschritten werden?

Fragen über Frage.
Vielleicht kann jemand etwas Licht ins Dunkel bringen.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.09.2016, 19:54
Beitrag #3
RE: FRAM am Arduino
(07.09.2016 07:50)ardu_arne schrieb:  Wie verhält sich aber ein FM24C16B bei "Multi-Byte Write" und "Sequential Read" wenn dabei Pagegrenzen überschritten werden?

Laut Datenblatt wird dann in der gleichen Page wieder bei 0 angefangen. Das nuss man also im Sketch abfangen, dass man erst bis zur Pagegrenze schreibt und dann mit der neuen Page weiter macht.

Ich habe bisher noch nichts getestet und es kann sein, dass ich erst nächste Woche dazu komme.
Ich werde Deinen Code testen und auch mal schauen, ob ich das Datenblatt umsetzen kann.

Wenn schon jemand Erfahrung mit diesem IC hat, kann er gern auf die Stolpersteine hinweisen.

Der FM24C64B hat aber in Figure 6 auch das niederwertigste Byte der Adresse als R/W-Bit.

Ich habe mir jetzt auch mal ein paar 64er betellt. Da muss man nicht 2 Grenzen (Wire-Lib und Page) beachten.
Wobei sich der Puffer in der Wire-Lib ziemlich einfach ändern läßt. Das sind 2 defines.

Gruß Tommy
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.09.2016, 20:51
Beitrag #4
RE: FRAM am Arduino
Dann ist das Softwareseitig auch umständlich wenn man bei den "kleinen" auf die Pagegrenzen achten muss. Unabhängig davon das der Wire Puffer nur 32 Byte (defaul) kann, muss man an der Pagegrenze das Schreiben beenden und den Rest dann mit neuer Adresse nachschieben.

Meine Testsketche schreiben aber immer nur ein Byte, da passiert dann nichts.

Den FM24C64B interessiert das R/W Bit auch nicht obwohl das dort in Fig. 6 auch so beschrieben ist. Aber das ist wieder das Thema dass ich mit "Memory Slave Device Address" und dem zugehörigen Bildchen nichts anfangen kann.

Ich habe meinen einzigen 64er den ich hatte jetzt dauerhaft im Einsatz. Es werden dabei fast nur 4Byte Variablen aber eine nach der anderen geschrieben. Nachschub ist aber schon im Warenkorb des Händlers.
60 4Byte Variablen gehen in knapp 16ms durch, aber bei 400kHz I²C.
An der Wire-Lib wollte ich nichts drehen, wegen der 32 Byte. Diese Grenze kommt erst zum tragen wenn man längere Texte oder struct-Variablem am Stück speichern oder lesen will.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.09.2016, 17:16 (Dieser Beitrag wurde zuletzt bearbeitet: 09.09.2016 19:24 von Tommy56.)
Beitrag #5
RE: FRAM am Arduino
Ich reihe mich erst mal in die Riege derer, die nicht verstehen warum es entgegen dem Datenblatt funktioniert, ein.

Mit Deiner Ansteuerung ( erst mal auf 0x50 und 0x51) kann ich Bytes lesen und schreiben. Wenn ich versuche, die Ansteuerung des Datenblatts nachzubilden, funktioniert nichts.

Gruß Tommy

Edit: Das kreuzt sich dann mit 0x57 des EEPROMS der DS3231.

Es hat mir keine Ruhe gelassen und ich habs raus gefunden.

Das Datenblatt stimmt und Deine/unsere Ansteuerung auch.

Die Lösung liegt in der Wire-Lib und dort in der utility/twi.c

in Zeile 143/144 Read wird mit 0 initialisiert und die von uns übergebene Adresse um 1 nach links verschoben geodert.

In Zeile 220/221 für Write - Inital 1 und dann Adresse Shiftleft 1 drüber.

Damit wird aus unseren Werten genau das, was im Datenblatt steht. Das scheint für alle Devices zu gelten.

Da müsste man jetzt die I2C-Spec lesen.

Gruß Tommy
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
09.09.2016, 21:34
Beitrag #6
RE: FRAM am Arduino
Hallo Tommy,
jetzt bist du aber tief in den Keller der Library hinab gestiegen.
Was du da heraus gefunden hast kann ich nachvollziehen. Danke für deine Forschung. Smile

Das Verhalten kann man wohl in der I2C-Spec nachlesen.
Eigentlich muss man das immer im Hinterkopf haben wenn man I2C Busteilnehmer selbst an jeder Library (außer der TWI) vorbei bedienen will.

In der twi.h steht ab Zeile 31:
Code:
#ifndef TWI_BUFFER_LENGTH
#define TWI_BUFFER_LENGTH 32
#endif
Wenn man in seinem Sketch ein: "#define TWI_BUFFER_LENGTH 64" einfügt kann man die Vorgabe aus der Headerdatei wahrscheinlich überschreiben und so die Puffergröße selbst wählen ohne die Library zu patchen.

Eine DS3231 habe ich nie benutzt, kenne deshalb deren EEPROM Adr. nicht.
Wenn die 0x57 stimmt könnte man die letzte Page des FM24C16B nicht gemeinsam mit der Uhr an einem Bus benutzen. Undecided
Wieder ein Grund nur die FM24C64B zu verwenden. Die belegen nur die Adr. 0x50 weil die Speicherzellenadresse dort 16 bitig im Telegramm übertragen wird und ein Pageselect entfällt.

Mein Beispielcode aus #2 sollte alle Pages des FM24C04B und des FM24C16B bedienen können.

Für den FM24C64B habe ich einen etwas anderen Code der auch Multi-Byte Read und Write unterstützt.
Code:
// FRAM schreiben - Variable, anzahl Bytes, Adresse im FRAM
void F_RAM_write (byte* wert, int numbytes, uint16_t framAddr) {
  TWBR = 12;  // 400 kHz (maximum)
  Wire.beginTransmission(F_RAM);
  Wire.write(framAddr >> 8);  Wire.write(framAddr & 0xFF);
  for (byte i = 0; i < numbytes; i++) Wire.write(wert[i]);
  Wire.endTransmission();
  TWBR = 72;  // 100 kHz (default)
}

// FRAM lesen - Variable, anzahl Bytes, Adresse im FRAM
void F_RAM_read (byte* wert, int numbytes, uint16_t framAddr) {
  TWBR = 12;  // 400 kHz (maximum)
  Wire.beginTransmission(F_RAM);
  Wire.write(framAddr >> 8);  Wire.write(framAddr & 0xFF);
  Wire.endTransmission();
  Wire.requestFrom(F_RAM, numbytes);
  for (byte i = 0; i < numbytes; i++) wert[i] = Wire.read();
  TWBR = 72;  // 100 kHz (default)
}
Da steckt auch die Taktumschaltung auf 400kHz mit drin.

Gruß
Arne

ExclamationMit zunehmender Anzahl qualifizierter Informationen bei einer Problemstellung, erhöht sich zwangsläufig die Gefahr auf eine zielführende Antwort.Exclamation
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
10.09.2016, 14:17
Beitrag #7
RE: FRAM am Arduino
Im Zweifel fliegt dann eben der EEPROM von der DS3231 runter.
Ich habe ja auch den FM24C64B bestellt.

Mit Deinen Routinen (umgestellt auf 1 Adressbyte) kann ich auch problemloa Blöcke schreiben. Eigenartigerweise sogar über Pagegrenzen hinaus.

Code:
char text[] ="ABCDEF";
char buffer[20];
...
  F_RAM_write((byte *)text,sizeof(text),0x1FE); // 2 Byte vor Pagegrenze
  F_RAM_read((byte *)buffer,7,0x1FE);
  Serial.println(buffer); // ergibt: ABCDEF
  F_RAM_read((byte *)buffer,7,0x200);  // 2. Page
  Serial.println(buffer); // ergibt: CDEF
Jetzt werde ich mal sehen, ob ich die Puffergröße intern verstecken kann.

Gruß Tommy
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
10.09.2016, 15:16
Beitrag #8
RE: FRAM am Arduino
(10.09.2016 14:17)Tommy56 schrieb:  ...
Mit Deinen Routinen (umgestellt auf 1 Adressbyte) kann ich auch problemloa Blöcke schreiben. Eigenartigerweise sogar über Pagegrenzen hinaus.
....

----ähm also da wäre ich mal vorsichtig...wenn du mit einer größeren Adresse als zugelassen wo reingehst dann steht die Information schon wo drin...aber nicht da wo du denkst sondern du überschreibst da dann einen Teil des Speichers der schon belegt ist...das knirscht dann ein bischen...Hardware ist da eigen...Big Grin
Also überlege dir mal ein Muster an Prüfziffern die du eintragen tust...dann überziehst die Pagegrenze um sagen wir mal 10% und dann liest die komplette Page am Stück aus...dann müßte der Fehler sichtbar werden.
lgbk

1+1 = 10 Angel ...und ich bin hier nicht der Suchmaschinen-Ersatz Dodgy...nur mal so als genereller Tipp..
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  LCD Anzeige für Arduino Mega2560 an Arduino Due? DaniDD 1 818 03.06.2015 12:16
Letzter Beitrag: DaniDD
  Arduino Pin mit anderem Arduino auslesen - geht das? Gelegenheitsbastler 8 3.242 08.05.2015 20:49
Letzter Beitrag: Bitklopfer
Question Arduino Mega ADK oder Arduino Due? Baja-Junky 1 4.176 14.08.2013 21:16
Letzter Beitrag: Bitklopfer

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste