Hi @all, ich habe jetzt schon so einiges gelesen was I2C (TWI) betrifft, komme allerdings nicht wirklich weiter. Ich möchte gerne einen EEPROM 24C512 per Software I2C an meinen ATMega8 hängen programmieren tue ich in ASM, habe jetzt einfach mal folgende fragen: 1. teilweise habe ich gelesen, das es nur über externen PullUp geht, teilweise hab ich auch schon gelesen direkt an die Ports zu hängen... welches Stimmt jetzt oder Geht beides ? 2. Wie muss ich jetzt den EEPROM Ansprechen ? A0-A3 ist auf GND ? 4. Wie spreche ich dann Die Adressen im EEPROM zum lesen an ? 5. Wie spreche ich die Adressen über 255 Byte an ist ja dann schon 16 bitig oder ?? 6. Und zu guter letzt was muss ich machen um etwas zu schreiben. Hauptsächlich geht es mir um den Abflauf, den Code bekomm ich dann schon irgendwie gebacken. Hoffe das ich Die fragen jetzt nicht allzudoof gestellt habe, und bedanke mich ;) Gruß Dennis
Hallo Dennis, also ich hab das schon vor kurzem gemacht allerdings mit einem 24C16 und in C. Was die PullUps angeht: lt. Spec. müssen die da ran ergo solltest Du dies auch tun. Mag sein das es auch ohne geht, ist aber keine saubere Lösung. Für Deine Fragen 2-6 würde ich die raten Dir ein Datenblatt zu besorgen, da steht das alles drin. z.b. hier: http://www.reichelt.de/inhalt.html?SID=14QCOf0dS4AQ4AAFiixGU354e1606a051c66940bf800ccb0d3ca2;ACTION=7;LASTACTION=6;SORT=artikel.artnr;GRUPPE=A32;WG=0;SUCHE=24C512;ARTIKEL=ST%252024C512%2520BN6;START=0;END=15;FOLDER=A300;FILE=ST24C512BN6%2524%2523ATM.pdf;STATIC=0;FC=669;PROVID=0;TITEL=0;DOWNLOADTYP=1;DATASHEETAUTO= Auf Seite 11 wird da z.B. Auch geschrieben wie man den adressiert. Hoffe das Hilft, wenn nicht kannst Dich ja noch mal melden. Grüßle, der Jochen
Hi Jochen, danke erstmal für Deine Antwort, so habe mir jetzt meine Adapter Platine fertig gemacht für mein EEPROM (Habe mir so ein kleines Testboard Set gebastelt) Habe als Pull-Up jetzt von der Datenleitung zu VCC einen 4k7 genommen ist das Ok, oder ist der zu Hoch ? Wenn ich das mit dem 24C32 (oder 64 oder 256 etc...) richtig verstanden habe, muss ich einmal I2C_Start dann 8 Bit senden die z.b. in Form von 0b10100001 (0xA1) ist zum lesen, dann in den Empfangsmodus gehen und 9 Bit empfangen (1. Bit ein ACK), richtig ? Gruß Dennis
Wenn externe Pullups, dann einen von SDA nach Vcc und einen zweiten von SCL nach Vcc. Allerdings gerade heute habe ich mit meinem ATmega8L bei 8064000Hz Takt, Vcc = 3.2V, I2C Takt ~400khz, mit einem ST24C64 der eigentlich für 5.0V bestimmt ist und OHNE externe Pullups, also nur die internen Pullups aktiv, absolut keine Probleme gehabt. Die Frage ist erstmal ob du Software oder Hardware TWI benutzen willst. Meine derzeitigen WinAVR C Source sehen so aus, sind aber noch nicht fertig und werden größtenteils noch in Assembler umgestzt und müssen noch Blöcke lesen und schreiben können. Das Prinzip ist aber klar. Die Soucen nutzen TWI im Pollling mode, was für EEPROM's meistens besser ist. Gruß Hagen #define EEPROM_ADDRESS 0xA0 void i2cInit(void) { TWBR = 3; // < 400KHz bei 8.064MHz clock } uint8_t i2cStart(void) { TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWSTA); while (!(TWCR & (1 << TWINT))); return(TWSR & 0xF8); } uint8_t i2cWrite(const uint8_t Value) { TWDR = Value; TWCR = (1 << TWEN) | (1 << TWINT); while (!(TWCR & (1 << TWINT))); return(TWSR & 0xF8); } uint8_t i2cRead(const uint8_t Ack) { TWCR = (1 << TWEN) | (1 << TWINT) | (Ack << TWEA); while (!(TWCR & (1 << TWINT))); return(TWDR); } void i2cStop(void) { TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWSTO); asm("rjmp .+0"); asm("rjmp .+0"); asm("rjmp .+0"); asm("rjmp .+0"); TWCR = 0; } uint8_t EEPROMSetAddress(const uint16_t Address) { return((i2cStart() == TW_START) && (i2cWrite(EEPROM_ADDRESS & 0xFE) == TW_MT_SLA_ACK) && (i2cWrite(Address >> 8) == TW_MT_DATA_ACK) && (i2cWrite(Address) == TW_MT_DATA_ACK)); } uint8_t EEPROMPut(const uint16_t Address, const uint8_t Value) { uint8_t Ack = EEPROMSetAddress(Address) && (i2cWrite(Value) == TW_MT_DATA_ACK); i2cStop(); while (i2cStart() != TW_START) ; i2cStop(); return(Ack); } int16_t EEPROMGet(const uint16_t Address) { uint8_t Ack = EEPROMSetAddress(Address) && (i2cStart() == TW_REP_START) && (i2cWrite(EEPROM_ADDRESS | 1) == TW_MR_SLA_ACK); uint16_t Result = -1; if (Ack) {Result = i2cRead(0);} i2cStop(); return(Result); } Gruß Hagen
Achso, im i2cInit() fehlt noch { #define I2C_SDA PC4 #define I2C_SCL PC5 DDRC &= ~((1 << I2C_SDA) | (1 << I2C_SCL)); // SDA,SCL als input PORTC |= (1 << I2C_SDA) | (1 << I2C_SCL); // SDA,SCL Pullups. } Gruß Hagen
Hi Hagen, ja die Pull-Up wieder stände habe ich so gesetzt. Wie ich am Anfang schon geschrieben hatte muss ich leider SoftwareSPI nutzen, da ich bereits kaum noch Port´s frei habe. Was C betrifft, komme ich wesentlich weniger mit klar wie mit ASM :( kommt aber bestimmt als nächstes, eine runde C lernen ;) Gruß Dennis
Hallo nochmal Dennis, Also ich denke Du wirst im Netzt auch Sourcen für ein SW I2C in ASM finde. Was die Ansteuerung angeht gibt es mehrere Möglichkeiten zum lesen und schreiben. Wenn Du dazu konkret fragen oder Problem hast kannse es ja noch mal hier posten oder mich anmailen. Grüßle, der Jochen
Hi @all nochmal, so die nacht war super lang, und ich bin immer noch nicht weitergekommen :( Ich habe jetzt einfach mal den EEPROM 24c32 mit 0x09 gefüllt um dieses dann einfach mal auszulesen und dann auf PortD auszugeben, bekomme aber irgendwie immer nur 0xFF zurück :( Ich habe mal im Anhang meine Test ASM Datei gepostet, vieleicht mache ich ja auch was Grundlegendes Falsch. Bitte um Hilfe. P.S: Der EEPROM ist jetzt so angeschlossen, SDA (Pin5) an PC1 über einen PullUp von 4k7, das gleiche für SCL (Pin6) an PC0 Gruß Dennis
So wie ich das jetzt auf die Schnelle sehe schreibst und ließt Du gleichzeitig in einem I2C-Zyklus also zwischen i2c_start und i2c_stop. Das geht nicht. Du mußt das jeweils einzeln machen. So wie ich das sehe versuchst Du vom Chip mit der Adresse A0h + 1 für lesen ab der Speicherstelle 0001h zu lesen, was hat da dann das 3 putchar zu suchen. Ist das ein SW TWI? Bin net so der Assembler Crack. Wenn Du da nicht weiterkommst können wir vielleicht nacher mal per ICQ oder so schwätzen muss jetzt mal einkaufen nacher hab ich aber Zeit. Kannst Dich ja sonst mal per eMail melden. Grüßle der Jochen
Hi Jochen, danke Dir. Ich blicke in dem Datenblatt leider nicht wirklich durch, so wie ich das verstanden habe muss ich die Speicheradresse in 2 schritten übergeben also MSB dann LSB sonst wird es ab 255byte schlecht... oder habe ich da was falsch verstanden... ICQ ist schlecht bei mir, gehe immer schnell per handy online. Kann dich höchstens anrufen wenn du möchtest oder umgekehrt. Gruß Dennis
Okay, versuche mal dir klar zu machen wie ich denke das es gehen müsste (allerdings ohne Garantie da ich mich mit ASM net so auskenne) Daten aus bestimmter Stelle des EEProm lesen wie folgt: rcall i2c_start ldi r16, 0b10100000 rcall pause rcall pause rcall putbyte -> Hier wird der Baustein mit der Adr. A0h im Schreibe-Modus angesprochen da die Adresse des zu lesenden Bytes an den Baustein übergeben werden muss also schreiben: ldi r16, 0b00000000 rcall putbyte ldi r16, 0b00000001 rcall putbyte ->hier werden die zwei Adressbytes geschrieben rcall i2c_start ldi r16, 0b10100001 rcall putbyte -> hier kommt nun eine Repeated-Startbedinung hin siehe dazu Datenblatt Seite 12 [Random Read]. Da muss dan jetzt auch die 1 rein fürs lesen. rcall getbyte rcall i2c_stop -> So nun müsste das gelesene Byte im r16 stehen Daten an bestimmter Stelle im EEProm schreiben wie folgt: rcall i2c_start ldi r16, 0b10100001 rcall putbyte -> Adresse + Schreibmodus an EEPROM ldi r16, 0b00000000 rcall putbyte ldi r16, 0b00000000 rcall putbyte -> Adresse an die geschrieben werden soll 00h ldi r16, 0b0101010101 rcall putbyte -> den Wert 55h schreiben rcall i2c_stop siehe dazu auch Datenblatt S. 11 Figure 2 Byte Write So, damit sollte es eigentlich funtionieren. Was ich Dir nicht sagen kann ist ob deine ASM Routinen für das I2C okay sind. Meiner Ansicht nach sollte das ein SW-I2C sein, wenn ja Frag ich mich aber wo z.B. Die Pins für den I2C deffinieert werden - oder sind das Pin 0 & 1 vom PortC?. Naja, vielleicht hilft das erst mal. Grüßle der Jochen
Oh mist, da ist ein Fehler beim Schreiben in EEPROM muss natürlich wie folgt aussehen: rcall i2c_start ldi r16, 0b10100000 ^da muss ne Null hin, wir wollwn ja was schreiben rcall putbyte ldi r16, 0b00000000 rcall putbyte ldi r16, 0b00000000 rcall putbyte ldi r16, 0b0101010101 rcall putbyte rcall i2c_stop
Hi Jochen, SUPER!!! ;) Ich danke Dir für Deine Hilfe habe erst einfach mal Byte´s geschrieben, um zu schauen ob überhaupt erstmal das Timing hinhaut. Dann mit PC ausgelesen supi, geht ;) jetzt habe ich folgenden Code: rcall i2c_start ldi r16, 0b10100000 rcall putbyte ldi r16, 0b00000000 rcall putbyte ldi r16, 0b00000001 rcall putbyte rcall i2c_start ldi r16, 0b10100001 rcall putbyte rcall getbyte rcall i2c_stop und auch dieser geht ;) Bekomme jetzt meine EEPROM Daten, ist echt super wie jeder jedem Hilft hier ;) Dickes Lob an Dich für dein Engagement. Gruß Dennis
Mir wurde hier am Anfang auch sehr viel geholfen deshalb helfe ich nun gerne auch Leuten die die selben Problem haben die ich hatte. Schön das es nun tut. Jochen
Zu früh gefreut :( die routine scheint zu funktionieren, nur bekomme ich bei jedem 2. bis 3. mal Datenmüll, jetzt hab ich mal mein Oszi an die SDA leitung gehängt und gesehen, das der EEPROM die Leitung nicht ganz auf 0 zieht. habe jetzt als PullUP schon 1k5 und 4k7 ausprobiert, bei beiden das gleiche. Was könnte das sein ? Gruß Dennis
Spontan würde ich da jetzt auf ein Timingproblem tippen. Ich weiß leider nicht wie das da mit dem SW-I2C aussieht. Meines Wissens kann der I2C max 400kHz. kann allso sein wenn Dein Prozessor "zu schnell" getaktet ist Du ein paar Wartezyklen einbinden musst. Ein anderes Problem könnte noch der EEPROM in der Form machen das der ne gewisse Zweit braucht um Daten zu schreiben. In dieser Zeit ist keine Kommunikation mit dem Chip möglich. Sollt aber bei Dir nicht der Fall sein da Du so wie ich das sehe nur lesen tust. Ich würde es erst mal mit ein paar Verzögerungen testen und wenn das keinen Erfolg bringt darauf hoffen das Dir vielleicht jemand anderes helfen kann. Der Jochen
Hi Jochen, hast Du den Windows Messenger ? Wenn ja, kannst Du mich bitte mal unter Blackice3000@gmx.de mal anmailen. Gruß Dennis
Hey Jochen ;) also im Moment bin ich Online. Habe es im übrigen gestern Abend noch geschaft, so wie der Fehler aussah, hat der EEPROM die Stop Condition nicht richtig empfangen, habe mir noch mal eine andere Routine Angeschaut, und habe gesehen das der Fehler im I2C_STOP liegt. Jetzt haut es hin ;) Endlich bekomm ich auf mein Grafik display ein wenig mehr wie nur "." Also weiter im Basteln, jetzt muss ich mal schauen, ob ich Irgendwo Font´s finde. Ansonsten heist es selber schreiben... uff.. Gruß Dennis
Hallo Dennis Wegen der Fonts schau doch mal bei http://www.apetech.de Da sollte doch was zu finden sein. MFG Dieter
Hi Dieter, schau ich gleich mal, sollte mir bestimmt Arbeit ersparen ;) Danke Dir Gruß Dennis
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.