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
10.11.2019, 18:55 (Dieser Beitrag wurde zuletzt bearbeitet: 10.11.2019 19:17 von Tommy56.)
Beitrag #25
RE: FRAM am Arduino
Da Interesse an der Version mit Übergabe der I2C-Adressen geäußert wurde, hier die Version (fRam2.h):
Code:
// Mit Anleihen bei rkuehle (Template), Rob Tillaart (I2C_EEPROM library), Ardu_Arne (FRAM), Tommy56 (fRam.h) und Arduino core (HEX)
// Handling für FRAM Bausteine 16 KBit (1 Adressbyte) und 64KBit (2 Adressbytes)
// für mehrere FRAM IC
#include <Arduino.h>
#include <Wire.h>

// I2C-(Basis)Adresse (Aus 0x5 wird dann die 0xC, die im Datenblatt steht)
//#define F_RAM 0x57  // auf DS3231 mit 7 gebrückt oder 0x50  


// FRAM schreiben - I2C-Adresse, Anzahl Adressbytes (1=16kB oder 2), Variable, anzahl Bytes, Adresse im FRAM
void F_RAM_write (byte i2c_adresse, byte num_adressbytes, byte* wert, int numbytes, uint16_t framAddr) {
  int devAdr, rc;
  TWBR = 12;  // 400 kHz (maximum)
  // Adressierungsart 1 -> 3 Bit in Adresse
  if (num_adressbytes == 1) {
    // 16 K
    devAdr = i2c_adresse | framAddr >> 8;
    Wire.beginTransmission(devAdr);
    Wire.write(framAddr & 0xFF);
    for (byte i = 0; i < numbytes; i++)  Wire.write(wert[i]);
    rc = Wire.endTransmission();
    //Serial.print("rc: ");Serial.println(rc);
  }
  else {
    // 64 K
    Wire.beginTransmission(i2c_adresse);
    Wire.write(framAddr >> 8);  Wire.write(framAddr & 0xFF);
    for (byte i = 0; i < numbytes; i++) Wire.write(wert[i]);
    rc = Wire.endTransmission();
  }
  TWBR = 72;  // 100 kHz (default)
}

// FRAM lesen - I2C-Adresse, Anzahl Adressbytes (1=16kB oder 2), Variable, anzahl Bytes, Adresse im FRAM
void F_RAM_read (byte i2c_adresse, byte num_adressbytes, byte* wert, int numbytes, uint16_t framAddr) {
  int devAdr, rc;
  TWBR = 12;  // 400 kHz (maximum)
  // Adressierungsart 1 -> 3 Bit in Adresse
  if (num_adressbytes == 1) {
    // 16 K
    devAdr = i2c_adresse | framAddr >> 8;
    Wire.beginTransmission(devAdr);
    Wire.write(framAddr & 0xFF);
    rc = Wire.endTransmission();
    Wire.requestFrom(devAdr, numbytes);
    for (byte i = 0; i < numbytes; i++) wert[i] = Wire.read();
  }
  else {
    // 64 K
    Wire.beginTransmission(i2c_adresse);
    Wire.write(framAddr >> 8);  Wire.write(framAddr & 0xFF);
    rc = Wire.endTransmission();
    // cast to int for Wirelib
    Wire.requestFrom((int)i2c_adresse, numbytes);
    for (byte i = 0; i < numbytes; i++) wert[i] = Wire.read();
  }
  TWBR = 72;  // 100 kHz (default)
}


// Schreibt beliebige Werte (auch Arrays beliebiger Typen) in den FRAM
template <class T> int fRamWrite(byte i2c_adresse, byte num_adressbytes, uint16_t framAddr, const T& wert) {
  byte* p = (byte*)(void*)&wert;
  int16_t len, cnt, orig;
  len = sizeof(wert);
  byte twi_length = BUFFER_LENGTH - num_adressbytes;
  orig = len;
  // Solange Bytes zu senden sind
  while (len > 0) {
    cnt = len;
    // Wenn  länger als TWI-Buffer - Adresslänge, dann begrenzen
    if (cnt > twi_length) cnt = twi_length;
    // Schreiben
    F_RAM_write (i2c_adresse, num_adressbytes, p, cnt, framAddr);
    // Restbytes berechnen
    len -= cnt;
    // neue FRAM-Adresse
    framAddr += cnt;
    // neue Quelladresse
    p += cnt;
  }
  return orig;
}

// liest beliebige Werte aus dem FRAM . Die Länge wird von der Zielvariablen bestimmt
// optionaler Parameter laenge wird nur berücksichtigt, wenn er kleiner, als die Länge der Variablen ist

template <class T> int fRamRead(byte i2c_adresse, byte num_adressbytes, uint16_t framAddr, const T& wert, int laenge = 0) {
  byte* p = (byte*)(void*)&wert;
  int16_t len, cnt, orig;
  len = sizeof(wert);
  byte twi_length = BUFFER_LENGTH - num_adressbytes;
  // Wunschlänge gesetzt und passt in Variable rein
  if ((laenge > 0) && (laenge < len)) len = laenge;
  orig = len;
  // Solange Bytes zu holen sind
  while (len > 0) {
    cnt = len;
    // Wenn  länger als TWI-Buffer - Adresslänge, dann begrenzen
    if (cnt > twi_length) cnt = twi_length;
    // Schreiben
    F_RAM_read (i2c_adresse, num_adressbytes, p, cnt, framAddr);
    // Restbytes berechnen
    len -= cnt;
    // neue FRAM-Adresse
    framAddr += cnt;
    // neue Quelladresse
    p += cnt;
  }
  return orig;
}

// Hilfsfunktion für Hexdarstellung
// Puffer, Wert, Stellenzahl (2 oder 4), Ein Blank wird voran gestellt
char *fillHex(char *buf, uint16_t val, uint8_t len, boolean withBlank = true) {
  uint16_t m;
  byte str, t;

  if (len == 4) {
    //Adresse
    str = 5;
    buf[0] = ' ';
    for (byte i = 1; i < 5; i++) buf[i] = '0';
  }
  else {
    // Byte
    str = 3;
    buf[0] = ' ';
    buf[1] = '0';
  }
  buf[str] = '\0';
  do {
    m = val;
    val /= 16;
    char c = m - 16 * val;
    buf[--str] = c < 10 ? c + '0' : c + 'A' - 10;
  } while (val);
  if (!withBlank) return buf+1;
  return buf;
}

// Anzeige des Fram im angegebenen Bereich Hex und als (druckbares) Zeichen
void dumpFram(byte i2c_adresse, byte num_adressbytes, uint16_t von, uint16_t bis) {
  // Hexformatierer
  char buf[6];
  //Lesepuffer
  byte readBuffer[16];
  // Zeichenpuffer
  char zbuffer[17];
  uint16_t start;
  uint8_t len = 16;
  start = von;

  Serial.print("FRAM Dump I2C-Adresse: 0x"); Serial.print(fillHex(buf,i2c_adresse,2, false)); Serial.print(" von 0x"); Serial.print(fillHex(buf, von, 4, false));
  Serial.print(" bis 0x"); Serial.println(fillHex(buf, bis, 4, false));
  while (start <= bis) {
    memset(zbuffer, 0, 17); // leeren
    if ((bis - start) < 16) len = bis - start + 1;
    fRamRead(i2c_adresse, num_adressbytes, start, readBuffer, len);
    Serial.print(fillHex(buf, start, 4)); // Adresse
    for (byte i = 0; i < len; i++) {
      Serial.print(fillHex(buf, readBuffer[i], 2));
      if ((readBuffer[i] < 32) || (readBuffer[i] > 126)) zbuffer[i] = '.';
      else zbuffer[i] = readBuffer[i];  // druckbare Zeichen
    }
    // Wenn letzte Zeile < 16, dann auffüllen
    if (len < 16) {
      for (byte i = 0; i < (16 - len); i++) Serial.print("   ");
    }
    Serial.print("   "); Serial.println(zbuffer);
    start += 16;
  }
}

//Füllen des Fram mit einem bestimmten Zeichen in einem Bereich
void fillFram(byte i2c_adresse, byte num_adressbytes, uint16_t von, uint16_t bis, uint8_t val) {
  // Hexformatierer
  char buf[6];
  byte writeBuffer[16];
  uint16_t start;
  uint8_t len = 16;
  start = von;
  memset(writeBuffer, val, 16);
  Serial.print("FRAM schreiben I2C-Adresse: 0x"); Serial.print(fillHex(buf,i2c_adresse,2, false)); Serial.print(" von 0x"); Serial.print(fillHex(buf, von, 4, false));
  Serial.print(" bis 0x"); Serial.print(fillHex(buf, bis, 4, false));
  Serial.print(" mit 0x"); Serial.println(fillHex(buf, val, 2, false));
  len = 0;
  while (start <= bis) {
    if ((bis - start) < 16) {
      len = bis - start + 1;
      F_RAM_write (i2c_adresse, num_adressbytes, writeBuffer, len, start);
    }
    else fRamWrite(i2c_adresse, num_adressbytes, start, writeBuffer);
    start += 16;
  }
}

Und ein paar Beispiele (für 64k FRAM):
Code:
// fram64k_2
#include <Wire.h>
#include "fRam2.h"

char text[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-*/,;.:";
char buffer[45]; // Länge wie text

char text1[] = "1234567890";
char text2[] = "abcdefghij";

float f= 33.44;

typedef struct {
  int i1;
  uint32_t aktMillis;
} teststruct;

teststruct tarr[10];


void setup() {
byte pos;
  Serial.begin(115200);
  Serial.println("Start");
  Wire.begin();
  // Schreib- und Leseteil können auch wechselseitig auskommentiert werden
  // fillFram(0x50, 2, 0xff,0x99);
  //fRamWrite(0x2d,text2);
  //fRamRead(0x0,buffer);
  //Serial.println((unsigned char *)buffer,HEX);
  
  // Schreibteil
  
  //fRamWrite(0x1FB,text1);
  //fRamWrite(0x50, 2,0x100, text);
  
  // Leseteil
  //fRamRead(0x02d,buffer);
  //Serial.println(buffer);
  //fRamRead(0x100,buffer);
  //Serial.println(buffer);

  // Hilfsfunktionen
  fillFram(0x50, 2, 0x00,0xff,0xee);
  fillFram(0x57, 2, 0x00,0xff,0xaa);
  fRamWrite(0x50, 2, 0x2d,text2);
  fRamWrite(0x57, 2,0x70, text);
  fRamRead(0x50, 2,0x2d, buffer);
  Serial.println(buffer);
  fRamRead(0x57, 2,0x70, buffer);
  Serial.println(buffer);
  dumpFram(0x50, 2,0, 0x1ff);
  dumpFram(0x57, 2,0, 0x1ff);
}

void loop() {  
}

Gruß Tommy

Nebenan wurde gerade mit 256k erfolgreich getestet.

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
11.11.2019, 10:56
Beitrag #26
RE: FRAM am Arduino
(10.11.2019 18:55)Tommy56 schrieb:  Da Interesse an der Version mit Übergabe der I2C-Adressen geäußert wurde, hier die Version (fRam2.h):

Danke Tommy,
jetzt wird es Zeit für mich, auch damit mal zu experimentieren.
Ein derartiger Käfer liegt hier schon länger rum.

Gruß Dieter

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  FRAM Speichergröße Fragen rev.antun 30 3.863 14.03.2021 22:59
Letzter Beitrag: Tommy56
  Arduino Mega 2560 vs Arduino DUE Batucada 24 15.462 11.07.2020 15:46
Letzter Beitrag: Tommy56
  LCD Anzeige für Arduino Mega2560 an Arduino Due? DaniDD 1 6.096 03.06.2015 12:16
Letzter Beitrag: DaniDD
  Arduino Pin mit anderem Arduino auslesen - geht das? Gelegenheitsbastler 8 12.540 08.05.2015 20:49
Letzter Beitrag: Bitklopfer
  Original Arduino MEGA 2560 und Original Arduino TFT LCD screen funzt nicht Odiug 6 9.062 12.12.2014 15:28
Letzter Beitrag: Odiug
  Arduino XBee mit XBee Arduino Werte versenden th3Khem 2 6.393 23.08.2013 10:12
Letzter Beitrag: th3Khem
Question Arduino Mega ADK oder Arduino Due? Baja-Junky 1 12.396 14.08.2013 21:16
Letzter Beitrag: Bitklopfer

Gehe zu:


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