OK,
da offensichtlich niemand meine Berechnung dementiern möchte, fahre ich fort:
In der Reset-Funktion wird die "I2CInit" aufgerufen.
SCL und SDA sind beim MEGA32 PC0 und PC1. Um mir die externen PullUps zu sparen, nehme ich die innern (Hab gelesen, dass das kein Problem darstellt):
| Code : |
I2CInit:
ldi r16,(1<<PC0)+(1<<PC1)
out PORTC,r16 |
|
Das Bitrate-Register wird also mit 72 gefüllt:
Und der Prescaler mit 0 (PS=1)
Ende:
Im Datenblatt ist auf Seite 180 ein schönes Beispiel gegeben. Diesen hab ich fast eins-zu-eins übernommen und "SENDEN" genannt. Der einzige Unterschied ist, dass ich weder SLA_W (Slave-Adresse) noch DATA (zu sendende Byte) als Konstante vorliegen habe, sondern in den Registern ADR und BYTE.
Die verwendeten Status-Codes sind auf Seite 183 zu finden.
| Code : |
.equ START = 0x08
.equ MT_SLA_ACK = 0x18
.equ MT_DATA_ACK = 0x28 |
|
In der ERROR-Funktion (sie wird aufgerufen wenn der Start missglückt oder kein ACK-Bit zurückgesendet wurde) schalte ich einfach nur ne LED ein. Diese wird später im Prog wieder gelöscht und ich erkenne an einer flackernden LED das Nichtfunktioniren des Bus.
Mein MAIN-Funktion sieht ganz einfach aus. Ein Counter, bei jedem Durchlauf decrementiert, wird an eine Reihe PCF8574 gesendet, noch ein bissl warten und das ganze von vorn:
| Code : |
MAIN:
dec COUNTER
mov BYTE,COUNTER
ldi ADR,0x40
rcall SENDEN
ldi ADR,0x42
rcall SENDEN
...
<ein bissl warten>
<Error-LED (wieder) aus>
rjmp MAIN |
|
Das wars schon!
Macht eine wunderschön flackernde Error-LED.
Ich hoffe dass jetzt irgend jemand die Muse hat sich an das Datenblatt zu setzen und mir dann erklärt warum es net so tut wies soll.
Danke auch an die, die sich meinen Beitrag wenigstens durchgelesen habe. (Es kommt recht selten vor dass ICH solche EIER bis zum Ende lese.)
[ Diese Nachricht wurde geändert von: HarryGr am 4 Jan 2005 1:19 ]