Forum: Mikrocontroller und Digitale Elektronik I2C / TWI EEPROM 24C02B


von 7_of_9 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich möchte per Software ein serielles (I2C) eeprom ansteuern.
leider gelingt es mir nicht es zu assimilieren ;-)

Ich bekomme kein ACK nach dem ich die EEPROM Adresse und das write bit 
gesendet habe.

Mit den Bibliotheken im Compiler scheint es zu funktionieren obwohl ich 
auch da kein ACK seitens des EEPROMS feststellen konnte weswegen ich es 
nochmal selbst schreiben wollte.

Ich benutzte ein 24C02B von Microchip, liegt an 5V. Alle Adressbits sind 
= 0 und WP ist auch 0 (keine write protection).
SDA und SCL liegen über 10K an VCC.

Wenn das EEPROM nicht eingesteckt ist sieht das Signal so aus wie im 
Datenblatt.
Stecke ich es ein, kommt die "Start Condition" nicht mehr an, auch ist 
nach der Übetragung SDA immer low obwohl es input ist mit pull up 
versehen...

Siehe hierzu die beiden Bilder vom Oszi, sowie vom EEPROM.
Controller und PullUps sitzen auf dem Entwicklungsboard.

Wahrscheinlich hab ich etwas übersehen sonst würde es ja auch generell 
nicht funktionieren.

tnx
7

von 7_of_9 (Gast)


Lesenswert?

Oh jetzt hab ich doch glatt den Programmcode vergessen ...

program att13softuart1;
//running on atmega8 8mhz external clock (from crystal)
var I2C_Scl_Output        : sbit at PORTB0_bit;
var I2C_Sda_Output        : sbit at PORTB1_bit;
var I2C_Scl_Input         : sbit at PINB0_bit;
var I2C_Sda_Input         : sbit at PINB1_bit;
var I2C_Scl_Direction : sbit at DDB0_bit;
var I2C_Sda_Direction : sbit at DDB1_bit;

procedure sendbyte(datenwort: byte);
var i: byte;
    begin
    i:=0;
    while i <8 do begin
    I2C_Sda_output := datenwort.7;
    datenwort := datenwort shl 1;
    delay_us(15);
    I2C_Scl_output := 1;
    delay_us(15);
    I2C_Scl_output := 0;
    delay_us(15);
    inc(i);
    end;
    I2C_Sda_Direction := 0;
    //await ack
    end;

begin
  I2C_Sda_output := 1;
  I2C_Scl_output := 1;
  I2C_Scl_Direction := 1;
  I2C_Sda_Direction := 1;

  delay_us(15);
  I2C_Sda_output :=0;  //start condition
  delay_us(15);
  I2C_Scl_output := 0;  //clock low
  delay_us(15);
  sendbyte(160); //sending device adress + write
end.

von Klaus 2. (klaus2m5)


Lesenswert?

Was mir ins Auge sticht: die Clock bleibt am Ende low, auch mit offenem 
Ausgang. Dir fehlt noch eine halbe Clock, oder Du fängst auf der 
falschen Flanke an.

von Mike R. (thesealion)


Lesenswert?

Dein EEPROM möchte dir vielleicht ein ACK senden, allerdings forderst du 
es nicht dazu auf.
Dir fehlt einfach der Clock Puls, bei dem das EEPROM das Ack senden 
soll. Von sich aus darf es das nicht, der Puls muß vom Master generiert 
werden.

von 7_of_9 (Gast)


Lesenswert?

Also der ClKport ist nach dem 8takt immer noch ausgang. Nur der SDAport 
wird als Input geschaltet.
Ich dachte der Master (µC) wartet auf das ACK und macht dann den 9Takt, 
deswegen wäre es ja nicht notwendig CLK als Input zu schalten oder?

Klaus 2m5 schrieb:
> Dir fehlt noch eine halbe Clock, oder Du fängst auf der
> falschen Flanke an.

...wieso? das Bit wird mein ich gültig zur steigenden Taktflanke. Und da 
sind 8 da. Oder meinst du ich muss bevor ich auf das ACK warte nochmal 
takten?

von spess53 (Gast)


Lesenswert?

Hi

>  I2C_Sda_output := 1;
>  I2C_Scl_output := 1;


Bei Software-I2c wird Portx nicht auf H gesetzt. Das bleibt immer auf L. 
Es wird lediglich DDRx geschaltet.

MfG Spess

von 7_of_9 (Gast)


Lesenswert?

gut, ich habe vor ende der procedure sentbyte noch die Anweisung 
I2C_Scl_output := 1; gesetzt um noch einen Takt zu erzeugen.
Allerdings bleibt SDA immer low egal welche adresse ich sende.

von 7_of_9 (Gast)


Lesenswert?

spess53 schrieb:
> Bei Software-I2c wird Portx nicht auf H gesetzt. Das bleibt immer auf L.
> Es wird lediglich DDRx geschaltet.

hmm du verwirrst mich ein bisschen. Um die start condition zu erzeugen 
müssenja SDA und CLK erstmal beide high sein, während dann SDA auf low 
geht ...
außerdem bleiben sie ja nicht immer auf high sondern nur eben am anfang.

von Daniel H. (doomstar)


Lesenswert?

Hi

du hast auch ein pull up Widerstand für die beiden Bus Leiteungen 
verwenden?

auf dem Bild seh ich die leider nicht?

Gruß
Daniel

von spess53 (Gast)


Lesenswert?

Hi

>hmm du verwirrst mich ein bisschen.

Um ein H auf der Busleitung zu erzeugen, wird das Pin auf Eingang 
geschaltet.
Der Pull-Up zieht die Leitung dann auf H. Das L wird durch Setzen als 
Ausgang erzeugt. Es gab mal eine AppNote von Atmel zu Software-I2C. Wenn 
es dich interessiert, kann ich die mal anhängen.

MfG Spess

von 7_of_9 (Gast)


Angehängte Dateien:

Lesenswert?

Jo hab hier auch nochmal ein pic.
ich hatte die auch schonmal direct am EEPROM hat aber auch nix gebracht.
Ich denke eher das liegt am timing oder am EEPROM. Allerdings sollte das 
EEPROM 400khz takt verkraften da bin ich noch weit von entfernt ...

von 7_of_9 (Gast)


Lesenswert?

spess53 schrieb:
> Es gab mal eine AppNote von Atmel zu Software-I2C. Wenn
> es dich interessiert, kann ich die mal anhängen.

ja das wäre nett vielleicht springt mir ja was ins okkular implantat.

Ich habe es trotzdem schonmal so geändert das ich low high mit 
input/output schalte.

Was mich etwas verwunder hat ist, dass obwohl ich zu Beginn beide Pins 
als Input habe, SDA low ist wenn das EEPROM eingesteckt ist ansonsten 
high.
Das EEPROM darf SDA doch nicht auf low ziehen oder?

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>ja das wäre nett vielleicht springt mir ja was ins okkular implantat.

Kein Problem.

>Das EEPROM darf SDA doch nicht auf low ziehen oder?

Nein. Aber möglicherweise hast du mit deinem aktiven H auf der 
Busleitung den Anschluss von EEPROM gekillt.

MfG Spess

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.