Forum: Mikrocontroller und Digitale Elektronik Lesen/Schreiben FRAM klappt nicht


von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Woran könnte es liegen, dass die beiden folgenden Methoden (oder eine 
von ihnen) nicht korrekt funktionieren? Die I2C-Adresse des FRAM ist 
0x50 (80 dezimal), ich schreibe testweise in die Speicherplätze 0-9 die 
Werte 10,11,12 ... 19, bekomme jedoch beim Lesen immer nur 255 zurück. 
"sw" ist eine Software-I2C, "softwire". Die funktioniert, das habe ich 
mit einem angepassten I2C-Scanner-Code getestet, der findet auch brav 
das FRAM auf 0x50.
1
void fram_write(byte i2c_addr, uint16_t ram_addr, byte value)
2
{
3
  sw.beginTransmission(i2c_addr);
4
  sw.write(ram_addr >> 8);
5
  sw.write(ram_addr);
6
  sw.write(value);
7
  sw.endTransmission();
8
}
9
10
byte fram_read(byte i2c_addr, uint16_t ram_addr)
11
{
12
  sw.beginTransmission(i2c_addr);
13
  sw.write(ram_addr >> 8);
14
  sw.write(ram_addr);
15
  sw.endTransmission();
16
  sw.requestFrom((int)ram_addr, (int)1);
17
  return sw.read();
18
}

Warum ich keine fertige Lib benutze? Keine von denen ist für SoftWire 
geeignet und soo viel Code ist es ja anscheinend auch nicht, wenn er 
denn funktionieren würde :-(

: Bearbeitet durch User
von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Wie heisst denn das FRAM?
Und an deiner Stelle würde ich mal etwas Fehlerabfrage machen, wie z.B. 
das ACK Bit. Bisher schreibst du da nur blind hin, ohne zu wissen, ob da 
überhaupt was im FRAM ankommt.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?


von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Matthias S. schrieb:
> Bisher schreibst du da nur blind hin, ohne zu wissen, ob da
> überhaupt was im FRAM ankommt.

Ja, das klingt sinnvoll, macht aber m.W. keine der Libs, die ich bisher 
untersucht habe. Viele arbeiten allerdings mit einem unübersichtlichen 
Wust an globalen Variablen, weshalb ich ziemlich lange gesucht habe

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Matthias S. schrieb:
> Wie heisst denn das FRAM?
> Und an deiner Stelle würde ich mal etwas Fehlerabfrage machen, wie z.B.
> das ACK Bit. Bisher schreibst du da nur blind hin, ohne zu wissen, ob da
> überhaupt was im FRAM ankommt.

Hättest du ein Beispiel, wie ich das als Boolean-Rückgabewert in der 
Write-Methode verwenden könnte, statt "void"?

von Wastl (hartundweichware)


Lesenswert?

Frank E. schrieb:
> Woran könnte es liegen, dass die beiden folgenden Methoden (oder eine
> von ihnen) nicht korrekt funktionieren?

Auch an deinem Aufbau und Schaltplan den du nicht zeigen willst.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Wastl schrieb:
> Frank E. schrieb:
>> Woran könnte es liegen, dass die beiden folgenden Methoden (oder eine
>> von ihnen) nicht korrekt funktionieren?
>
> Auch an deinem Aufbau und Schaltplan den du nicht zeigen willst.

Wennd der I2C-Scanner den Chip findet, sehe ich da eigentlich kein 
Problem. Derzeit ist das ein "Aufbau" mit Dupont-Wires ... am Uno

: Bearbeitet durch User
von Wastl (hartundweichware)


Lesenswert?

Frank E. schrieb:
> Wennd der I2C-Scanner den Chip findet, sehe ich da eigentlich kein
> Problem.

Ich schon. Ein Acknowledge vom Slave bekommen ist was anderes
als einen Block von Daten lesen oder schreiben.

Frank E. schrieb:
> Derzeit ist das ein "Aufbau" mit Dupont-Wires

Den du natürlich nicht zeigen willst da die Schaltung höchst
geheim ist.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Wastl schrieb:
> Den du natürlich nicht zeigen willst da die Schaltung höchst
> geheim ist.

Doch, aber erst morgen vormittag ...

von Harald K. (kirnbichler)


Lesenswert?

Frank E. schrieb:
> sw.beginTransmission(i2c_addr);

Und wo ist das r/w-Bit?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Frank E. schrieb:
> Hättest du ein Beispiel, wie ich das als Boolean-Rückgabewert in der
> Write-Methode verwenden könnte, statt "void"?

Ich weiss ja nicht mal, mit was für einem MC du da rummachst. Wenns AVR 
wäre, verlasse ich mich da auf die bei mir sehr bewährte Library von 
PFleury.
Für STM32 habe ich hier was für die SPL, was auch Fehler meldet.

Harald K. schrieb:
> Und wo ist das r/w-Bit?

Gute Frage. Es müsste ja in der Read Routine Bit 0 gesetzt sein.

: Bearbeitet durch User
von Thomas Z. (usbman)


Lesenswert?

Frank E. schrieb:
> der findet auch brav
> das FRAM auf 0x50

im Datenblatt steht aber 0xA0 für schreiben und 0xA1 für lesen (bei 
A2..A0 =0)
Dein Scanner gibt aber 7 Bit Adressen aus. Du must das R/W Bit selber 
dranpfriemeln.
also etwa so:
- (0x50 << 1) | 0 beim schreiben
- (0x50 << 1) | 1 beim lesen

Wenn ich mich richtig erinnere  machst du den Fehler nicht zum ersten 
mal.
Deine Routinen haben im Lesebetrieb nichts mit der im DB geforderten 
Sequenz zu tun, und im Schreibbetrieb hast du halt die falsche Adresse. 
Würdest du auf ACK prüfen würdest du das sofort sehen.

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Thomas Z. schrieb:

> - (0x50 << 1) | 0 beim schreiben
> - (0x50 << 1) | 1 beim lesen
>
> Wenn ich mich richtig erinnere  machst du den Fehler nicht zum ersten
> mal.
> Deine Routinen haben im Lesebetrieb nichts mit der im DB geforderten
> Sequenz zu tun, und im Schreibbetrieb hast du halt die falsche Adresse.
> Würdest du auf ACK prüfen würdest du das sofort sehen.

Wie ich schon schrieb, ich habe beide Methoden aus einer anderen, 
fertigen Lib entnommen, die sind genau so, wie eingangs beschrieben. 
Werde ich aber heute mal versuchen.

von Thomas Z. (usbman)


Lesenswert?

Frank E. schrieb:
> Wie ich schon schrieb, ich habe beide Methoden aus einer anderen,
> fertigen Lib entnommen,

mach es einfach so wie es im DB beschrieben ist und es wird 
funktionieren.
Wie das wire Gedöns mit Ack und dem r/w Bit umgeht musst du dort 
nachschauen.
Übrigens EEprom Libs für 64k EEproms sollten auch funktionieren

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Ich habe das Problem jetzt anders gelöst.

Grund für den Einsatz FRAM ist die etwas zu langsame Ausgabe eines 
Bondruckers in einem Automaten-Prototypen (ca. 5s für ca. 12cm). Das hat 
leider genügt, dass mancher Kunde meinte, an dem Bon ziehen zu müssen, 
was das Druckmodul regelmäßig mit einer Fehlermeldung "Papierstau!" 
missinterpretiert und seinen Betrieb vorläufig einstellt.

Die schnelle Lösung für den im Einsatz befindlichen Prototyp: Die 
Druckdaten nicht pö-a-pö ausgeben, sondern erstmal (im FRAM) sammeln. 
Dann erfolgt am Ende die Bonausgabe "in einem Rutsch" schnell genug, so 
dass niemand mehr Zeit hat, an dem Bon zu zerren.

Aufgrund mechanischer Gegebenheiten wollte ich den FRAM zunächst nicht 
an die originalen Hardware-Pins für I2C des Arduino Mega anschließen, 
sondern SoftWire benutzen. Das wiederum klappt nicht auf die Schnelle 
mit den vorhandenen Libs (Adafruit u.a.), die sind alle auf Wire 
ausgelegt.

Nach 2 Tagen Zeitverschwendung habe ich nun doch eine kleine 
Adapterplatine gebaut, die sogar vom Kunden vor Ort einfach aufgesteckt 
werden kann. Die geänderte Firmware läuft nun mit der 
Adafruit-I2C-FRAM-Lib und FIFO-Druckerpuffer, die kann ich über 
Fernzugag einspielen.

: Bearbeitet durch User
von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Anbei mal eine kleine Lib für I2C-EEPROM, geht natürlich auch für FRAM.
Der Unterschied ist, beim EEPROM wird bis zu 10ms lang versucht, den 
Slave zu adressieren, beim FRAM klappt das immer sofort.

von Harald K. (kirnbichler)


Lesenswert?

Frank E. schrieb:
> Die schnelle Lösung für den im Einsatz befindlichen Prototyp: Die
> Druckdaten nicht pö-a-pö ausgeben, sondern erstmal (im FRAM) sammeln.

Und warum muss das dann FRAM sein? Stinknormales SRAM täte es auch und 
dürfte deutlich weniger kosten.

Daß während des Druckvorganges die Stromversorgung ausfällt, dürfte 
eher unwahrscheinlich sein (oder das Gerät ist sehr, sehr merkwürdig 
"designt").

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

Harald K. schrieb:
> Frank E. schrieb:

> Und warum muss das dann FRAM sein? Stinknormales SRAM täte es auch und
> dürfte deutlich weniger kosten.

Gibts I2C-Ram? Habe keinen auf einem breakout für Arduino-Umgebung 
gefunden. Und seriell muss auch sein, wegen der Anzahl der freien Pins.

von Harald K. (kirnbichler)


Lesenswert?

Frank E. schrieb:
> Gibts I2C-Ram?

Als reines SRAM nicht, nur als NVRAM z.B. mit EEPROM-Puffer. Für Deine 
Anwendung etwas verfehlt.

SPI-RAM aber gibt es (z.B. 24LC512 mit 64 kiB).

von Uwe D. (monkye)


Lesenswert?

Frank E. schrieb:
> Harald K. schrieb:
>> Frank E. schrieb:
>
>> Und warum muss das dann FRAM sein? Stinknormales SRAM täte es auch und
>> dürfte deutlich weniger kosten.
>
> Gibts I2C-Ram? Habe keinen auf einem breakout für Arduino-Umgebung
> gefunden. Und seriell muss auch sein, wegen der Anzahl der freien Pins.

Google schon wieder Offline? (Sorry, musste jetzt mal sein…)

https://www.mouser.de/c/semiconductors/memory-ics/sram/?interface%20type=I2C

Nachtrag: die Frage wäre bei mir eher, warum die lahme I2C jetzt sRAM 
bedienen soll. Aber ja, vielleicht mangels freier Pins…

: Bearbeitet durch User
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.