Hallo allerseits.
Als neues Lernprojekt habe ich mir zum Ziel gesetzt mal was mit einem
DS1621 zu machen. Da sich dort die Fehlersuche aber imho schwierig
gestaltet, habe ich mit der Porterweiterung PCF8574 angefangen.
Schreiben auf den Baustein funktioniert. Die Lesefunktion hängt noch.
Problem an der Stelle:
Die Wertigkeit der Pins ist um 1 Bit verschoben:
- An P0 lese ich 2 aus
- P1 gibt 4 zurück
- P2 gibt 8 zurück usw ...
- P1 + P2 gleichzeitig ergibt 6 (2+4 ...)
Also im Ansatz liege ich wohl richtig. Ich finde nur nicht wo sich
dieses verlorene Bit versteckt hat :-/
Im Anhang ist der komplette I2C-Code. Mir ist bewusst, dass es dort noch
sehr viel Verbessrungspotential gibt. (Z.B. etliche delays
rausschmeissen ...)
Hier mal direkt die Lesefunktion:
1 | I2C_read:
|
2 | push tmp3 ; Working Registers
|
3 | push temp2
|
4 |
|
5 | ldi temp1, 0x00 ; Ausgabevariable initialisieren.
|
6 | ldi temp2, 0x08 ; Schleifenzähler
|
7 |
|
8 | in tmp3, SDADIR ; SDA-Direction auf Eingang
|
9 | andi tmp3, 0b11111101
|
10 | out SDADIR, tmp3
|
11 | nop
|
12 | ;--------------------------------------------------
|
13 | I2C_loop3: rcall I2C_ClockPulse
|
14 | clc ; Carry löschen
|
15 | sbic SDAREAD, SDA ; Wenn SDA=0 überspringe den SEC Befehl
|
16 | sec ; SDA=1? Dann setzte Carry Flag. Anm.: Durch den folgenden ROL Befehl wird das ggf gesetzte Carry Flag zum Bit0 des einzulesenden Wertes!
|
17 | rol temp1 ; Ausgabevar um 1 Bit nach oben schieben
|
18 | dec temp2 ; Schleifenzähler - 1
|
19 | brne I2C_loop3 ; Schon bei 0 angekommen ?
|
20 | ;--------------------------------------------------
|
21 |
|
22 | in tmp3, SDADIR ; SDA-Direction auf Ausgang
|
23 | ori tmp3, 0b11111111
|
24 | out SDADIR, tmp3
|
25 |
|
26 | pop temp2
|
27 | pop tmp3
|
28 |
|
29 | rcall I2C_Stop
|
30 |
|
31 | ret ; Abrage der Daten ist beendet
|
Es würde mich sehr freuen, wenn sich Jemand mal den Code anschauen würde
und mir hoffentlich sagen kann an welcher Stelle ich ein Brett vorm Kopf
hatte/ habe.
Grüße,
Alexander