Guten Abend,
Ich habe zurzeit ein kleines Problem, und zwar folgendes ich habe mir
gestern ein kleinen 2kb EEPROM Chip für 65 Cent gekauft. Es ist der
24C16WP von ST. Dieser wird über denn I2C Bus angesteuert. Da ich mich
vorher oder auch um genau zu sein ein paar Monate früher(ca. Februar
2016) mich mit ein 16x2 LCD das per I2C angesteuert wird auseinander
gesetzt habe. Wahr dieses mal es kein Problem.
Ich habe die drei Analogen Pins(A0, A1, A2) auf Masse gezogen. Und laut
Datenblatt ist die Adresse dann so 1010 000 + RW(0x50 ohne RW) die drei
nullen das sind die Analogen Pins. Da ich ja alle auf Masse gezogen habe
sind sie ja "0". Um die "Daten" zu senden habe ich mich an diesen
Tutorial vom Arduino Orientiert:
http://www.hobbytronics.co.uk/arduino-external-eeprom
Ich habe mal meine s_epprom.c und s_epprom.h Dateien angehangen. Die I2C
Library von Peter Fleury. Nur der "Lite" Version. Also nur das was ich
brauche(i2c_init, start, stop, write, readAck(heißt bei mir nur read).
Habe ich mir kopiert. Um Speicherplatz zu sparen. Ich arbeite mit dem
ATMega328P mit 16 MHz.
so schreibe/lese ich einen Wert:
1
writeEEPROM(0, 123); // 0 ist die Adresse im EEPROM und 123 das byte
2
3
readEEPROM(0); //0 ist die Adresse im EEPROM. Aber es wird auf dem LCD nicht dargestellt. Dort steht einfach nur "EEPROM Value: " eig. sollte da stehen "EEPROM Value: 123"
Hat da jemand ne Idee was ich falsch gemacht habe?
Mfg Felix
Felix N. schrieb:> Ich habe die drei Analogen Pins(A0, A1, A2) auf Masse gezogen.
Das sind 'adress pins', nicht 'Analog Pins'.
> Und laut> Datenblatt ist die Adresse dann so 1010 000 + RW(0x50 ohne RW) die drei> nullen das sind die Analogen Pins. Da ich ja alle auf Masse gezogen habe
Wie kommst du drauf ?
Adresse ist 0xA0 oder 0xA1, je nachdem ob du lesen oder schreiben
willst.
Marc V. schrieb:> Wie kommst du drauf ?
Im Datenblatt steht Device Select Code:
1010 A10 A9 A8 RW
http://prntscr.com/b6hf0u
Und weil ja die adress pins auf Masse liegen müsste sie ja "0" sein. Und
dann kommt ja wenn man A10 A9 und A8 durch 000 ersetzt 1010000 ohne RW
Bit.
http://numbermonk.com/binary/80/de
0x50 und beim Ansprechen dann noch das RW Bit:
i2c_start(I2C_DEVICE_ADRESS + I2C_WRITE);
I2C device ist 0x50 und i2c_write ist 0
H.Joachim S. schrieb:> Genau das ist doch die bekannte Adresse für Eeproms, 0xA0 bzw 0xA1.> Wo ist dein Problem?
Das Problem ist das ich diesen nicht ansprechen kann. Das LCD schon mit
0x4E. Wenn ich aber vor der while(1) Schleife was ins EEPROM schreibe
und dann noch ne Zeile im Display änderen will. Geht das nicht. Also er
bleibt beim writeEEPROM() hängen. 0xA0 oder 0xA1 ist auch kein
Unterschied
@Felix Neumann (felix_n888)
>Das Problem ist das ich diesen nicht ansprechen kann. Das LCD schon mit>0x4E.
Deine Software arbeitet mit 8-Bit Adressen.
Aber auch das kann man leicht rausfinden. Sprich in einer Schleife alle
Adressen von 0x00 bis 0xFF an, wenn ein ACK kommt, ist es eine gültige
Adresse.
Falk B. schrieb:> Aber auch das kann man leicht rausfinden. Sprich in einer Schleife alle> Adressen von 0x00 bis 0xFF an, wenn ein ACK kommt, ist es eine gültige> Adresse.
Gute Idee.
Nur wie setzt man das am besten in die Praxis um. Denn mit einer for
Schleife die von 0 bis xx zählt geht ja schlecht. Da ja später auch noch
Buchstaben kommen. Und dann i2c_start(Adresse) und bei return 0 ist es
ja ne gültige Adresse und wenn return 1 kommt ja nicht. Oder?
//EDIT Wahrst schneller.
Falk B. schrieb:> enn ein ACK kommt, ist es eine gültige> Adresse.
Ich habe mein LCD Display abgeklemmt für denn Test. Und auf 0x160 kommt
eine Antwort.
http://prntscr.com/b6i63u
Falk B. schrieb:> Was wohl daran liegt, daß deine I2C Funktionen eine 7 Bit Adresse haben> wollen. Also eher 0x50 als 0xA0.Felix N. schrieb:> Und laut> Datenblatt ist die Adresse dann so 1010 000 + RW(0x50 ohne RW) die drei
Und laut Datenblatt ist die Adresse 0xA0 oder 0xA1 (wie das auch bei
allen Datenblättern die von Hersteller stammen, der Fall ist).
Warum Leute immer noch anstatt 0xA0 0x50 benutzen, um dann in der
I2C-Routine mit irgendwelchen (völlig unnötigen) bitschiebereien zur
richtigen Adresse zu gelangen, wird mir immer ein Rätsel bleiben.
I2C benutzt zwar nur 7 bit zur Adressierung aber es sind die oberen
7 bits. Bit 0 ist für R/W reserviert und wird immer ausgeblendet.
Felix N. schrieb:> Ich habe mein LCD Display abgeklemmt für denn Test. Und auf 0x160 kommt> eine Antwort.
Sage ich doch.
@ Felix Neumann (felix_n888)
>> enn ein ACK kommt, ist es eine gültige>> Adresse.>Ich habe mein LCD Display abgeklemmt für denn Test. Und auf 0x160 kommt>eine Antwort.
Das glaube ich mal keine Sekunde, denn die I2C Adresse ist im Normalfall
< 0xFF sprich kleiner als 255 ;-)
>http://prntscr.com/b6i63u
Nach 0x8 kommt im Hexadezimalsystem eher nicht 0x10. Deine 0x Vorsilbe
ist Unsinn! Deine 160 (dezimal) ist 0xA0 (hexadezimal)!
Falk B. schrieb:> Nach 0x8 kommt im Hexadezimalsystem eher nicht 0x10. Deine 0x Vorsilbe> ist Unsinn! Deine 160 (dezimal) ist 0xA0 (hexadezimal)!
Auf 0xA0 bekomme ich auch nur eine Antwort. Ich spreche denn Chip jetzt
per i2c_start(0xA0) an ohne das + 0 und + 1.
Das scheiben ins EEPROM scheint ja zu funktionieren. Zumindestens bleibt
er dort nicht hängen. Aber beim readEEPROM bleibt er stehen. Um genauer
zu sein bleibt er beim i2c_readAck() hängen. Es ist nämlich diese Zeile:
while(!(TWCR & (1<<TWINT)));
Dort bleibt er hängen.
@ Felix Neumann (felix_n888)
>while(!(TWCR & (1<<TWINT)));>Dort bleibt er hängen.
Hast du die Pull-Up Widerstände am Bus vergessen? SDA und SCL brauchen
jeweils ca. 5kOhm gegen VCC!
Falk B. schrieb:> Hast du die Pull-Up Widerstände am Bus vergessen? SDA und SCL brauchen> jeweils ca. 5kOhm gegen VCC!
Nein habe ich nicht. Zwischen SDA und SCL sind 10 k Ohm gegen VCC. Mein
LCD funktioniert. Wenn die Anschlüsse vom EEPROM Chip auf das LCD
umsteckte und die Adresse ändere. Dann funkt. das ja. also das LCD.
Felix N. schrieb:> Denn mit einer for Schleife die von 0 bis xx zählt geht ja schlecht. Da> ja später auch noch Buchstaben kommen.
Wie meinst du das? Hast du da noch Nachholbedarf bei den
Zahlendarstellungen? Dir ist schon klar, dass die Hex-Darstellung nur
eine kompaktere und "binärere" Darstellung einer "ganz normalen"
Integerzahl ist?
Felix N. schrieb:> Dort bleibt er hängen.
Hast du ein (Speicher)Oszilloskop oder einen Logikanalyzer zur Hand?
@ Felix Neumann (felix_n888)
>Auf 0xA0 bekomme ich auch nur eine Antwort. Ich spreche denn Chip jetzt>per i2c_start(0xA0) an ohne das + 0 und + 1.
MÖÖÖÖP!!! Du musst schon zum Lesen +1 addieren, sonst denkt der IC, du
willst schreiben!
>zu sein bleibt er beim i2c_readAck() hängen. Es ist nämlich diese Zeile:>while(!(TWCR & (1<<TWINT)));>Dort bleibt er hängen.
Wahrscheinlich weil du die SCHREIBadresse verwendest!
Bastian W. schrieb:> Bist du sicher das du i2c_read() nach dem i2c_stop ausführen solltest ?
Danke. Seit dem bleibt er dort nicht mehr hängen.
Falk B. schrieb:> Wahrscheinlich weil du die SCHREIBadresse verwendest!
Okay. Nun funktioniert es teilweise. Nur der Zurück kommende Wert ist im
0xFF also 255. Es macht dabei kein Unterschied ob ich rdata auf
i2c_read() setzte oder i2c_read() direkt ins sprintf. Ich habe mal denn
neuen readEEPROM() Code angehangen.
Die Dateien sind beide die gleichen. Habe nur das .c für die Codeansicht
vergessen
@ Felix Neumann (felix_n888)
>Okay. Nun funktioniert es teilweise. Nur der Zurück kommende Wert ist im>0xFF also 255.
Weil du vorher keine gescheiten Daten ins EEPROm geschrieben hast. Oder
der Schreibzugriff fehlgeschlagen ist, wenn z.B. das WP Pin auf LOW
liegt ;-)
Falk B. schrieb:> Weil du vorher keine gescheiten Daten ins EEPROm geschrieben hast. Oder> der Schreibzugriff fehlgeschlagen ist, wenn z.B. das WP Pin auf LOW> liegt ;-)
Ins EEPROM schreibe ich ja mit writeEEPROM nur ob das auch erfolgreich
funktioniert kann ich nicht sagen. Bei mir sind A0, A1, A2, Vss, Mode/WC
auf LOW und Vdd auf +5 Volt. Und SDA und SCL am Controllor. Ich denke
mal das WP WC ist. Denn soweit ich weis heißt WP hat Write Protection.
Und WC heißt Write Control. Muss ich diese auf HIGH setzten also +5
Volt?
Falk B. schrieb:> Nein, LOW ist bei dem IC OK. Siehe Datenblatt.
Okay. Die meisten i2c Methoden geben ja ein Status zurück 0 Alles Okay 1
Fehler. Ich mir ein uint8_t Variable erstellt und bei i2c_start und bei
denn i2c_write Methoden in der EEPROM_write Methode die Variable davor
gesetzt. Also so test = i2c_...();
Beim Ansprechen(i2c_start()) kommt 0 zurück also Alles okay
Beim Schreiben von eepromaddress >> 8 kommt auch noch 0 zurück
Beim Schreiben von eepromaddress & 0xFF kommt 1 zurück fehler
Beim Schreiben von dem Wert der Dort hin soll(123 bei mir) kommt auch 1
zurück. Also mache ich was beim schreiben falsch. Würde ich mal sagen.
Ich schreibe ja beim zweiten mal eepromaddress & 0xFF. Das ist 255 kann
es sein das dort schon der Wert hin kommt also(123). Ich denke mal das
das eepromaddress & 0xFF noch zur Adressierung gehört?
@Felix Neumann (felix_n888)
>Fehler. Ich mir ein uint8_t Variable erstellt und bei i2c_start und bei>denn i2c_write Methoden in der EEPROM_write Methode die Variable davor>gesetzt. Also so test = i2c_...();
Du hast gar keine Methoden, denn das hier ist simples C, kein C++.
>Beim Ansprechen(i2c_start()) kommt 0 zurück also Alles okay>Beim Schreiben von eepromaddress >> 8 kommt auch noch 0 zurück>Beim Schreiben von eepromaddress & 0xFF kommt 1 zurück fehler
Schlecht.
>Beim Schreiben von dem Wert der Dort hin soll(123 bei mir) kommt auch 1>zurück. Also mache ich was beim schreiben falsch. Würde ich mal sagen.
Ja. u.a. bei der Adressierung. Denn die hat bei diesem IC nur EIN
Adressbyte! Die oberen 3 Adressbits stecken in den I2C Adressbits 3-1!
Damit erscheint der 16 kBit EEPROM löogisch als 8 einzelne EEPROMs mit
je 2 kBit. Und damit braucht man nur ein Adressbyte für die unteren 8
Adressbits.
>Ich schreibe ja beim zweiten mal eepromaddress & 0xFF. Das ist 255 kann>es sein das dort schon der Wert hin kommt also(123). Ich denke mal das>das eepromaddress & 0xFF noch zur Adressierung gehört?
Ja, aber das ist falsch. Siehe Datenblatt.
Trotzdem darf beim Schreiben von mehreren Daten kein Fehler kommen.
Falk B. schrieb:> Trotzdem darf beim Schreiben von mehreren Daten kein Fehler kommen.
Hmm, okay kleiner Fortschritt. Nun kommt keine Fehler mehr beim
Schreiben.
Ich habe bei readEEPROM nun was anderes gemacht. Gehe erst in denn
Schreib Modus schreibe mit i2c_write(eepromaddress >> 8) und
eepromaddress & 0xFF. Dann mache ich i2c_rep_start() mit Lese Modus. Nur
dann kommt wenn ich i2c_read() mache nicht der Wert zurück denn ich dort
reingeschrieben habe sondern die Adresse. Also wenn die Adresse 0 ist
und der Wert 255. Dann kommt nicht 255 zurück sondern 0 wenn ich Adresse
aber 255 ist und der Wert 0 also genau anderes rum. Dann kommt 255 mit
i2c_read() zurück.
Komisch.
HI
Das Datenblatt hast du dir aber durchgelesen? Wenn ja, dann weißt du
auch, das
i2c_write(eepromaddress >> 8);
i2c_write(eepromaddress & 0xFF);
nicht stimmt.
MfG Spess
spess53 schrieb:> Das Datenblatt hast du dir aber durchgelesen? Wenn ja, dann weißt du> auch, das>> i2c_write(eepromaddress >> 8);> i2c_write(eepromaddress & 0xFF);>> nicht stimmt.
HI,
In meinen Datenblatt finde ich das so ähnlich: http://prntscr.com/b6nfpg
Sorry, für die Frage aber wie muss es dann richtig heißen?
Komme grade mit meinen Wissen nicht mehr hinterher.
spess53 schrieb:> Das Datenblatt hast du dir aber durchgelesen?
Bestimmt nicht.
> Wenn ja, dann weißt du auch, das> i2c_write(eepromaddress >> 8);> i2c_write(eepromaddress & 0xFF);> nicht stimmt.
Falk hat ihn schon darauf aufmerksam gemacht, hat aber anscheinend
nichts gebracht. Er versucht es stur auf die falsche Art in der
Hoffnung, dass der klügere (24C16) nachgibt...
@ Felix Neumann (felix_n888)
>In meinen Datenblatt finde ich das so ähnlich: http://prntscr.com/b6nfpg>Sorry, für die Frage aber wie muss es dann richtig heißen?
Es gibt nur EIN Adressbyte!
Falk B. schrieb:> Es gibt nur EIN Adressbyte!
Erst mal möchte ich mich bei euch bedanken! Vielen dank an euch alle.
Funktionieren tut es nun. Beim nächsten mal wieder ich mich erst mit dem
Datenblatt auseinander setzten bevor ich hier was poste.
Eine Frage hätte ich da noch, und zwar. Wenn ich zwei mal hinter
einander was ins EEPROM Schreibe also so
writeEEPROM(0, 0x4E);
writeEEPROM(1, 0x27);
davor noch mit 2 Sek. Delay damit ich mich noch eben im HTerm verbinden
kann um die Werte Serial auszulesen. Nur dann bleibt er dort hängen.
Wenn ich aber ein Wert schreibe dann auslese kurz warte dann wieder
schreibe und auslese. Dann funktioniert es.
Ist das normal?
@ Felix Neumann (felix_n888)
>Eine Frage hätte ich da noch, und zwar. Wenn ich zwei mal hinter>einander was ins EEPROM Schreibe also so>writeEEPROM(0, 0x4E);>writeEEPROM(1, 0x27);>davor noch mit 2 Sek. Delay damit ich mich noch eben im HTerm verbinden>kann um die Werte Serial auszulesen.
Wieso? Man kann auch beim Programmstart auf ein Startzeichen vom UART
warten.
> Nur dann bleibt er dort hängen.>Wenn ich aber ein Wert schreibe dann auslese kurz warte dann wieder>schreibe und auslese. Dann funktioniert es.>Ist das normal?
Woher sollen wir das wissen? Wir kennen dein Prgramm doch gar nicht!!
Wir haben keine Glaskugel!
https://www.mikrocontroller.net/articles/Netiquette#Klare_Beschreibung_des_Problems
"Daran denken, dass die Leute im Forum nicht neben einem sitzen und
alles so vor sich sehen wie der Fragesteller"
Falk B. schrieb:> Woher sollen wir das wissen? Wir kennen dein Prgramm doch gar nicht!!> Wir haben keine Glaskugel!
Sorry. Also die writeEEPROM und readEEPROM sind identisch mit deiner die
du gepostet hast. Meine main.c Klasse habe ich angehängt.
@ Felix Neumann (felix_n888)
>Sorry. Also die writeEEPROM und readEEPROM sind identisch mit deiner die>du gepostet hast. Meine main.c Klasse habe ich angehängt.
Du hast auch keine Klasse, also zumindest keine C++ Klasse ;-)
Das Programm ist soweit OK, auch wenn einige unsinnige Konstrukte drin
sind.
sei() macht man nicht, wenn keinerlei Interrupts verwendet werden.
Die Funktionen zum Schreiben sollten funktionieren und nicht hängen
bleiben.
Falk B. schrieb:> Du hast auch keine Klasse, also zumindest keine C++ Klasse ;-)>> Das Programm ist soweit OK, auch wenn einige unsinnige Konstrukte drin> sind.>> sei() macht man nicht, wenn keinerlei Interrupts verwendet werden.>> Die Funktionen zum Schreiben sollten funktionieren und nicht hängen> bleiben.
Das ich so oft Klassen, Methoden etc.. sage liegt dran das ich auch noch
Java Programmiere. Okay muss mich korrigieren, das schreiben
funktioniert. Wenn ich nach dem _delay_ms(1000); eine Debug Message
sende kommt diese auch im USART an. Er bleibt dann beim readEEPROM()
hängen. Zumindestens kommt "Value = WERT VOM EEPROM" nicht im USART an.
//EDIT Die i2c Methode(Weis nicht wie es anderes nennen soll, wenn es
keine Methoden sind) bei der readEEPROM() geben alle 0 zurück also kein
Fehler. Aber trotzdem kommt nix im USART an.
Nochmal eine Kurze Frage. Wie kann man so ein Chip zerstören. Ohne
Gewalt Einwirkungen. Denn ich habe mir davon 3 Stück gekauft. Und habe
grade denn mal gegen einen anderen ausgetauscht. Und dann kam auch
wieder der Wert im USART an.
Kann man so ein Chip leicht zerstören?
Felix N. schrieb:> Nochmal eine Kurze Frage. Wie kann man so ein Chip zerstören. Ohne> Gewalt Einwirkungen. Denn ich habe mir davon 3 Stück gekauft. Und habe> grade denn mal gegen einen anderen ausgetauscht. Und dann kam auch> wieder der Wert im USART an.>> Kann man so ein Chip leicht zerstören?
Hammer ;-)
Wenn du durch einen Fehler im Programm eine Endlosschleife bastelst und
fleißig in den EEProm schreibst, dann bekommst du den auch kaputt.
Sascha
Ich sage es immer wieder, ein (Saleae) Logic Analyzer (Clone) kostet
<10Euro (Prime ca. 16Euro), die SW ist in Form von Sigrok kostenlos.
Damit hat man solche Probleme binnen Minuten geklärt, denn die Bedienung
ist ein Kinderspiel, fertige Decoder für x Anwendungen machen es
möglich.
Harald schrieb:> Ich sage es immer wieder, ein (Saleae) Logic Analyzer (Clone) kostet> <10Euro (Prime ca. 16Euro), die SW ist in Form von Sigrok kostenlos.> Damit hat man solche Probleme binnen Minuten geklärt, denn die Bedienung> ist ein Kinderspiel, fertige Decoder für x Anwendungen machen es> möglich.
Der nützt nichts wenn man das Datenblatt nicht liest und schon falsche
Kommandos sendet. Dann zeigt der LA was man sehen will und trotzdem geht
nichts.
Sascha
@ Felix Neumann (felix_n888)
>> Die Funktionen zum Schreiben sollten funktionieren und nicht hängen>> bleiben.>//EDIT Die i2c Methode(Weis nicht wie es anderes nennen soll,>wenn es keine Methoden sind)
Es sind alles ganz einfache FUNKTIONEN!
Sascha W. schrieb:> Harald schrieb:>> Ich sage es immer wieder, ein (Saleae) Logic Analyzer (Clone) kostet>> <10Euro (Prime ca. 16Euro), die SW ist in Form von Sigrok kostenlos.>> Damit hat man solche Probleme binnen Minuten geklärt, denn die Bedienung>> ist ein Kinderspiel, fertige Decoder für x Anwendungen machen es>> möglich.> Der nützt nichts wenn man das Datenblatt nicht liest und schon falsche> Kommandos sendet. Dann zeigt der LA was man sehen will und trotzdem geht> nichts.>> Sascha
Ja, das ist wohl leider wahr! Der einzige Trost beim LA ist die
Klartext-Anzeige der Dinge, die man tut. Für EEPs gibt es komplette
Decoder, da steht es dann Schwarz auf Weiß. Vielleicht kann so ein Tool
helfen, wobei natürlich gilt: A fool with a tool is still a fool.