Hallo Alf,
das grunsätzliche Problem bei I2C ist, daß die SDA-Leitung bidirektional
arbeitet, im Gegensatz zur SCL-Leitung, wo immer der Master (Controller)
die Leitung treibt und die Clock-Impulse ausgibt.
Damit auf der SDA-Leitung Daten bidirektional gesendet werden können,
wurde sie als WIRED OR definiert, d.h. ein 10k Widerstand hält die
Leitung immer High; die einzelnen Busteilnehmer dürfen sie zu bestimmten
Zeitpunkten gegen Masse ziehen (=Low). Tun das mehrere zur gleichen
Zeit, entsteht zumindest kein Schaden.
Dazu ist ein Open-Collector- oder Open-Drain-Transistor erforderlich.
Wird ein Prozessorport als Ausgang konfiguriert, bekommst Du nicht nur
beim Acknowledge Probleme, sondern auch wenn der Slave (EEPROM) seine
Daten sendet.
Hier gibt es jetzt zwei Möglichkeiten:
1. Beim PIC gibt es je nach Modell meistens am Port A einen Pin, der nur
als Open-Drain arbeitet, d.h. der Transistor, der die Leitung auf High
zieht, fehlt. Zu den Zeiten, wo Du Daten vom Slave erwartest, mußt Du
den Pin High schalten, dann ist er vom Prozessor her passiv, und das
EEPROM kann die SDA-Leitung auf Masse legen.
2. Beim Atmel und den meisten anderen Controllern gibt es so einen Pin
nicht. Hier muß man einen normalen Port benutzen. Das funktioniert aber
auch: Solange der Master Daten sendet, gibst Du über SDA entweder High
oder Low aus. Der externe 10k Widerstand ist in diesem Fall
bedeutungslos, und dem EEPROM ist es egal.
Sobald aber Daten vom EEPROM erwartet werden, also z.B. beim neunten
Clock oder beim Einlesen der Daten, schaltest du bereits vorher den
SDA-Pin als Eingang! Dann wird der Pegel auf der SDA-Leitung nur vom
EEPROM bestimmt. Jetzt brauchst Du nur noch den Zustand des Pins
einzulesen (Achtung: beim Atmel geht das über die PINx-Register, die
PORTx-Register sind nur für den Ausgang) Achte auch darauf, die internen
Pull-Up-Widerstände des Atmels zu deaktivieren, diese sind so
niederohmig, daß es manchmal Probleme mit externen Pull-Ups gibt.
Anschließend schaltest Du den SDA-Pin wieder als Ausgang (mit dem
richtigen Pegel).
Noch ein Tip: die meisten EEPROMS sind für 100 kHz oder 400 kHz Bustakt
gedacht. Achte darauf, die notwendige Anzahl Mikrosekunden zu warten,
nachdem eine Leitung ihren Zustand gewechselt hat. Auch beim Einlesen
von SDA empfehlen sich einige NOPs, da das Aufladen der
Leitungskapazität durch den 10k Widerstand in Controller-Dimensionen
recht lange dauert.
Welchen Prozessor benutzt Du eigentlich?