Hallo,
ich bin gerade dabei das TW-Interface zu programmieren, ich arbeite mit
zwei ATMEGA32. Ich bin soweit, dass vom Master die Startcondition
gesendet wird. Jetzt habe ich das Datenblatt so verstanden, dass der
Slave die Startcondition bestätigen muss. Macht er das automatisch oder
muss ich das via Software machen?
Vielen Dank im voraus
lg Torsten
Hallo,
bei TWI gibt es nur für Daten-Telegramme eine Quittierungs-Option
(Acknowledge) durch den Empfänger; Start- und Stop-Bedingungen werden
"einfach so" gesendet.
Okay, danke. Also ich bin jetzt soweit, dass die Startcondition gesendet
ist und habe (also vom Master aus) die Zieladresse gesendet. Wie kann
der Slave jetzt feststellen ob er seine Slaveadresse empfangen hat? Die
eigene Slaveadresse steht schon im Adressregister drin.
lg Torsten
Hallo,
noch zur Ergänzung: zur Überprüfung des Zustandes vom TWI-Interface ist
das TWI-Statusregister und das TWInt-Flag wichtig. Das Flag teilt eine
Änderung des Status mit, und das Statusregister liefert den Status-Code
der stattgefundenen Aktion. Entweder macht man die Abarbeitung in einer
ISR, oder man prüft das TWInt-Flag, ob es gesetzt ist, und reagiert
anhand des Statuscodes entsprechend (incl. Rücksetzen des TWInt-Flags).
Das Ganze ist recht genau im Mega32-Datenblatt beschrieben; auch einige
Beispiele sind dort zu finden (sowohl für die Master- als auch für die
Slave-Seite).
Ich habe eigentlich immer Software-I2C genommen. So richtig bin ich mit
der Hardwarelösung nie klargekommen, und da es bei mir immer nur um
ziemlich wenig traffic ging (Uhr, Poti oder ein paar Daten an ext.
EEProm), bin ich dabei geblieben. 1000fach bewährte Routinen, da hatte
ich keine Lust, stundenlang dran zu bleiben.
Gibt auch noch einige andere hier, die Probleme mit TWI hatten.
Hm... also das Statusregister lasse ich mir über fünf LED's am PortB
ausgeben, so wie sie jetzt leuchten würde das bedeuten, dass im
Statusregister eine 0x48 steht. Laut Datenblatt gibt es diesen Status
aber nicht. Hat jemand noch eine Idee?
lg Torsten
Wie sieht denn dein Programm aus?
Den slave musst du eben passend einstellen:
- passende Adresse
- twi eingeschaltet ;)
- als slave
- soll auf empfangene Bytes antworten (TWEA)
- Lösch das TWINT (falls gesetzt)
Beachte:
a) Das TWEA muss grundsätzlich eingestellt werden bevor das
Byte/Adresse übertragen wird.
b) TWINT muss immer von Hand gelöscht werden (1 reinschreiben!)
c) der ganze Bus ist blockiert (=low-pegel), solange bei irgendeinem
angeschlossenen AVR das TWINT gesetzt ist.
hth. Jörg
ps. bei Atmel gibt's dazu App. Notes inkl. Code
Es gibt zwei gängige Konventionen über den Umgang mit Adressen.
Offiziell sind das 7 Bit 00-7F und das R/W Bit wird rechts angefügt,
anderseits findet man sie oft als 8 Bit 00-FE, mit dem untersten Bit als
R/W-Bit.
Wenn du zur zweiten Fraktion zählst, dann ist 0x11 eine Leseadresse.
Von welcher Seite ist hier eigentlich die Rede? Vom Master oder vom
Slave?
Mit Zieladresse meine ich den Slave. Ich habe das Datenblatt so
verstanden, dass ich in den oberen sieben Bits die Adresse festlege und
das unterste Bit (also das Nullte Bit) gibt an ob ich an den Slave
senden will ( = 1) oder ob ich vom Slave lesen will ( = 0). Ist das
falsch?
lg Torsten
Oops, danke - ohne dieses Forum und ohne eure Hilfe wäre ich echt
aufgeschmissen. Dann versuche ich mal den nächsten Schritt, vielen Dank
:)
lg Torsten
Also ich muss doch noch einmal nachfragen. Aus den Quelltexten im
Internet werde ich nicht schlau. Ich habe mir zwischenzeitlich einige
Funktionen gebaut, die mir einen blinkenden Fehlercode anzeigen. So kann
ich Schritt für Schritt vorgehen und merke genau an welche Stelle ich
nicht weiter komme. Die Zieladresse ist mit dem "Schreibbit" beim Slave
angekommen, ich habe versucht an eine andere Adresse zu senden - da
kommt dann eine Fehlermeldung. Das bedeutet, dass der richtige Slave
definitiv geantwortet hat.
Wenn ich jetzt das erste Datenbyte übertrage kommt allerdings keine
positive Meldung vom Slave. Ich würde ja vermuten, dass ich das
empfangene Datenbyte aus dem Datenregister lesen muss. Leider wird der
TWI-Interrupt (0x20) im Slave aber nicht ausgelöst, also weiß meine
Software nicht wann etwas angekommen ist. Ich Controlregister sind die
Bits TWEA, TWEN und TWIE gesetzt. Kann mir da jemand noch einen Tipp
geben was ich noch falsch gemacht haben könnte?
lg Torsten
Wird nach Abarbeiten der TWI-Bearbeitungsroutine auch das TWInt-Bit im
Control-Register durch Schreiben einer 1 zurückgesetzt? Sonst hängt der
Slave fest und kann nichts mehr annehmen, bis das Bit gelöscht wird.
Die gesendete Adresse zum Schreiben ist korrekt? (LSB der Adresse = 0)?
Ich würde ja gerne das Interruptflag zurück setzen, aber es passiert ja
im Slave nichts. Hier ist mal die Main-Routine :
Main:
lds Value, 0x3b ; PortA lesen
ldi Math, 0x01
eor Value, Math
sts 0x3b, Value ; PortA0 toggeln
lds Value, 0x21
sbrc Value, 0x01
rcall twowire_Receive_Function
rjmp Main
In den ersten vier Zeilen lasse ich lediglich eine LED blinken, damit
ich eine Kontrolle habe ob der Prozessor auch in der Mainroutine
arbeitet. In den drei nächsten Zeilen prüfe ich den Interrupt des TWI,
wenn er gesetzt ist soll das Programm verzweigen - macht es aber nicht.
Ich glaube ich mache das was grundlegendes falsch.
lg Torsten