Hi :-)
Ich bin gerade dabei einen kleinen Test mit dem I²C-Bus zur Einarbeitung
durchzuführen. Leider klappt das nicht so wie ich mir dachte. Der Slave
will einfach nicht hören.
bei Master und Slave habe ich einfach SDA und SCL miteinander verbunden
und jeweils über einen Pull-Up Widerstand von 4,7kOhm nach Vcc gelegt.
Am Master hängen 4 unterschiedlichfarbige Status-LEDs an PortB 0-3 und
eine dicke rote Error-LED an PortB 4. Ausserdem ein hardwareentprellter
Taster an PinD 2 (INT0) welcher bei fallender Flanke den Interrupt
auslöst um mein Programm auszuführen.
Am Slave hängen am PortD 0-7 insgesamt 8 gelbe LEDs nebeneinander. So
kann ich einen 8-Bit-Wert schön parallel ausgeben.
Das Testprogramm soll erstmal einen 8-Bit Wert an den Slave schicken der
diesen dann an seinem PortD ausgibt und anschließend hochzählen. Soweit
bin ich jedoch noch garnicht gekommen da der Slave nichtmal den
Interrupt auszulösen scheint. Irgendwie tut er überhaupt nichts und ist
taub. Habe ich im Code vielleicht irgendwas vergessen? Der Master erhält
nach dem Senden der Slave-Adresse ein NOT ACK bzw eben kein ACK vom
Slave worauf sich schließen lässt dass sich dieser nicht angesprochen
fühlt. Die ersten beiden Status-LEDs und die Error-LED an meinem Master
leuchten. Am Slave tut sich nichts..
Master:
Nur mal kurz über den Empfänger-Code geschaut, grundsätzlich:
In der Interruptroutine musst Du als erstes mal die verschiedenen
Statuscodes des TWSR auswerten. Diese sind im Datasheet beschrieben.
Erkennt der Slave beispielsweise, dass seine SLA-Adresse gesendet wurde,
steht im TWSR beispielsweise 0x60.
Wenn im TWSR dann 0x80 steht, hast der µC ein Byte empfangen.
Halte Dich mal an das Datasheet, dort sind ja auch Routinen angegeben.
Ansonsten findest Du im Netz sicherlich Beispielcodes.
LG EC
Hi, danke schonmal für die Antworten.
Ich weiß dass ich in der Empfänger Interruptroutine die Statuscodes zur
weiteren Verarbeitung erstmal auswerten muss :-) Aber dazu kommt es erst
garnicht. Der Interrupt wird überhaupt nicht ausgeführt, der Slave
reagiert garnicht erst.
Habe mir auch das Beispiel hier obendrüber mal angeschaut, alles
plausibel aber helfen tuts mir leider nicht wirklich :-( Einen Fehler in
der Schaltung kann ich auch nicht wirklich entdecken. Irgendwo im
Programm ein Fehler? Ich hab leider auch kein digitales
Speicheroszilloskop.
mfg PoWl
Got it. Tja das passiert wenn man das Manual nicht von vorne bis hinten
hin wort für wort durchließt.
1
; TWI und Interrupt aktivieren
2
ldi R16, (1 << TWEN) | (1 << TWIE)
3
out TWCR, R16
Da muss noch das TWEA Bit rein damit das ACK überhaupt gesendet wird...
schwupp, schon funktioniert es :-)
Danke trotzdem für die Hilfen, ich werde mich melden wenn es wieder
probleme gibt.
mfg PoWl
Das Teil bringt mich noch zur verzweiflung. Nachdem ein erster Transfer
geklappt hat, dafür ein zweiter aber nicht habe ich mal weitere
Untersuchungen angestellt. Irgendwie ist da der Wurm drin. Entweder der
Master sendet die Stop-Condition nicht richtig raus oder der Slave
erkennt sie irgendiwe nicht?! Nach einschalten der Versorgungsspannung
drücke ich auf meinen magischen INT0 Taster. Prompt leuchten alle 4
bunten StatusLEDs am Master die mir anzeigen dass er mit seiner
senderoutine fertig ist. Am Slave jedoch nur die beiden ersten gelben
Status LEDs die mir zeigen dass die Adresse empfangen und ACK gesendet
und dass die daten empfangen und ack gesendet worden sind. Jedoch wurde
die stop condition nicht erkannt. Findet da jemand den fehler?
Master:
Leider kann ich den Post nicht mehr editieren. Mir ist aufgefallen dass
wenn ich das erste mal die Übertragung starte eine zweite nicht möglich
ist. Die Start Condition wird vom Master irgendwie nicht gesendet bzw.
das TWINT-flag wird einfach nicht gesetzt?! Wenn ich den Slave nach der
ersten Übertragung jedoch resette dann geht es wieder. Wenn ich den
Slave resette nachdem ich die zweite übertragung gestartet habe (also
einfach 2 mal hintereinander auf den taster drücken) dann läuft das
programm im master weiter und sendet die SLA + R/W. Danach geht die
Error LED an was bedeutet dass der Slave kein ACK sendet.
Ich habe das Masterprogramm mal geringfügig modifiziert.. testweise.
Egal ob ich die Stop-conidition am ende nun sende oder nicht, der slave
reagiert gleich. Er erkennt sie einfach nicht. Irgendwo ist da der Wurm
drin aber ich bin schon ganz verzweifelt.. ich finde keinen Fehler
mehr.. möglicherweise hab ich ja was übersehen, nur was :-S
mfg PoWl
tut mir leid dass ich hier soviele postings mache.. kann leider
irgendwie nicht editieren!?
Ich habe mal im slave einen zähler eingebaut der die interrupts zählt
und am PortD ausgibt.
dann habe ich mal im master die 4 schritte Start-Condition senden, SLA +
W senden, Daten senden, Stop Condition senden schrittweise
auskommentiert. Zuerst habe ich die letzten 3 auskommentiert, d.h. der
master sendet nur eine startcondition und macht garnix. Wie zu erwarten
führt der slave kein interrupt aus. Die LEDs an Port D bleiben aus.
als nächstes habe ich nur die letzten beiden schritte im master
auskommentiert, es wird jetzt also die startcondition gesendet und
SLA+W. Der Interruptzähler im Slave zeigt an Port D nun einen interrupt
an, wie zu erwarten. Am Master leuchten natürlich die ersten beiden
bunten Status-LEDs.
dann habe ich mal den letzten schritt auskommentiert. D.h. es werden
jetzt startcondition, SLA+W und das Datenbyte gesendet.
Unerwarteterweise leuchteten nun sämtliche LEDs an Port D, d.h. es
würden 255 Interrupts ausgelöst. Wieso denn so viele? Und wieso denn
genau 255? Ich nehme mal an das liegt am Master aber ich kann im code
auch keinen fehler entdecken der soviele datenbytes hintereinander
sendet. Ist meine TWI hardware kaputt oder habe ich irgendwas grob
falsch gemacht?