Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C Komm. interruptbasiert mit Assembler: Code? Erfahrungen?
Hi!
Ich habe vor, zwei Mega32s per TWI bzw. I2C interruptbasiert kommunizieren zu lassen. Der Grund ist, dass mein geplanter Roboter mehr Ein-/Ausgänge und Hardwaremodule braucht, als ein Mega32 hat.
Leider kann man eine solche Kommunikation nur schwer mit AVRStudio simmulieren, was das Debugging erschwert.
Und weil das auch ne Menge Programmierarbeit ist und ich (noch) kein Meister bin, frage ich Euch, ob Ihr wisst, wo man Programmcode dazu herbekommen kann? Bei Atmel habe ich keine Application Note gefunden, was mich verwundert, da das doch viele Leute gebrauchen können, oder etwa nicht?
Das was man sonst im Netz findet ist entweder unvollständig oder nutzt keine IRQs.
Hat jemand Erfahrungen mit derartiger Kommunikation und kann mich vor ein paar Tücken warnen?
Gruß Gock
Muss es unbedingt TWI sein oder wäre SPI nicht sinnvoller ?
Für SPI gibt es sogar ein kurzes Programmbeispiel im Datenblatt.
Auf Theaterzentrum.at war mal ein 12 Kanal Dimmerpack, dort wurde SPI zu Komunikation zwischen 3 ATMEGA 8 eingesetzt.
Die Daten wurden dort während des Nulldurchgangs Interrupts (INT 0) übertragen.
Der Code war komplett in Assembler gehalten.
Die gesamte Steuerung des Dimmerpacks lief nur in Interruptroutinen ab, das bedeutet das gesamte Hauptprogramm lautete:
MAIN:
JMP MAIN
Ob es noch eine Spiegelseite gibt kann ich Dir leider nicht sagen.
Notfalls hätte ich den Quellcode noch irgendwo in den Tiefen meiner Festplatte.
Bei Atmel gibt es Appnotes dazu!
AVR311: Using the TWI module as I2C slave
AVR315: Using the TWI module as I2C master
Ich hab schon erfolgreich nen Mega8 als Slave im Einsatz. Ist eigentlich nicht sonderlich kompliziert, man frag bei jedem TWI-Interrupt den Statuscode ab und reagiert laut der Tabelle im Datenblatt.
Für den Master benutze ich die lib von P. Fleury.
Ich werde mein Programm bald mal ins wiki packen... [allerdings in C, aber das Prinzip dürfte leichtin in ASM zu übertragen sein]
Hi, ich hab es jetzt nach endlosen Versuchen geschafft, das meine TWI-Routine läuft.
Auf die Schnelle hänge ich mal die Interupt-Routine und die Subroutine zum Einleiten der Transmission an.
WR = R16, HR = R17
Die Routine funktioniert in etwa so: Der Teilnehmer, der SUB_START_TWI_TRANSMISSION ausführt macht sich zum Master, schickt ein Byte zur Adressierung der gewünschten Daten an den Slave, und bekommt dann 8 Datenbytes + eine Checksumme zurück. Die Variable STAT_TWI kennzeichnet die möglichen Zustände von Interupt zu Interupt. Ist die Übertragung erfolgreich, bleibt der Status bei 0x10 stehen, bei Fehlern meldet sich die Routine mit 0x1D zurück.
Der abgefragte Slave merkt im Idealfall nichts davon, das er abgefragt wird, die Daten müssen also immer im Datenbereich bereitliegen.
Vielleicht kannst Du Dir ja ein paar Anregungen holen.
Ach so, ich hab es mir einfach gemacht, in dem ich nur gerade TWI-Adressen zulasse, damit das R/W Bit gleich frei ist.
greetz Rajko
@wkrug
Es sollte schon I2C sein, weil ich gerne irgendwann auch noch den einen oder anderen I2C Baustein anschließen möchte. Außerdem kann ich die ExtIRQs auch gut gebrauchen.
@uwegw
Atmel hat leider vergessen dazuzuschreiben, dass es C ist. Ich hätte es aber gerne in Assembler, dann weiß ich wenigstens, was die Dinger machen :-)
Ich Prinzip ist das nicht so kompliziert, aber wenn man keinen Riesencode haben will, dann muss man sich schon ein paar Kniffe einfallen lassen (Sprungsequenzen oder so). Und am Ende hat man einen Fehler und findet ihn nicht... Ich habe mein Programm ja auch schon weit getrieben, aber es geht bestimmt besser.
@bax
ja, ein paar Anregungen könnte ich gebrauchen. Das Prinzip ist mir auch klar, nur die Ausführung macht mir etwas Sorgen. Wolltest Du eigentlich etwas anhängen? Oder was meintest Du? Wenn Du AssemblerCode hast, aäre das sehr nett.
Danke erstmal, Gruß Gock
PS: Wenn ich es geschaft haben sollte, stell ich es auch mal ins Wiki.
Sorry bax, hab Deine Dateien nicht gesehsen, weil ich noch nicht angemeldet war... Ich sehe es mir heute abend mal an.
Gruß
@ bax
Erst mal vielen Dank für den Riesencode. Ich habe eine Weile gebraucht, um zu verstehen, wie es gemeint ist, ist ja auch nicht gerade wenig.
Zur Zeit versuche ich noch, 6 Bytes an einen Slave zu schicken, aber später will ich auch einen abfragen.
Die Idee mit der Checksumme ist gut, vielleicht werde ich sowas auch vorsehen.
Hast Du nachweislich schon mal Fehlübertragungen erlebt? Wie oft kommt sowas vor?
Wie hast Du den Code getestet? Im AVR Studio, indem Du den Slave simuliert hast?
Gruß Gock
Hi Gock,
ich hab das größtenteils direkt mit der Zielschaltung zum laufen gebracht, das ist zum einen ein Mega32, der ein kleines 128x64 Grafik-Lcd ansteuert, und zum anderen ein Mega8, der ein paar I/O's hat. Durch das LCD hatte ich die Möglichkeit, mir die interessanten Daten und Zustände direkt anzeigen zu lassen. Mit dem Studio läßt sich das TWI ja nicht wirklich simulieren.
Die Checksumme hab ich vorgesehen, weil das Projekt für mein Auto gedacht ist, und ich dort eine TWI-Verbindung zwischen dem Display-Controller in der Instrumententafel und der 'Zentrale' im Handschuhfach oder der Mittelkonsole aufbauen möchte. In dieser Umgebung könnte ich mir schon Störungen vorstellen, beim Probeaufbau auf dem Stubentisch hatte ich allerdings noch nie Probleme. Hab zur Zeit 1,5m Kabel zwischen den Teilnehmern und fahre mit 200kHz TWI-Frequenz.
Was ich im Hauptprogramm noch machen muß ist eine Überwachung, das sich der Status der Übertragung alle paar millisekunden ändert, und das die Verbindung resettet wird, wenn das mal hängen bleibt. Dann dürfte auch hot-plugging möglich sein.
greetz Rajko
@ Bax
Du hast relativ viel Code benutzt, ich werde mal versuchen, die Übermittlung bzw. den Empfang mehrerer Bytes hintereinander in einer Schleife unterzubringen. Wird aber noch einen Moment dauern. Wenn ich das schaffe und es Dich interessiert, kannst Du ja mal bescheid sagen.
Gruß Jo
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.