Hallo Leute bin seit Tagen am probieren vom AT24C512B zu lesen bzw zu schreiben. Im anhang hab ich ein Testprogram was mir einen Wert in den EEPROM schreiben soll, wieder auslesen und per UART an den PC schicken soll. bekomm aber immer nur 255 gesendet. WP ist auf GND Adresse ist 1 eingstellt. Hab schon wie oft im Datenblatt gesucht aber nichts gesonderes gefunden. Vll überseh ich auch was. Kann jemand mir weiterhelfen
Wenn man vom Master zum Slave ein Byte schreibt, dann gibt der Slave ein ACK nicht der Master. Gruß Oliver
Also hab mal alle auf 0 geschrieben ausser beim Readbyte. Jetzt sendet er noch nicht einmal.
Schau dir am besten mal die I2C-Routinen von Peter Fleury an. Die funktionieren 100-prozentig. http://homepage.hispeed.ch/peterfleury/avr-software.html
Also habe es mal mit der anderen Routine Probiert aber klappt immer noch nicht. Noch eine Idee?
Peter schrieb: > bekomm aber immer nur 255 gesendet Dein Read schreibt ja auch wieder 255 rein. Zum Lesen mußt Du Repeat-Start + Leseadresse senden. Genau so, wies im Datenblatt des 24C512 steht. Und nach dem Schreiben entweder Adreß-ACK-Polling oder 10ms warten. Peter
Peter schrieb: > Peter Dannegger schrieb: >> Dein Read schreibt ja auch wieder 255 rein. > > Beim aktuellen Code? Ja natürlich. Die Richtung kann man nur mit dem I2C-Adreßbyte umschalten. Dein
1 | input = i2c_readAck(); |
macht daher ein I2C-Write mit 0xFF. Du solltest endlich mal ins 24C512 Datenblatt schauen. Da ist alles ausführlich dargestellt. Peter
Ich hab doch hier das Bit 0 (R/W Bit) in der xyz Variable auf 1 gesetzt. Damit maskiere ich meine Adresse zum senden an das EEPROM.
1 | xyz|=0b10100001; |
2 | addressout=addressout<<1; |
3 | xyz|=addressout; |
Mit der Variable adressout will ich flexibel bleiben um auch mehrere EEPROM im System beschreiben zu können.
Versuchs mal so:
1 | unsigned char eeprom_readbyte (unsigned char addressout, uint16_t eepromaddress){ |
2 | addressout = addressout<<1; |
3 | i2c_init(); |
4 | i2c_start_wait(0b10100000|addressout); |
5 | i2c_write((eepromaddress>>8)&0xFF); |
6 | i2c_write(eepromaddress&0xFF); |
7 | i2c_start_rep(0b10100001|addressout); |
8 | unsigned char input = i2c_readAck(); |
9 | i2c_stop(); |
10 | return input; |
11 | }
|
PS: RTFM. Da sieht man schön unter "Random Read", was man machen muss. Gruß Oliver
Hi sorry habs jetzt auch gesehen. Werde es nach der Arbeit mal ausprobieren. Schonmal vielen dank für die Hilfe!
So hier mal die getesteten Programme. Hat also am auslesen gelegen. auch bei dem hier zuletzt geposteten Programm ist noch der Fehler das auf ein ACK gewartet wird. Beim lesen muss aber ohne ACK gelesen werden.
1 | void eeprom_writebyte (unsigned char addressout, uint16_t eepromaddress ,unsigned char data) |
2 | {
|
3 | addressout = addressout<<1; |
4 | i2c_init(); |
5 | i2c_start_wait(0b10100000|addressout); |
6 | i2c_write ((eepromaddress>>8)&0xFF); |
7 | i2c_write (eepromaddress&0xFF); |
8 | i2c_write (data); |
9 | i2c_stop (); |
10 | }
|
11 | |
12 | unsigned char eeprom_readbyte (unsigned char addressout, uint16_t eepromaddress) |
13 | {
|
14 | addressout = addressout<<1; |
15 | i2c_init(); |
16 | i2c_start_wait(0b10100000|addressout); |
17 | i2c_write((eepromaddress>>8)&0xFF); |
18 | i2c_write(eepromaddress&0xFF); |
19 | i2c_start_wait(0b10100001|addressout); |
20 | unsigned char input = i2c_readNak(); |
21 | i2c_stop(); |
22 | return input; |
23 | }
|
Peter schrieb: > auch > bei dem hier zuletzt geposteten Programm ist noch der Fehler das auf ein > ACK gewartet wird. Genau genommen wird beim Lesen nicht auf ein ACK gewartet, sondern eines gesendet. Das aber nur, wenn man noch ein weiteres Bytes lesen möchte. Das i2c_read_ack ist natürlich deplatziert, wenn man nur ein Byte lesen will. Gruß Oliver
Hallo zusammen, macht das hier sind oder gibt es eine besser/schnellere alternative ein Pagewrite/read durchzuführen. Habe keine richtige AT24C512 lib in C gefunden.
1 | void at24c512_pagewrite(unsigned char addressout, uint16_t eepromaddress , uint8_t &ee_data, uint8_t len) //Maximal len=128 |
2 | {
|
3 | addressout = addressout<<1; |
4 | i2c_init(); |
5 | i2c_start_wait(0b10100000|addressout); |
6 | i2c_write ((eepromaddress>>8)&0xFF); |
7 | i2c_write (eepromaddress&0xFF); |
8 | for(uint8_t i=0; i<len; i++) |
9 | {
|
10 | i2c_write (ee_data); |
11 | &ee_data++; |
12 | }
|
13 | i2c_stop (); |
14 | }
|
15 | |
16 | void at24c512_pageread(unsigned char addressout, uint16_t eepromaddress, uint8_t &ee_data, uint8_t len) //Maximal len=128 |
17 | {
|
18 | addressout = addressout<<1; |
19 | i2c_init(); |
20 | i2c_start_wait(0b10100000|addressout); |
21 | i2c_write((eepromaddress>>8)&0xFF); |
22 | i2c_write(eepromaddress&0xFF); |
23 | i2c_start_wait(0b10100001|addressout); |
24 | for(uint8_t i=0; i<(len-1); i++) |
25 | {
|
26 | *ee_data=i2c_readAck(ee_data); |
27 | &ee_data++; |
28 | }
|
29 | *ee_data=i2c_readNak(); |
30 | i2c_stop(); |
31 | }
|
Peter schrieb: > Hallo zusammen, Für Deine Frage solltest Du einen neuen Thread eröffnen, statt einen nur vage mit Deinem Thema verwandten aus der fünfjährigen Versenkung zu holen.