Forum: Mikrocontroller und Digitale Elektronik ATMega32 I2C connect mit AT24Cxx EEprom


von Gerhard H. (oderlachs)


Lesenswert?

Hallo Freunde !
Ich möchte mal um Unterstützung bitten.

Seit Tagen bemühe ich mich, um ein Schreib-/Lesezugriff vom ATmega zum 
I2C Speicher hinzubekommen.

Es misslingt mir aber nur....Habe bislang nach dem Buch:
"AVR Mikrocontroller Programmierung in C" von Heimo Gaicher probiert...

Nun habe ich ein Tutorial das im Internet vorgestellt wurde versucht, 
auch wieder ohne Erfolg. :((

Das "AT24C64 Modul" (Steckbrett) habe ich auf Funktion mittels Arduino 
getestet, da geht es.

Ich habe den Code(Main-,Headerdatei usw.) gezipt und auf meinen Webspace 
gelegt.

   http://oderlachs.de/code/AVR/I2C_Demo.zip

Vielleicht kann wer bitte drüber schauen.

Das ich in der Main eine c- und nicht die h-Datei includiere, hat den 
Grund das ich mit Geany unter Linux arbeite.

Gruss und Dank

Gerhard

Nachtrag :
schon der Aufruf

ret = i2c_start(Dev24C02+1);

in main bringt alle LEDs , also Fehler ..aber warum ???

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Angehängte Dateien:

Lesenswert?

Gerhard H. schrieb:
> Vielleicht kann wer bitte drüber schauen.

 Warum hast du die I2C Adresse geändert ?
1
 #define Dev24C02  0xA0      // device address of EEPROM 24C02, see datasheet

 Und die SCL und SDA pins (und PORT), CPU_FREQ entsprechend angepasst ?

 P.S.
 Um nutzlosen Diskussionen vorzubeugen, Bild anbei.

: Bearbeitet durch User
von Gerhard H. (oderlachs)


Lesenswert?

Hallo Marc !
Die I2C Addr vom AT24C64 ist 0x50....lt Datenblatt und lt I2C Scanner.
Mit dieser Ardresse kann ich den EEprom auch mittels Arduino 
beschreiben/auslesen.
Beim Atmega32 habe ich PortC.0 als SCL und PortC.1 als SDA verbunden.
Das habe ich nach dem Pinout im Datenblatt Atmega32. bei Ltg sind per 
7k5 Widerstände gegen +5V (Ub) gelegt.
 Ich arbeite mit dem STK500 von ATMEL.

Gruss und Dank

Gerhard

Ich kann natürlich auch mal was falsch lesen....dank der guten 
schlechten Augen ;)...Will hier keinem was widerlegen !

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Gerhard H. schrieb:
> Die I2C Addr vom AT24C64 ist 0x50....lt Datenblatt und lt I2C Scanner.

 Nein.
 Das ist wahrscheinlich bei Arduino so, weil er die Adresse nach
 links schiebt.
 Ich glaube, dass die Fleury-library nicht nach links schiebt.
 Probiere es doch mit 0xA0.

von pegel (Gast)


Lesenswert?

http://www.atmel.com/Images/doc0336.pdf
die Adresse auf Seite 11 ist eindeutig.

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


Lesenswert?

Marc V. schrieb:
> Ich glaube, dass die Fleury-library nicht nach links schiebt.

So isses. Für ein EEPROM wäre 0xA0 oder eben 0xA1 richtig.

von Gerhard H. (oderlachs)


Lesenswert?

Habt erst mal vielen, vielen herzlichen Dank, die Addr 0xA0  geht dann 
erst mal , jedenfalls sind die Fehler-LEDs aus, nach den dem I2C Start 
Aufruf...

Nun ja, es sind mal wieder gewisse Anfängerfallen in die ich da trete.

Werde mal berichten wie ich das Problem I2C-EEprom weiter in den Griff 
bekomme...oder auch nicht ;)

Ich arbeite auch ungern so mit was "fremden Code", wenn ich nicht genau 
weiss was da geschieht.

Die Druckfehlerteufel sind ja auch bei sogenannten Fachbücher eine 
grosse Plage....ein falsch gedrucktes Zeichen kann da schon ne Menge 
bewirken.

Gruss und Dank

Gerhard

von Gerhard H. (oderlachs)


Lesenswert?

Der Admin mag mir verzeihen, das ich neu Schreiben, aber beim Editieren, 
habe ich immer Probleme...

Also heute konnte ich Dank Regenwetter und darum "Gartenfrei" hatte, ein 
neues Progrämmchen für I2C Verbindung schreiben.
Ich habe mich da sehr an das Beispiel aus dem oben genannten Buch 
gehalten.

http://oderlachs.de/code/AVR/Neu_TWI.zip

Ich glaube das dies ja auch so funktioniert, aber das weitaus grössere 
Problem für mich ist die Kommunikation/Protokollablauf mit dem EEprom.
Ich dachte das man ja da von Speicherstelle 0...bis Ende einfach 
draufschreiben kann....

Beim Lesen desselben kann man wohl von Speicherstelle 0 kontinuierlich 
weiter Auslesen kann.

Doch dieses hier : http://oderlachs.de/code/AVR/EEProm_I2C AT_24C64.pdf

beweist mir aber was anderes. Nun schau ich erst mal da wie Ochs in 
Uhrwerk auf den ersten Blick

Vielleicht hat ja ein netter User hier bitte für mich ein wenig 
Starthilfe, damit ich in die Gedankengänge komme ??

Gruss und Dank

Gerhard

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


Lesenswert?

Gerhard H. schrieb:
> Ich dachte das man ja da von Speicherstelle 0...bis Ende einfach
> draufschreiben kann....

Kann man auch, dauert aber länger. Und - ein EEPROM ist kein Ersatz für 
RAM, sondern eben ein nichtflüchtiger Speicher, der bei jedem Schreiben 
(und da muss man sich drüber klar werden) ein wenig 'abgenutzt' wird. 
Das ist bei 1.000 oder 10.000 Schreibvorgängen noch kein Problem, aber 
bei etwa 1.000.000 Schreibvorgängen auf eine Zelle dann doch.

Deswegen möchten die meisten Leute gar nicht hunderte von Zellen am 
Stück beschreiben, sondern nur die, die wirklich übers Ausschalten 
hinweg gespeichert werden müssen und das sind im Allgemeinen sehr 
wenige.

von Gerhard H. (oderlachs)


Lesenswert?

Nun ja, das mit der "Haltbarkeit" ist mir bekannt. Mir geht es darum ein 
etwa halbes Jahr dort Klimadaten zu speichern. Diese sollen dann später 
ausgelesen werden können..da dachte ich mir solch ein Chip wäre da das 
"Beste" . Er wird alle 24h einmal beschrieben...vielleicht auch alle 12h 
aber das sollt auch in ca 6 Monaten noch nicht an die Haltbarkeitsgrenze
gelangen.

Ich lasse mich aber gern des Besseren belehren ! Für mich ist diese 
Hardwareverwendung noch Neuland. Auch ist es Hobbyprojekt, muss also 
nicht all zu sehr sicherheitsrelevant sein.

Wenn ich das Datenblatt so richtig verstanden habe müsste ein solcher 
stilisierter Programmablauf möglich sein:
1
/*
2
*
3
* Ablauf Kommunikation mit I2C Speicher AT24C64
4
* 
5
* 
6
*
7
* lt. Figure 2. Byte Write  S.11  Datasheet
8
*/
9
10
 TWI_Start();
11
12
 MaWriteACK( DEV_ADDR_WR );  // Master write  Device-Adresse to Slave, wartet auf ACK vom Slave
13
14
 MaWriteACK( PageADDR_MSB ); // Master write  MSB-Page-Adresse to Slave, wartet auf ACK vom Slave
15
16
 MaWriteACK( PageADDR_LSB ); // Master write  LSB-Page-Adresse to Slave, wartet auf ACK vom Slave
17
18
 MaWriteACK( Data_1 );       // Master write  Datenbyte 1 to Slave, wartet auf ACK vom Slave
19
20
 MaWriteACK( Data_2 );       // Master write  Datenbyte 2 to Slave, wartet auf ACK vom Slave
21
 .......
22
 .......
23
 MaWriteACK( Data_n );       // Master write  Datenbyte n to Slave, wartet auf ACK vom Slave
24
25
 TWI_Stop();
26
27
28
/**********************
29
/
30
/ ein TWI_RE_START() wo, noch nicht ganz begriffen ????
31
/
32
/**********************/

Gerhard

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


Lesenswert?

Gerhard H. schrieb:
> ein TWI_RE_START() wo, noch nicht ganz begriffen ????

Das ist eine Eigenart des EEPROM. Du startest normal mit einem TWI Write 
auf die Schreibadresse (0xA0), um den Adresszähler des EEPROM 
einzustellen. Nun kommt der TWI Restart mit EEPROM Adresse 0xA1, um dann 
das Datum zu lesen.
Der Restart wird also nur gebraucht, um Daten vom EEPROM zu lesen und 
nicht für den Schreibvorgang.

Wenn du dirs einfach machen willst, Peter Fleury hat in seinen I²C 
Bibliotheken ein Beispiel fürs EEPROM und auch sonst ist die Bibliothek 
recht pflegeleicht.

von holger (Gast)


Lesenswert?

>Ich dachte das man ja da von Speicherstelle 0...bis Ende einfach
>draufschreiben kann....

Nur innerhalb einer Page kann man mehrere Bytes auf einmal schreiben.
Wenn die Page z.B. 32Byte hat, du aber 33Bytes sendest gibt es ein
Rollover der Page und Byte33 landet am Anfang der Page und nicht in der
nächsten Page. Wenn du zwei Byte sendest und das erste auf Adresse 31
der Page liegt bekommst du auch ein Rollover der Page.
Du musst also immer darauf achten dass ein Page Schreibzugriff
nicht über eine Pagegrenze drüber geht.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Gerhard H. schrieb:
> / ein TWI_RE_START() wo, noch nicht ganz begriffen ????

 Matthias S. hat es dir schon erklärt aber hier noch einmal:
1
/* Random read (beliebige Adresse) */
2
 TWI_Start();
3
 MaWriteACK( DEV_ADDR_WR );  // Master sendet Device-Adresse+WR to Slave, wartet auf ACK vom Slave
4
 MaWriteACK( PageADDR_MSB ); // Master write  MSB-Page-Adresse to Slave, wartet auf ACK vom Slave
5
 MaWriteACK( PageADDR_LSB ); // Master write  LSB-Page-Adresse to Slave, wartet auf ACK vom Slave
6
7
/* Jetzt kommt repeated start, um auf lesen umzuschalten */
8
 TWI_Start();
9
 MaReadACK( DEV_ADDR_RD );  // Master sendet Device-Adresse+RD to Slave, wartet auf ACK vom Slave
10
11
/* Jetzt werden (als Beispiel) 3 Bytes eingelesen */
12
 x = MaReadByteAck();
13
 y = MaReadByteAck();
14
 z = MaReadByteNack();
15
 TWI_STOP();

 Falls du jetzt wieder Start und DEV_ADR_RD sendest, wird aus der
 Adresse 3 gelesen (unter der Voraussetzung, dass PageADDR_LSB und
 PageADDR_MSB Null waren.

von Patrick J. (ho-bit-hun-ter)


Lesenswert?

Hi

Nachdem Du mit Schreiben oder Lesen fertig bist, kannst Du mit 
TWI_STOP() den Bus frei geben (ein anderer Master könnte sich jetzt den 
Bus schnappen), oder per TWI_Re_Start() direkt eine neue Anfrage senden 
- da kann kein anderer Master 'reinquatschen', da der Bus ja noch belegt 
ist und zwischendrin nicht freigegeben wurde.

... wobei ein START und ein RE_START genau die selbe Funktionalität 
haben - kann aber sein, daß hier ein START nicht geht oder einen Fehler 
auswirft.

Wenn ich Dich richtig verstanden habe, willst Du Sensordaten über Monate 
aufzeichnen - so weit, (wohl) kein Problem.
Dann liegen zwischen den Schreibzugriffen aber 'Welten' an µC-Zeit - 
Theoretisch sollte der Bus aber die ganze Zeit 'Dir' gehören, wenn Du 
Diesen nicht frei gibst.

Wenn aber auch noch von 'wo Anders' auf den Bus zugegriffen werden soll 
(Multi-Master), wäre es sinniger, den Bus wieder frei zu geben und nur 
'anzufordern', wenn Du Daten zum Wegschreiben hast oder Daten lesen 
willst.

Habe selber aber bisher nur I2C-Displays beschrieben, also nicht 
wirklich viel Erfahrung und 'nur' Alles selbst zusammen gereimt.

MfG

Edit
holger schrieb:
>Wenn die Page z.B. 32Byte hat, du aber 33Bytes sendest gibt es ein
>Rollover der Page und Byte33 landet am Anfang der Page und nicht in der
>nächsten Page. Wenn du zwei Byte sendest und das erste auf Adresse 31
>der Page liegt bekommst du auch ein Rollover der Page.

Werden dann die vorderen Bytes teilweise überschrieben?
Da - meines Verständnis nach - erst geleert werden müssen (aber auf 1 
geschrieben werden) und beim Beschreiben 'nur' auf Null geändert werden 
- sollte ich im Schlimmsten Fall später nur noch Nullen im EEprom lesen 
können, oder?

Danke

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>Werden dann die vorderen Bytes teilweise überschrieben?

Ja, die werden überschrieben.

von holger (Gast)


Lesenswert?

>Da - meines Verständnis nach - erst geleert werden müssen (aber auf 1
>geschrieben werden) und beim Beschreiben 'nur' auf Null geändert werden
>- sollte ich im Schlimmsten Fall später nur noch Nullen im EEprom lesen
>können, oder?

Nein, da wird nichts geleert. Geschrieben wird erstmal nur in den
Pagebuffer. Und der Pagebuffer wird erst nach I2C-Stop ins
EEPROM geschrieben. Es stehen später nicht nur Nullen im EEPROM drin.

von Gerhard H. (oderlachs)


Lesenswert?

Hallo Freunde !

Ich möchte erst mal denen einen grossen Dank zollen(!!!), die mir das 
nun wohl auch für mich begreifend erklärt haben.
Ich denke schon, das ich damit erst mal etwas weiter komme, freu.

Ja ich habe so eigenständig noch nie was mit I2C gemacht, nun per 
Arduino, da gibst ja Libs/Exemples ohne Ende. Für einen Atmega8 mal was 
in Bascom, aber das ist was anderes, auch schon fast vorgefertigtes.

Gut, es gibt vieles von P.Fleury, aber ich habe damit auch meine 
Probleme gehabt es zu begreifen, anzuwenden.

Ich glaube auch mein grösster Mangel ist, dass ich kaum English kann, 
auch keinen Gusto mehr aufs Erlernen habe, weil mir das im Alter auch 
sehr schwer fällt.

Ich werde über Erfolg und Niederlage berichten.....

Gruss und Dank

Gerhard

von S. Landolt (Gast)


Lesenswert?

In diesem Fall wäre vielleicht ein SPI-EEPROM wie 25LC256 bzw. 25LC1024 
praktischer gewesen. Ich zumindest arbeite lieber mit SPI als mit I2C, 
wenn es Pin- und Leitungsanzahl irgendwie hergeben.

von S. Landolt (Gast)


Lesenswert?

PS: vielleicht hätten auch die 4 KiB EEPROM eines ATmega1284 für die 
rund 400 Messungen gereicht.

von Gerhard H. (oderlachs)


Lesenswert?

Ja bestimmt hätte das gereicht, aber ich habe zwei Gründe für meine 
Variante:

1. Verwendung von Bauteilen aus der Bauteilkiste

2. ist der EEprom auf einer steckbaren Lpl. , kann abgezogen und daheim
   ausgewertet werden.

Gerhard

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


Lesenswert?

Gerhard H. schrieb:
> Gut, es gibt vieles von P.Fleury, aber ich habe damit auch meine
> Probleme gehabt es zu begreifen, anzuwenden.

Man muss bei der Fleury Lib eigentlich nur verstehen, das es eine 
Variante für das Hardware TWI Interface gibt und eine für Soft-TWI.
Wenn man 'twimaster.S' kompiliert, ist das die Soft-TWI Variante, die 
auf jedem AVR läuft, man muss dann aber auch in 'twimaster.S' die 
benutzten Pins deklarieren.
Wenn man stattdessen 'twimaster.c' ins Projekt einfügt, muss man auch 
die Pins benutzen, die der AVR für TWI reserviert hat, da nun die TWI 
Hardware des AVR benutzt wird.

von Gerhard Hinze (Gast)


Lesenswert?

Danke Matthias !

Es ist ja noch kein Meister vom Himmel gefallen, vieleicht schaffe ich 
ja noch die "Gesellenprüfung". ;)
Ich weiss ja Dank der vielen Infos, die hier kamen, nun ne ganze Menge 
mehr .

Gruss & Dank
Gerhard

von Gerhard H. (oderlachs)


Lesenswert?

Hallo !
Ich kann erst mal "voller Stolz" berichten, dass eine Porterweiterung 
mit I2C Chip PCF8574 wunderbar klappt, dann werde ich das andere auch 
noch schaffen.
Euch allen nochmals vielen herzlichen Dank für Eure Hilfe.

Gruss

Gerhard

von Gerhard H. (oderlachs)


Lesenswert?

Hallo Freunde !
Ich glaube ich muss nochmals um Hilfe bitten. Noch nicht so ganz will es 
mir gelingen, den Eeprom per I2C zu beschreiben/auszulesen.

Ich habe jetzt einen AT24C04 verwendet und den Programmablauf nach oben 
von Euch gezeigten Ablauf geschrieben .

Mein Code hier als zip : http://oderlachs.de/code/AVR/TWI_Eeprom.zip

Am PortA liegen 8 LED zur binären Anzeige des gelesenen Bytes.

Am PortB liegen die 7 Error-LEDs . Da die LEDs gegen +Ub liegen  wird 
mit 0(GND) auf ON geschaltet.

Ein Fehler wird mir nicht angezeigt, nur ist die Byte-Anzeige PortA 
immer dieselbe  "01011000", egal welches Byte ich schreibe.

Vielleicht habe ich was übersehen, mein Code sollte selbsterklärend an 
Hand der Kommentare sein.

Vielleicht kann ja wer mal BITTE  drüberschauen.

Gruss und Dank

Gerhard

von Peter D. (peda)


Lesenswert?

Gerhard H. schrieb:
> Ich habe jetzt einen AT24C04 verwendet

Die kleinen werden aber anders adressiert. Da sind die oberen Bits mit 
in der I2C-Adresse verwurstet.

Gerhard H. schrieb:
> Mein Code hier als zip

Was stört Dich am Dateianhang?

von Gerhard H. (oderlachs)


Lesenswert?

Hallo Peter !

Dateianhang, na ich möchte nicht das Forum hier mit Codeanhang 
vollmüllen, zum Anderen kann ich per FTP schnell mal aktualisieren auf 
meinem Webspace.

Ich lesen gerade im Datenblatt, aber so richtig habe ich es noch nicht 
"gefressen" mir Adressierung & Speicherzelle(Schreiben/Lesen). Ist auch 
für mich ein Erstlingswerk auf dieser Ebene.

Gruss
Gerhard

von Gerhard H. (oderlachs)


Lesenswert?

Hallo Freunde !

Nun habe ich ein Tutorial im web gefunden , was auch bei mir geht ! :=)

 http://www.circuitstoday.com/use-external-eeprom-avr-atmega32

Ich weiss noch nicht was ich bei mir immer falsch hatte, ich werde mal 
den Code der einzelen Funktionen/Routinen vergleichen.

Damit hat sich das Problem erst mal"sozusagen erledigt" freu, anhand des
Sourcecodes werde ich dann auch verstehen wie es gehandelt wird beim 
I2C-EEprom.
Vor allem ist es mir ja wichtig herrauszubekommen, was trotz der vielen 
versch. Anleitungen und Tutus falsch war.


Gruss und Dank

Gerhard

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.