Forum: Mikrocontroller und Digitale Elektronik I2C Beispiel


von Tom Bayer (Gast)


Lesenswert?

Hallo zusammen,
kann mir jemand einen Tip geben wo ich ein Beispiel für eine
Ansteuerung eines I2C Beisteins finden kann. Ich verwende einen 4433
und einen SAA1064. Ich würde gerne sehen wie das mit dem Clocksignal
erzeugen und dem Timing funktioniert.
Vielen Dank Tom

von Tom Bayer (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
nachdem ich leider kein passendes Beispiel gefunden habe, habe ich mich
einfach einmal versucht.
Also ich habe einen 4433 und ich verwende einen Phillips saa1064
controller der über I2C angesteuert wird. Ich habe zwei sieben Segment
Anzeigen wie im Datenblatt angeschlossen aber leider wollen die nicht.
Ich habe den Code angehängt. Es wäre schön wenn jemand mir helfen
könnte. Ich weiss nicht woran es liegt aber meine beiden Anzeigen
machen garnichts. Vielleicht stimmt auch das timing nicht. Ich
programmiere mit Assembler
Grüße Tom

von thkais (Gast)


Lesenswert?

Zunächst ist der I²C-Bus logisch als "Open Collector" aufgebaut, d.h.
man kann die Leitung nur auf GND ziehen, ein High ist "offen" und
wird durch externe Widerstände auf VCC erzeugt. Mit dem Atmel muß man
etwas basteln, damit es funktioniert.
Ein Pin auf logisch "0": Datenrichtung = 1, Port = 0
Ein Pin auf logisch "1": Datenrichtung = 0, Port = x
Geeignete Pull-Up Widerstände sind ca. 1-10 kOhm
Dann solltest Du Dich mit dem I²C-Protokoll auseinander setzen - es
besteht aus mehr, als nur ein Byte senden. Lade Dir das Datenblatt des
SAA herunter, dort sollte das Protokoll beschrieben sein.
Prinzipiell siehts so aus:

Startbit - Adressbyte mit Datenrichtungsbit - Acknowledge - Datenbyte -
Acknowledge - evtl. weitere Datenbytes + Acknowledges - Stopbit.

von Tom Bayer (Gast)


Lesenswert?

Hallo thkais,
das mit den Widerständen habe ich nicht ganz verstanden. Also ich hatte
gedacht wenn ich dem SAA1064 eine logisch '1' gebe zieht er mir
seinen passenden Ausgang auf Masse und das Segment leuchtet. Kannst du
mir auch sagen was du mit der Software meinst. Ich habe meinen
Beispielcode angehängt und da habe ich doch auch zuerst Startbit, slave
adress usw. gesendet. Die Acknowledges habe ich halt nicht ausgelesen.
Ich habe einfach einen Takt gewartet und dann weitergemacht.
Grüße Tom

von Torsten (Gast)


Lesenswert?

Hallo,
Deine Start- und Stopbits sind falsch. Probier mal folgendes:

startbit:
    cbi    portd,sda    ;Datenleitung low
    rcall  warten      ;ganze Periode warten
    cbi    portd,scl    ;Taktleitung low
    rcall  warten      ;ganze Periode warten
    ret

stopbit:
    sbi    portd,scl    ;Takt high
    rcall  warten      ;ganze Periode warten
    sbi    portd,sda    ;Data high
    rcall  warten      ;ganze Periode warten
    ret

Am Programmanfang mußt Du sda und scl noch auf 1 setzen und an beide
Pins externe Pull-up Widerstände anschließen.

Gruß Torsten

von thkais (Gast)


Lesenswert?

@TOM:
In Deiner angehängten Datei sehe ich nichts vom Senden einer Adresse,
geschweige denn den Takt für das ACK-Bit. Vielleicht bin ich mit
Blindheit geschlagen?
Nochn Tipp: Man kann das Senden der einzelnen Bits wunderbar mit dem
Rol-Befehl machen (Schleife)

von Tom Bayer (Gast)


Lesenswert?

Hallo,

ich hatte mir das so vorgestellt mit dem senden der Adresse. Das geht
doch oder?

rcall  startbit    ;Startbit senden
ldi  byte,0b01110000          ;slave Adresse und schreiben setzen
rcall  byte_senden    ;auf Bus legen
rcall  warten      ;eine Periode auf Acknowledge warten
rcall  warten

Ich lade also die Adresse und sende sie zusammen mit 'schreiben'.
Nachdem ich das gemacht habe warte ich eine Periode und lese das Ack
NICHT aus sondern ignoriere es. Ich bin ja der einzige Master.
@thkais
wie hast du denn das mit dem rol Befehl gemeint. Sendest du dann immer
das Carry. Kann denke ich auch so gehen.

von Torsten (Gast)


Lesenswert?

Hallo Tom,

Du mußt auf jeden Fall ein 9. Taktsignal senden, damit Dein Slave das
Acknowledge-Bit überhaupt sendet. Auswerten braucht Du das natürlich
nicht unbedingt. Und wie schon gesagt, schaue Dir Deine Start- und
Stopsequenz nochmal an.

Gruß Torsten

von Tom Bayer (Gast)


Lesenswert?

Hallo Torsten,

vielen Dank. Ich habe mein Programm um diesen neunten Takt erweitert
und nun funzt es wunderbar. Ich hatte leider nicht gesehen, dass man
diesen neunten Takt auch senden muss. Ich habe gedacht der Device macht
das ganze.
Vielen Dank nochmal. Ich räume meinen Code noch ein wenig auf und
stelle ihn nochmal hierher. Aber mich würde auch gerne noch
interresieren was thkais mit dem rotieren gemeint hat. Wie soll ich mir
das denn vorstellen?
Grüße Tom

von Tom Bayer (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe mal meinen Code angehängt so wie es bei mir funktioniert. Nach
dem init werden noch eine 0 an das erste Digit und eine 9 an das zweite
Digit gesendet. Vielen Dank an alle.
Grüße Tom

von thkais (Gast)


Lesenswert?

Wie Du schon richtig vermutet hast - Mit ROL das Datenregister shiften
und immer das Carry senden, das Ganze in einer Schleife 8x. Damit
kannst Du Deinen Code um einiges kürzen - und übersichtlicher machen.

von Tom Bayer (Gast)


Lesenswert?

Hallo thkais,
wie soll ich denn mein Carry senden. Kann man direkt an einen Portpin
senden. Ich hab mir das ganze nochmal angeschaut und ich komm einfach
nicht drauf wie du das anstellen willst. Ich bin nur auf folgendes
gekommen: Rotieren->schauen ob carry gesetzt ist->dann senden. Aber ich
meine das nicht kürzer als mein Prog. Vielleicht sehe ich auch nur
nicht wie man das anders machen kann.
Grüße Tom

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.