Hallo! Hier ein funktionierendes Beispiel für einen I2C-Slave mit Hilfe des USIs. Läuft auf attiny26 und attiny2313. Vielleicht interessiert es ja jemanden... Gruß Axel Gartner PS: Siehe auch: http://www.mikrocontroller.net/articles/USI
SCL Overflowfehler korrigiert. Axel Gartner
Gast
#287908
Hallo Alex! Schön das du die so viel mühe gemacht hast. Das gleiche was du hier gepostet hast, bschäftigt mich schon ein paar Wochen. Also vielen Dank! Jetzt wollte ich das Programm mal testen und compilieren . Benutze das AVR Studio.....mit GCC! Nun meine Frage: Du linkst in den Programm zu keiner header datei oder ähnliches....! Bei kompilieren bekomme ich fehler, ../main2.c:63: error: `PORT_USI_SCL' undeclared (first use in this function) und noch viele andere....! ´Falls du doch auf andere datein links......wäre es super wenn du diese zur verfügung stellen könntest. DANK IM VORRAUS Dear Benno!
Gast
#287909
Hallo Benno!
Du must in deinem Makefile den MC-Typ definieren
z.B.: _at90tiny26_
MCU = attiny26
F_CPU = 8000000UL
CDEFS = -DF_CPU=$(F_CPU) -D__$(MCU)__
Die Defines sind typabhängig. forlgendes steht ganz am Beginn:
// Device dependant defines
#if defined(_at90tiny26_) | defined(_attiny26_)
#define PORT_USI_SCL PORTB2
#endif
#if defined(_at90Tiny2313_) | defined(_attiny2313_)
#define PORT_USI_SCL PORTB7
#endif
Gruß
Axel
Gast
#287910
@Axel, wenn man bestimmte Defines verlang, gehört es zum guten Ton, bei fehlen dieser Defines mit #error einen entsprechenden Hinweis auszugeben. Nach Monaten oder Jahren weißt Du sonst selbst nicht mehr, welche Defines für welches Projekt mal benötigt wurden. #if !defined(MODEL) #error Modell nicht definiert! #endif Peter
Gast
#287911
Wunderbar das hat geklappt....! Wenn ich jetzt mit einem Master folgendes sende START ADRESSE (0x20) R/W dann sollte doch der Slave den BUS auf LOW ziehen richtig?
Der slave zieht einmal beim Erkennen der Startbedingung und einmal beim 16-ten SCL Flankenwechsel die SCL Leitung runter. Nachdem der jeweilige Interrupt abgearbeitet wurde, wird die SCL wieder freigegeben. Axel
Gast
#287913
Hallo zusammen, cih habe versucht, den Code auf meinem ATTiny26 zum Laufen zu bekommen. Die Start-Condition erkennt der Controller auch noch und springt auch in die ISR, arbeitet diese ab und springt wieder zurück. Allerdings bleiben dann SCL und SDA low, was ja eigentlich nicht sein dürfte, oder? PullUps sind überall drin. Als I2C-Master verwende ich gerade einen RS232/I2C-Adapter der Firma IB-Hoch. Kann es ein, dass ich hier einfach keinen Takt zur Verfügung habe und den selbst vom Slave aus generieren sollte? Denn in diesem Falle kann es ja durch die Einstellung USI_CONTROL |= (1<<USIWM1) | (1<<USIWM0) | (1<<USICS1); (externer Clock) gar nicht gehen. Oder verstehe ich da was total falsch? Wer hilft mir mit dieser Geschichte auf die Sprünge, denn ich sehe gerade bei mir einfach den Fehler nicht....! Vielen Dank mal soweit! Dennis
Hi zusammen, ich bin im Moment auch daran, einen ATtiny als I2C-Slave zu programmieren, allerdings einen ATtiny45. Ich habe die defines geändert, sodass die PINS und PORTS stimmen. Allerdings weiss ich nicht ganz, wie ich das jetzt genau mit meinem Programm verbinden kann. Ich möchte, wenn die Verbindung hergestellt ist, irgendwelche Daten, die in einer Variabel gespeichert sind, zurücksenden. Wo genau kann ich so etwas denn in den Code einfügen? Herzlichen Dank schon im Voraus, Benedikt K.
Gast
#287915
Hallo, habe versuch den Slave auf Tiny45 zu portieren (nur Pins verändert). Wenn ISR ausgelöst wird, sollte eine LED angehen, aber nicht mal START Condition wird erkannt :-o Nebenbei benutze ich auch die PWMs, ist aber wohl egal. Die ersten Zeilen habe ich so geändert: /* Device dependant defines */ #define DDR_USI DDRB #define PORT_USI PORTB #define PIN_USI PINB #define PORT_USI_SDA PORTB0 #define PORT_USI_SCL PORTB2 soll ja richtig sein, oder? Jetzt schlage ich mich den ganzen Tag damit rum und sehe den Wald vor lauter Bäumen nicht und bin kurz dran den ganzen Kram in Software zu implementieren. Weis jemand Rat? Hat jemand vielleicht auch Probleme damit gehabt und es auch nicht ging? Als Master habe ich AVR Mega 8, auf dem Oszi ist Start Condition wunderbar zusehen und die Implementierund des Masters funktioniert mit anderen Sachen... Mh... Help Gruß Kest
Hallo, ich kann dir leider nicht viel Hoffnung machen. Ich hab das auch schon verzweifelt versucht. Evtl. hilft dir dieser http://www.mikrocontroller.net/forum/read-4-271460.html oder dieser http://www.mikrocontroller.net/forum/read-1-239761.html Thread. Gruß Michael
Gast
#287917
Vielleicht nützt das ja jemandem. Ich hatte das mal geschrieben und getestet (auf Tiny2313), es ist aber nicht produktiv im Einsatz, mag also Macken haben. Orientiert sich auch an Atmels AN, arbeitet aber Message-orientiert.
Gast
#287918
Hallo ! Beschäftige mich gerade mit dem Code von Axel Gartner ... versuche das für codvision umzusetzen meine frage ist nach dem die Startbedingung erkannt wurde und erfolgreich das Adressbyte inklusive R oder W Bit eingelesen wurde, muß doch der slave generell das acknow.Bit setzen oder??? d.h. SDA als Ausgang und auf low ziehen. oder langt es den Pin nur als Ausgang zu schalten? DDR_USI |= (1<<PORT_USI_SDA); USI_STATUS = 0x0e;// reload counter for ACK, (SCL) high and back low bzw. suche die stelle an der das Acknowlege (SDA->Low) gesetzt wird. Vielleicht kann mir jemand einen Tip geben oder sagen ob ich falsch liege! Vielen dank!
Gast
#817373
Hallo, ist zwar schon ein älterer Beitrag, aber für mich doch sehr aktuell :) Ich beabsichtige gerade die Umsetzung bei einem Tiny261, dass das USI zum I2C-Slave wird. Sendet halt keine ACK. Die Interruptroutine vom Codevision-Wizard will auch net :) Wurde das Problem schon mal gelöst für einen Tiny. Wäre dankbar für Tipps und natürlich auch nen Bsp.-Code :) Grüße
In der Tat. Alter Thread. Aber manche Threads wollen einfach nicht sterben ... :) Also. Dank A.K.'s Code habe ich jetzt mal was gesehen auf meinem I2C-Bus. Ich verwende einen ATtiny45 als Slave und den I2C-Tester aus dem "ATM18-Projekt" als Master. Wenn ich jetzt mit dem (famosen) I2C-Sniff von Peda auf dem Bus lausche, sehe ich, dass Bits verloren gehen, wenn der Slave sendet. Ein anderer Slave (mit Hardware-I2C) geht problemlos, das vom Master gesendete kommt auch an. Hat jemand einen Tip? Mit dem DSO nachgemessen fällt mir auf, dass die Datenbits beim "Master-Write" etwas nach den Clock-Bits enden (was mir ansich richtig erscheint). Beim "Master-Read" (was ja wie erwähnt nicht ganz klappt) enden sie aber schon in der frühen fallenden Flanke vom Clock-Bit. Könnten meine Probleme damit etwas zu tun haben? Ist jemand hier weiter? Und gibt es eine funktionierende CodeVision-Portierung? Grüße, Christoph
Hallo... hier findet ihr eine ausführlice Bibliothek für ein I2C / TWI Interface mit dem AVR USI. http://www.jtronics.de/elektronik-avr/lib-i2ctwi-mit-usi-interface.html Die Biblitothek ermöglicht eine I2C/TWI Kommunikation über das USI Interface von Atmel. Der verwendete Controller wird dabei als Slave in dem Bussystem verwendet. Neben Controllern der Reihe ATTiny, wie dem ATTiny2313, werden auch eine Reihe von anderen Controllern mit USI Interface unterstützt. Die Bibliothek ist so programmiert, dass der Slave wie ein I2C-Speicher (I2C-Epprom) funktioniert. unterstützt werden bisher folgende Controller: ATtiny2313, ATtiny25, ATtiny45, ATtiny85, ATtiny26, ATtiny261, ATtiny461, ATtiny861, ATmega165, ATmega325, ATmega3250, ATmega645, ATmega6450, ATmega329, ATmega3290, ATmega169 Grüße Martin http://www.jtronics.de Info... ich habe die datei nicht angehängt, da sie in Zunkunft noch weiter von mir ausgbeaut wird. Damit jeder immer die neuste Version bekommt sollte er die Lib von meiner Seite laden.
Gast
#1760296
Genau so was hab ich gesucht! Und im gegensatz zu allen anderen Codeschnipseln funktionierte die Bibliothek gleich beim ersten Versuch. Vielen Dank der Richard
Gast
#1785434
Cool genau das hab ich gesucht. danke
Hallo, Ich hoffe das hier jemand ein offenes Ohr für mich hat. Ich hab mir auch die Lib von Martin gezogen, doch ich kann auf keine Weise den Attiny ansprechen. Der Test des Master-Codes mit einem externen EEPROM funktioniert wunderbar, doch wenn ich den Attiny verwende, dann bleibt der Master hängen. Vllt. könntet ihr mal über den Code schauen, ich hab wahrscheinlich Tomaten auf den Augen, sitz auch schon seit 9 an der ganzen sache :( MfG
hier das allgemeine Beispiel von mir, steht auch auf der jtronics.de
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
also 1.nimmst du überall die delays raus, so was macht man nicht, da der controller in der zeit nur warten und die anderen aufgaben nicht machen kann. 2. schreib die Adressen und Befehle bei TWI/I2C lieber binär, ist viel übersichtlicher. Du erkennst eher Muster und meist hat jede Bit nummer bei einem Befehl ihre Aufgabe. 3.so sollte das aussehen
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
Moin :D @ Martin Danke das du dir die Sachen mal angesehen hast, aber selbst mit deinem Codeschnipsel funktioniert nix, da bleibt er mir bei Slaveadresse senden hängen und ich bin mir eigentlich fast sicher das es am Slave liegt. Kannst du dir das mal anschauen ?! Aber so viel kann man da ja ne falsch machen, wahrscheinlich bin ich einfach nur zu doof dazu. MfG
So habs grad nochmal aufgebaut atmega8 mit attiny2313 hab es erst mit dem internen quarz des attiny getestet, geht nicht. hab einen quarz dran gemacht ... geht. Der internen quarz der controller ist also zu ungenau. Ist nix neues, steht ja schon ganz oft im forum. Die Programme poste ich dir dann noch. gruß martin
stop zurück, mit internem 8Mhz geht es auch... also jetzt gehts! Warum es vorher nicht ging, keine ahnung. hier die datei für den ATtiny2313 Slave bei 8Mhz
Gast
#2011540
Hallo, ich bekomme folgenden Fehler bei Verwendung von avr-gcc und attiny[248]5:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
USICIF sollte doch definiert sein. BTW: bei attiny26 funktioniert das Compilieren ...
Unterstützt werden bisher folgende Controller: ATtiny2313, ATtiny25, ATtiny45, ATtiny85, ATtiny26, ATtiny261, ATtiny461, ATtiny861, ATmega165, ATmega325, ATmega3250, ATmega645, ATmega6450, ATmega329, ATmega3290, ATmega169 deinen Controller musst du da mal noch selber implementieren ... stell dann bitte das neue file hier hoch.
Hier noch eine Version mit überarbeiteten Kommentaren komplett in Englisch... Vielen Dank nochmal an Markus für das überarbeiten Grüße Martin
Gast
#2011651
Hallo, vielen Dank für die super schnelle Antwort. Martin J. schrieb: > Unterstützt werden bisher folgende Controller: > > ... ATtiny25, ATtiny45, ATtiny85 Ich möchte das für attiny45 ja nutzen. Verstehe ich hier etwas falsch ?
mhm könnte ein kleiner Fehler sein... in der usiTwiSlave.c musst du folgendes Ändern
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
so sollte dann funktionieren... testen kann ich das aber net , hab grad kein controller dafür hier. sag Bescheid, ob es geht. Viel Erfolg
Gast
#2011704
Danke :-) Compilieren geht schon mal ...
fein fein
Gast
#2021323
Jepp, das sollte in den Quellen dringend korrigiert werden! Ich bin beim ATtiny45 eben auch auf den USICIF-Fehler gestoßen... :-/ Gruß, Volker
hier die korrigierte Version
kann man hiermit auch einen LM75 Temp. Sensor auslesen? Oder geht das nur als Master? Meine Hardware soll in etwa so aussehen: LM75-->usi Attiny slave-->twi atmega master
Deine Struktur geht so nicht. Der LM75 wird auch über I2C/TWI angesprochen, von daher kannst du den auch gleich mit dem Mater auslesen. Der Attiny hat außerdem nur einen Hardware TWI, bzw. nur ein USI Interface. Deine Skizze ist somit nur mit einem Software TWI umsetzbar. Grüße Martin
Martin J. schrieb: > hier die korrigierte Version Hallo Martin, ich versuche momentan die Tiny45-Version zum laufen zu bekommen. MASTER: ATMega1284P SLAVES: PCF8563 RTC, DS2482-100 1-Wire Master, ATTiny45 (in EEPROM Version) als DCF77 Controller ATTiny45 -> 1MHz interner Takt aus 8MHz RC-Oszillator Der Tiny funktioniert als DCF77 Slave anstandslos, synchronisiert ohne Probleme und die Daten stimmen. Die Uhr und auch der 1Wire Bus funktionieren mit den Treibern für den ATMega1284 bereits seit mehr als einem Jahr im Dauerbetrieb fehlerfrei. Sobald der ATTiny mit dabei ist, gibt es sporadische Aussetzer, und die RTC und der 1Wire Master sind nicht mehr ansprechbar. Der ATTiny45 meldet sich garnicht, bzw. erkennt seine Adresse nicht (mit Debugger geprüft). Die empfangenen Werte im USIDR / USIBR entsprechen nicht den übertragenen Adresswerten. Die empfangenen Adresswerte kommen im System nicht vor, gehören also definitiv auch nicht zu den anderen Slaves. Nach Ausfall der Kommunikation wird per WDT-Reset die Kommunikation wieder hergestellt, aber der Zyklus beginnt irgendwannn wieder, und neben dem ATTiny funktionieren die anderen Slaves auch nicht mehr. FRAGE: hast Du (oder ein anderer im Forum) einen ATTiny45 schon mit anderen (echten Hardware)Slaves gemeinsam betrieben? Gruß
Gast
#2410152
Hallo. klingt interessant was du da machst. Leider kann ich dir grad nicht helfen. Ich habe für ein Messsystem 2 Attiny 2313, 2 Atmega644 und 2 Maxim ADCs an einem I2C Bus Betrieben. Die Attinys arbeiteten mit der hier vorliegenden Library. Bisher konnte ich keine Fehler bzw. Probleme finden. Der Aufbau läuft jetzt schon seit Jahren ind verschiedenen Systemen zuverlässig. Momentan habe ich keinen ATTiny45 zu verfügung, sonst hätte ich es auch mal getestet. VIelleicht kann dir daher jemand anderes helfen. Grüße Martin
Gast
#2410157
Die neuste version hast du aber? siehe Beiträge weiter oben. eine noch neuere Version als die oben findest du hier: http://www.jtronics.de/avr-projekte/library-i2c/twi-slave-mit-usi-avr
martin schrieb: > Die neuste version hast du aber? > siehe Beiträge weiter oben. > > eine noch neuere Version als die oben findest du hier: > http://www.jtronics.de/avr-projekte/library-i2c/twi-slave-mit-usi-avr Ja, ich nutze die neueste Library. Ich habe auch bereits die ATTiny Clock auf 8 MHz gesetzt, um die schnellste IRQ-Verarbeitung zu ermöglichen. Außerdem nutze ich das USIBR anstatt USIDR um keine Zeitprobleme bei 400kHz Masterclock zu bekommen. Bisher hat nichts geholfen. Seltsam, daß der ATTiny die Kommunikation der anderen Slaves stört ..... Wenn der Fall gelöst ist, melde ich mich wieder! Grüße
Gast
#2410184
Das wäre super, dann könnte im Fall eines Fehlers die Lib angepasst werden oder anderen mit gleichem Problem hätten dann schnell eine Lösung. noch viel erfolg.
martin schrieb: > .... viel erfolg Problem gelöst! Der ATTiny kann trotz 8 MHz Taktfrequenz (ohne Teiler!) offensichtlich keine 400kHz I2C Clock vertragen. Ich werde mir mal die vom C-Compiler generierten Interrupt-Routinen anschauen. Im USIDR stehende Daten werden wahrscheinlich bereits geshiftet, bevor die IRQ-Routine die Daten einlesen kann. Allerdings bringt die Nutzung des USIBR keine Verbesserung! Na mal sehen ... Da es in meine Anwendung kein Problem ist, die I2C-Clock umzuschalten kann ich ersteinmal weiterarbeiten. Weitere Infos folgen. Gruß
Gast
#2411182
interessant. meine erfahrungen waren, dass du bei 16MHz CLock den I2C bis knapp über 900Khz takten kannst, was aber nicht zu empfehlen ist. Der Bus läuft aber sicher bis zu 800 Khz. grüße martin
Der Link http://www.jtronics.de/elektronik-avr/lib-i2ctwi-mit-usi-interface.html liefert mir eine eigenartige Fehlermeldung mit SeaMonkey 2.6: >Umleitungsschleife >Limit für Umleitungen dieser URL überschritten. Die angeforderte Seite konnte nicht geladen werden. Dies könnte von blockierten Cookies verursacht werden. >Der Verbindungsversuch zur aufgerufenen Adresse wurde abgebrochen. Die >aufgerufene Website leitet die Anfrage so um, dass sie nie beendet werden >kann. >Haben Sie Cookies, die von dieser Website benötigt werden, deaktiviert oder >blockiert? >HINWEIS: Falls das Akzeptieren von Cookies die Probleme mit der aufgerufenen Adresse nicht behebt, handelt es sich vermutlich um eine Fehlkonfiguration des Servers und nicht um einen Fehler Ihres Computers. Habe allerdings keine Cookies blockiert. Mein Browser akzeptiert alle Cookies für diese Session.
Hallo http://www.jtronics.de/avr-projekte.html?start=7 Der Link sollte funktionieren. Ich habe ein anderes Problem: Der Master ist mittels Hardware TWI auf einem Mega8 realisiert. Ich schreibe ein Byte auf den controller, und möchte danach die Übertragung beenden. Das was passiert ist leider, das der ATTiny 24 mit seiner USI-Schnittstelle den Bus blockiert, in dem er die SDA Leitung auf masse behält. Meine eigene implementierung mit read_nack am slave funktioniert leider nicht. der Master läuft mit 8MHz, ebenso der Slave (tiny) Die gleiche Sache mit Hardware-TWI programmiert läuft einwandfrei. Ich habe auch so das gefühl, das USI TWI ein deutlich größerer Software-Aufwand ist als Software TWI Auch normale i2c eeproms funktionieren problemlos
Nachtrag: Ich hab es hinbekommen. Ganz dummer Fehler, ich habe eine Code-Zeile auskommentiert gehabt, und diese Codezeile hätte nicht auskommentiert werden dürfen.
Hat jemand den Code schon mal für einen ATMega8 umgebaut? geht das oder spricht technisch was dagegen? genügt es folgende Ergänzung zu machen?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
hat doch sicher schon mal einer probiert oder?
Gast
#2941831
hallo Martin, ich habe mir die lib bei http://www.jtronics.de runtergeladen. Das Problem was ich habe/hatte das ein I2C keinen richtigen ACK ausgeführt hat bzw. den SCL nicht verzögert hat bis der IRQ dran ist. Bei meiner Schaltung wird viel mit IRQ gemacht, darum ist nicht immer zeit sofort auf den IRQ zu reagieren. Die Lib macht das im prinzip richtig (es werden die richtigen Modes verwendet die auch ein SCL-hold auslösen. Das können sie aber nur wenn die entsprechenden Bits auch low sind. Laut Doku wir die SDA nur dann low gesetzt wenn diese auch im Port Low ist. Durch das setzen des DDR's wird nur der Ausgang duchgeschaltet und das Portbit an den Ausgang gelegt (attiny x4). Damit das Funktioniert habe ich folgendes eingefügt:
1 | |
2 | |
3 | |
4 | |
geändert zu
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
und folgendes:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
geändert zu:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
bei mir funktioniert jetzt sowohl der ACK als auch die SCL-Verzögerung. bye woodym
Gast
#2942765
Hallo. kannst du noch die Änderung als Datei hochstellen und vielleicht dem Autor Bescheid geben, damit bei anderen nicht das gleiche passiert. Grüße Tobi
Gast
#2944862
hallo, nach vielem Testen muß ich meine Änderungen wieder revidieren. Bevor ich die Änderungen gemacht hatte, gab es kein ACK. Nach den Änderungen war das dann perfekt. Weil ich noch weitere Probleme versuche zu finden, habe ich die Änderungen wieder rückgängig gemacht. Und siehe da, jetzt geht es auch ohne diese Änderungen. Das sind dann immer Situationen die einen verzweifeln lassen. Was nun? Muß das nun oder nicht? Noch habe ich das Prob das ab 200kHz die Daten nicht immer sauber ankommen. Wobei es scheinbar kein Prob mit der geschwindigkeit zu sein scheint, viel mehr mit dem Abstand zwischen den Protokollen. Jetzt versuch ich erst mal zu verifizieren ob immer dann wenn es nicht geht vielleicht ein andere IRQ ansteht. Wenn die Lib richtig funktioniert, dann dürfte das jedoch keine Rolle spielen weil der SCL beim Start und zum ACK so lange runter gehalten wird. Was seltsam ist, das nach einem Start sofort die Clocks kommen. ein zweites Telegramm danach hat dann die verzögerung die ich aufgrund des IRQ's erwarten würde. bye woodym
Gast
#2946318
Ja das sind die schönsten Fehler. Ich bin schon gespannt was nun als Fazit da raus kommt. Vor kurzem hatte ich auch so ein Problem mit dem I2C des Xmegas. Nach ewigem Suchen hat es am Ende dann endlich funktioniert. Der Fehler lag aber am Slave, dieser war konnte einfach nicht bei dem Tempo mithalten. Viel Erfolg noch bei deiner Suche
Gast
#2947866
hallo tobi, mein fazit... es funktioniert auch ihne die änderungen. Warum es vorher nur mit den Änderungen funktionierte, kann ich nicht sagen. Was verblüffend ist, das diesr kleine attiny doch so flott ist. Mein Problem hatte nichts mit der Geschwindigkeit zu tun sondern mit einem Positionsbuffer. Kurz umrissen was es werden soll/ist: Ein kleines Board mit l293 (ja ich weiß, sehr betagt aber dafür sehr unkomplizert) das einen kleinen Stepper antreiben soll. Mit auf dem Board ein kleiner Attiny der im I2c-Mode positionen für den Stepper entgegen nehmen kann oder im 2. mode einfach mit CLK und DIR angesprochen werden kann. Da das ja nicht abendfüllend ist, kann per Software auch der Stepper im Microschritt betrieben werden (4Step, 8Step und 16Step). Und mit dieser Option (und der damit verbundenen Rampenansteuerung) ist der Attiny schon etwas ausgelastet. Aber genau das richtige um kleine Stepper ohne viel aufwand von Außen ansteuern zu können. Nun zum Fehler den ich hatte: wenn eine Position per I2C übertragen wurde und der Stepper diese angefahren hat, sollte man eine weitere Position schon übermitteln können damit es zu keinem 'Stottern' kommt. Der Fehler war nun das das Locking zwischen IRQ-I2C Positionsübermittung und Positionsabarbeitung nicht geklappt hatte. Das habe ich schlicht weg umgangen indem ich einen Ringbuffer mit 32 Positionen eingebaut habe der einfach zu Locken ist (mit cli/sei). Der I2C schreibt im IRQ rein und die Positionierung holt zwischen Cli und Sei aus dem Buffer raus. Jetzt muß nur noch das Optionale 'Fahre beim einschaltren die Homeposition an) eingebaut werden und dann geht das ;-) bye woodym
Hallo zusammen, habe auf einem ATTiny2313 die USI-TWI Slave http://www.jtronics.de/avr-projekte/library-i2c-twi-slave-usi.html zum Laufen gebracht. Soweit - sogut! Hat schön funktioniert, kann den 2313 über Raspberry PI wunderbar ansteuern und auch abfragen. Der 2313 ist bei mit 8 Mhz intern getaktet - kein CKDIV8 gesetzt. Wenn ich nun zusätzlich den Timer0 im CTC Modus aktiviere, kann ich vom Raspberri Pi nicht mehr den Slave ansprechen. Irgendetwas im Timing scheint sich auf dem I2C Bus zu verändern. Dabei arbeit in die Timer0 - Interrupt Routine (8bit) nur noch den Befehl "uint8_t Zaehler++" ab. Nun meine Frage zur Theorie: Eigentlich dachte ich, dass die Timer (bis auf den Interrupt) keine Prozessor Zeit beanspruchen. In der Interrupt Routine steht ja auch nur ein minimalistischer Befehl. Der Interrupt und dieser Befehl können doch nicht so zeitkritisch sein ??? Kann mich da mal bitte ein Wissender aufklären, in welchen Konflikt ich reinlaufe, bzw. wie ich die Thematik in den Griff kriege? Sind TWI-Slave Impelementierungen auf einem Atmel so sensibel ? Muss ich die Interrupts gegeneinander verriegeln, oder macht der Prozessor dies eigenständig? Danke im voraus!
Hallo, Bitte hänge dein gesamtes Programm noch an. So ist das nur Raten..
Uwe S. schrieb: > Hallo, > > Bitte hänge dein gesamtes Programm noch an. > So ist das nur Raten.. Also, dann mal das Programm: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >> //###################################################################### ######## //USI TWI Slave driver - ATTiny2313 //Fuses: Ext FF; Hi DF; Lo 64 #include <stdlib.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> //################################################################## USI-TWI-I2C #include "usiTwiSlave.h" #define SLAVE_ADDR_ATTINY 0x22 #ifndef F_CPU #define F_CPU 8000000UL #endif uint8_t Farbe; uint8_t PWM; uint8_t PWM2_Wert; uint8_t PWM3_Wert; uint8_t PWM4_Wert; int main(void) { //################################################################## DDRD |= (1 << PD2); DDRD |= (1 << PD3); DDRD |= (1 << PD4); PORTD &= ~(1 << PIN2); PORTD &= ~(1 << PIN3); PORTD &= ~(1 << PIN4); // Timer 0 konfigurieren TCCR0A = (1<<WGM01); // CTC Modus TCCR0B |= (1<<CS00); // No Prescaler OCR0A = 55; TIMSK |= (1<<OCIE0A); sei(); // Global Interrupts aktivieren //################################################################# Main routine cli(); // Disable interrupts usiTwiSlaveInit(SLAVE_ADDR_ATTINY); // TWI slave init sei(); // Re-enable interrupts while(1) { Farbe = rxbuffer[0]; PWM2_Wert = rxbuffer[1]; PWM3_Wert = rxbuffer[2]; PWM4_Wert = rxbuffer[3]; txbuffer[0]= Farbe; txbuffer[1] = PWM2_Wert; txbuffer[2] = PWM3_Wert; txbuffer[3] = PWM4_Wert; if (PWM >= PWM2_Wert) { PORTD &= ~(1 << PIN2); } else { PORTD |= (1 << PIN2); } if (PWM >= PWM3_Wert) { PORTD &= ~(1 << PIN3); } else { PORTD |= (1 << PIN3); } if (PWM >= PWM4_Wert) { PORTD &= ~(1 << PIN4); } else { PORTD |= (1 << PIN4); } } ISR (TIMER0_COMPA_vect) { PWM ++; } <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< <<< Die entsprechenden ISR Slave Routinen sind bekannt http://www.jtronics.de/avr-projekte/library-i2c-twi-slave-usi.html Danke im voraus
Hallo Hendrik, 55 (DEZ) im Timer0 CompareRegister und Vorteiler 1:1 bedeutet: alle 6,8 us einen Interrupt (1/8MHz * 55). In der IRQ-Routine passiert ja noch (etwas) mehr als nur die Addition. Der Interrupt hat eine höhere Priorität als die USI IRQ's, so dass für das sensible Timing in der ACK/NAK Phase eventuell Probleme enstehen können. Soweit ich mich erinnere werden in der USI-Lib die IRQ Routinen nicht als kritische Bereiche (CLI;SEI) höher priorisiert. Teste das doch mal mit 255 = 31 us oder einfach mit einem höheren Vorteiler. Oder sperre die T0 IRQ's zum Test innerhalb der USI Interruptroutinen. Gruß
Hallo Reiner, habe mal den Gegentest gemacht: 1. Teiler auf 1024 2. OCR0A auf 250 3. Alle Abfragen in der Main Routine auskommentiert 4. Timer ISRs in den USI ISR Routinen gesperrt!!! NO! geht definitiv nicht. Gegentest ohne Timer ISR: Funzt! Ich habe folgende Beobachtungen gemacht (mit Logicport) Das ganze käuft unter 3,3 Volt (stabilisiert). Verändere ich den Trigger Level im LogicPort von 0,5 Volt auf 1,2 Volt, liegen die interpretierten Adressen (im LogicPort) schon mal daneben (anstelle x21 wird x42 interpretiert). Das stellt für mich die I2C Schnittstelle des Raspberry PI mal grundsätzlich hinsichtlich Robustheit (Flankensteilheit ?) in Frage - Linux ist ja auch kein Echtzeitsystem - haben mir ja schon viele gesagt! Ausserdem scheint mir die USI-Slave Implementierung bei 8Mhz in einem 2313 ebenfalls nicht so robust - oder positiv gesagt, filigran zu sein. Habe noch einmal den Gegentest ohne Timer ISR gemacht - funzt. Das Oszilloskop zeigt mir als Zeitdifferenz zwischen ACK und NAK ca. 3 -4 usec an. Das ist natürlich bedenklich wenig, wennn Interrupts irgendeine Reaktion verhindern sollten. Nun ist ja ein ATTiny2313 ja auch nicht ein "Präzsionsinstrument..." Schade um die bisher investierte Zeit. Einen letzten Versuch werde ich demnächts noch machen, indem ich einen externen Quarz mit 16 Mhz anschliesse. Mal schaun, was passiert. Gerüchteweise soll ja der interne weniger stabil sein - und doppelte Taktfrquenz hilft vielleicht. Ansonsten werde ich (sollte kein systematischer Fehler vorliegen) wohl auf asynchrone Kommunikation umsteigen. Danke im voraus (falls jemanden noch etwas einfallen sollte)
Hendrik L. schrieb: > Die entsprechenden ISR Slave Routinen sind bekannt Nein. Es hat keiner Lust, Deinen Code zusammen suchen zu müssen. Weißt Du nicht, was ein "Dateianhang" ist und wie man ein Zip aus allen nötigen *.c, *.h erzeugt? Peter
Gast
#2975620
Hallo Hendrik, Du wirst ein Timing-Problem haben. Wenn die Timer-ISR alle 55 Takte aufgerufen wird, dann bleibt dem Programm keine Zeit noch andere Dinge zu tun. Schau Dir mal das Assembler-Listing der ISR an. Selbst wenn die Routine so klitzeklein aussieht, benötigt sie vermutlich so an die 40-50 Takte für alle die push und pop Aktionen. mögliche Abhilfe: 1. Maximalen CPU-Takt (20MHz) 2. ISR in Assembler schreiben 3. PWM-Takt reduzieren Michael S.
Hallo Hendrik, beim RasPI ist die Hardware I2C Schnittstelle schon o.k. ! Ich habe die mit verschiedenen Slaves ohne Probleme im Betrieb. Es liegt wohl eher am ATtiny. Die USI-Implementation macht bei mir bis 100 kHz keine Probleme, danach treten sporadisch auf dem I2C-Bus Probleme auf (andere Slaves 'hängen' und blockieren den BUS), was auf Probleme mit dem USI Timing deuten. Ist halt nur eine Notlösung. Bei anderen ATMEL Typen mit Hardware I2C habe ich noch nie irgendwelche Probleme bis 400 kHz gesehen! Es gibt allerdings auch 14/20 Pin MCUs welche bis zu 1 MHz Clock als Slave vertragen ;-) (mit 8 MHz interner Clock) Dazu gibts dann noch frei einstellbare IRQ Prioritäten! Du solltest Dir eine MCU passend zur Aufgabe suchen! Gruß
Reiner Geiger schrieb: > das sensible Timing in der ACK/NAK Phase eventuell Probleme enstehen > können. Nein. Beim I2C ist nichts sensibel, alle Takte können beliebig lang sein. Der I2C synchronisiert sich immer auf den langsamsten Teilnehmer. Das ist ein riesen Vorteil gegenüber SPI, es können keine Daten verloren gehen. Natürlich muß der Slave das Clock Stretching einschalten und der Master zum I2C-Standard konform sein, d.h. das SCL abfragen, bis es wieder high ist. Genau deshalb ist nämlich auch SCL open-drain und nicht nur SDA. Peter
Gast
#2975654
Hallo Reiner Geiger, das Timing (bezogen auf den TWI-Takt) ist - im Gegensatz zur Seriellen Schnittstelle - bei TWI völlig unkritisch: Der SCL-Takt bzw. genaugenommen der Flankenwechsel dirigiert das Konzert. Das Timing (bezogen auf den Takt der CPU) ist das Problem. Wenn der CPU nicht genügend Takte zur Abarbeitung ihres Jobs eingeräumt werden (und dann womöglich gelegentlich noch ein Timer seine Aufmerksamkeit fordert), dann kommt das System natürlich ins Humpeln. Die USI-TWI-Routinen sind relativ lang, entsprechend lang ist auch die Dauer der Bearbeitung - umsolänger, je niedriger der CPU-Takt. Michael S.
Hallo Peter, stimmt genau! Leider wird bei der USI Implementation von I2C einiges mit Software erledigt; das funktioniert eben nur mit passenden Kombinationen von I2C Takt und MCU-Takt. Das gleiche Problem findet man ebenfalls wenn durch Leitungskapazitäten eine kleine Verzögerung eintritt und das Clock-Stretching knapp vom Master verpasst wird. Dann hilft nur eine kleinere I2C taktrate. Deswegen gibt es mit der USI-Implementierung ab 100 kHz Probleme mit manchen Slaves ( z.B. ds2482-100 ). Gruß
Peter Dannegger schrieb: > Hendrik L. schrieb: >> Die entsprechenden ISR Slave Routinen sind bekannt > > Nein. > Es hat keiner Lust, Deinen Code zusammen suchen zu müssen. > Weißt Du nicht, was ein "Dateianhang" ist und wie man ein Zip aus allen > nötigen *.c, *.h erzeugt? > > > Peter Hallo Peter, Der Rest ist gar nicht MEIN Code - sondern der von http://www.jtronics.de/avr-projekte/library-i2c-twi-slave.html. Habe ich oben schon gesagt. Andere *.c und *.h Files (von mir) gibt es nicht, nur die jtronics! In den jtronics Dateien habe ich auch nichts verändert - ich stelle diesen Code auch nicht in Frage, ist er doch in allen relevanten Foren empfohlen. Gehe also davon aus, dass in den Basics die Lösung nicht zu suchen ist - wenn, liegt der "Fehler" darin, dass die Timer0 ISR irgendwie das Timing zu Lasten der USI ISR verändert - was ich aber nicht verstehe! Ich habe zwischenzeitlich sogar auch den Code aus der Timer0 ISR komplett entfernt! ISR (TIMER0_COMPA_vect) { // PWM ++; } Ändert gar nichts! Nur wenn ich alles // TCCR0A = (1<<WGM01); // CTC Modus // TCCR0B |= (1<<CS02) | (1<<CS00); // Prescaler 1024 // OCR0A = 250; // TIMSK |= (1<<OCIE0A); auskommentiert habe, funzt die Kommunikation SICHER. Zwischendurch bei eingeschaltetem Timer0 und ISR sporadisch ... - je nach Kombination von PreScaler und OCRA0 - aber nicht zuverlässig, mal ja mal nein! Mit Abschlußwiderständen 10kOhm habe ich auch schon gespielt - bringt nichts. Ein anderer Tiny 2313 - bringt nichts - Gegencheck - verhält sich genauso. Ein Check mit einem PCF 8574AP hat unter allen Betriebszuständen eine saubere Adressierbarkeit mit dem Raspberry Pi ergeben. Ich denke, ein ATTiny2313 mit 8 Mhz ist grenzwertg für eine 400 khz TWI- Slave Software Implementierung - wobei ich mir das Phänomen "geht nicht in Kombination mit Timer0 ISR" nun bei "leerer ISR" (siehe oben) nicht mehr erklären - kann (mit meinem bescheidenen Halbwissen - in aller Demut - daher meine Fragestellung an die Experten!). Weiß jemand evtl., ob ich (und wie) den SCL Takt an der Raspberry PI I2C Schnittstelle auf sagen wir mal 100 Khz runter bekomme ? 10khz würden mir auch schon reichen! Danke!
Hendrik L. schrieb: > Ein Check mit einem PCF 8574AP hat unter allen Betriebszuständen eine > saubere Adressierbarkeit mit dem Raspberry Pi ergeben. Der PCF8574 ist kein MC, d.h. SCL ist nur Eingang, da auf dem PCF8574 kein Programm läuft und somit auf nichts gewartet werden muß. Wenn der Raspberry Pi das Clock-Stretching nicht beachtet, ist das der Grund, warum ein dummmer I2C-Chip funktioniert, aber ein MC nicht. In diesem Fall braucht man für den Raspberry Pi einfach nur eine korrekt implementierte I2C-Lib, damit man auch MCs als I2C-Slave ansprechen kann. Peter
Hendrik L. schrieb: > > Weiß jemand evtl., ob ich (und wie) den SCL Takt an der Raspberry PI I2C > Schnittstelle auf sagen wir mal 100 Khz runter bekomme ? 10khz würden > mir auch schon reichen! > > Danke! http://doc.byvac.com/index.php5?title=RPI_I2C ;-)
Reiner Geiger schrieb: > Hendrik L. schrieb: >> >> Weiß jemand evtl., ob ich (und wie) den SCL Takt an der Raspberry PI I2C >> Schnittstelle auf sagen wir mal 100 Khz runter bekomme ? 10khz würden >> mir auch schon reichen! >> >> Danke! > > http://doc.byvac.com/index.php5?title=RPI_I2C > > ;-) Hallo Reiner, vielsten Dank - da steht es ja - RPI hat kein Clock Stretching! Werde berichten! Vielen Dank!
Soooo ...! Nachdem ich wie angeregt die TWI Taktrate des RPI von 400 kHz auf ca. 66 kHz (gemessen) verringert habe, läuft die Koppelung nun stabil. Es hatte zwar noch einige Hänger gegeben, aber aus irgendwelchen Gründen läuft das System JETZT stabil (ohne Hänger). Irgendwie schon etwas mysteriös. Die PWM Addition und den restlichen Code habe ich wieder aktiviert, der Prescaler ist nun ausgeschaltet - immer noch alles stabil! Etliche Stunden investiert - ganz schön nervend. Vielen Dank für Eure Hilfe! Gruß
Nach 4 Stunden Weiterentwickung meines Programms und damit verbundenem Testing unter allen "Betriebszuständen": Kein einziger Ausfall mehr, selbst bei Erweiterung des Programm Codes in der ISR-Timer0! Damit ist für mich diese Master-Slave-Codierung robust. Dank an den Ersteller des Programms. Guten Rutsch an Alle!
Hallo zusammen, leider funzt die obige Lösung 1 der I2C Bus Verlangsammung nur bei der 256 MB Raspberry Pi Variante (Version 1.0). Bei der 512 MB Version (2.0) wurde die GPIO Belegung neu festgelegt, I2C-0 wurde von der Stiftleiste genommen, stattdessen wurde I2C-1 dort herausgeführt. Die "schnelle Lösung" (Register Patch) funzt aber nur beim I2C-0, der nun nicht mehr einfach über die Stiftleiste zugänglich ist. Habe darum die in der Lösung 2 empfohlenen "Ersatz- I2C Routinen" neu installiert - nach dieser Anleitung http://doc.byvac.com/index.php5?title=RPI_I2C#Devices_requiring_Option1_or_2. Sie hat zudem den Vorteil, dass man auf jede beliebige Pin Paarung einen I2C Bus beim Raspberry Pi legen kann (also auch mehrere). War nicht ganz einfach - aber wenn man der Anweisung exakt folgt, klappt alles wunderbar. Damit kann man im Master jede Busgeschwindigkeit einstellen. Und der ATTINY2313 als Slave antwortet bei niedriger Geschwindigkeit wunderbar! Gruß
Gast
#3687129
Ist zwar schon älter, aber egal. Ich versuche auch einen ATMega mit einem ATTiny4313 per TWI zu verbinden. der ATMega sendet alle 100ms ein Signal (dabei geht er über alle 40 Slaves, ob vorhanden oder nicht). Sobald ich die Karte von dem Attiny einstecke, sind beide Datenleitungen (SCL und SDA) auf 5V und der ATMega hängt sich auf. Woran kann das liegen, bzw. was habt ihr besonderes eingestellt?
Hallo, vielleicht dir hier jemand helfen, da hatte letztes auch jemand Problemen mit den ATtinys. Frag doch mal wie er es gelöst hat. http://www.jtronics.de/forum/viewtopic.php?f=7&t=303
Lösen konnte ich das leider nicht (Attiny I2C mit USI war einfach nicht stabil als Slave [Master: Atmega]). Habe aufgegeben und statt eines Tiny einen Atmega mit TWI als Slave genommen.
Der Vollständigkeit halber: bezüglich der jtronics library (http://www.jtronics.de/avr-projekte/library-i2c-twi-slave-usi.html Webseite verweist auf diesen Thread hier). Bei mir (und noch mindestens einem anderen, zum Beispiel hier: http://forum.arduino.cc/index.php?topic=160147.0 welcher eine Library benutzt die ihrerseits auf der oben erwähnten usiTwiSlave library aufbaut und das selbe Symptom zeigt) ist das Problem aufgetreten daß der Slave nur mit Adressen < 64 zuverlässig funktionierte, insbesondere wenn andere Interrupts auf dem Slave mit im Spiel waren und das clock stretching direkt nach der Startbedingung erforderlich wurde. Der Grund war die falsche Erkennung der Startbedingung: Direkt nach der Startbedingung legt der Master das höchste Adressbit (im Falle von Adressen zwischen 64 und 127 wäre das eine 1) auf SDA, gibt SCL frei und wartet darauf dass der Slave ebenfalls SCL freigibt. Der Slave muss nun im ISR(USI_START_VECTOR) ermitteln ob eine Start- oder eine Stopbedingung vorliegt. usiTwiSlave.c verwendet dazu irrtümlicherweise diese Zeile code
1 | |
Und das kann nicht zuverlässig funktionieren, SDA ist zu diesem Zeitpunkt undefiniert und wenn die Slave-Adresse > 63 ist dann ist die Wahrscheinlichkeit hoch dass zu diesem Zeitpunkt SDA bereits high ist, insbesondere wenn der Interrupt verzögert ausgelöst wird und der Slave daher schon eine Weile auf der Taktleitung steht. Der folgende Patch sollte das Problem beheben (bei mir tut er es, seither rennt der Slave auf dem Tiny zuverlässig mit 400kHz ohne jegliche Aussetzer):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
Hallo, ich möchte etliche ATTiny85 mit diesem Code nutzen. Ich habe den letzten Beitrag mit dem Patch gelesen und habe daraufhin von der jtronics Seite die V1.3 der Lib runtergeladen. In dieser Version ist der Patch ja noch nicht implementiert. Gibt es Bestätigungen oder Einwände bezüglich des Patches? Hat es außer dem Entwickler des Patches jemand so am laufen? Vielen Dank für Feedback... MfG Dennis
Gast
#4947246
Hallo, dann einfach patch mit in den Code einbauen und fertig. Daher wird auch auf diesen Thread hier verwiesen, damit man die neuste Erkenntnisse selber ändern kann. Grüße Martin
Dennis K. schrieb: > ... > Gibt es Bestätigungen oder Einwände bezüglich des Patches? > Hat es außer dem Entwickler des Patches jemand so am laufen? Ja, und läuft mit allen Adressen ...
Gast
#5878531
Ist eine Erweiterung auf 10bit interessant, wobei aber die Addresse falsch herum it, z.B. addr 0x250 => 0b1110IO0 0x50 -> 0xf4 0x50 => 0x50f4 als macro: #define addr10bit(x) ((((x)&0xff)<<8|((x)&(0x300))>>7|0xf0)
Gast
#5882127
Ich hätte gerne einen TWI-slave auf dem Tiny88 und bin nicht in der Lage das selbst zu programmieren. Die lib von jtronics scheint genau das zu sein was ich brauche, das Eeprom-Imitat. Das steht dann auch /*###################################################################### ######## Name : USI TWI Slave driver - I2C/TWI-EEPROM Version : 1.3 - Stable autor : Martin Junghans jtronics@gmx.de page : www.jtronics.de License : GNU General Public License Update : 09.09.2011 - ATtiny24, ATtiny44, ATtiny88 allerdings geht es dann für den Tiny88 nicht weiter. Ich denke mal das ist ein Schreibfehler und sollte heisse Tiny84? Die SDA/SCL-Pins anzupassen ist ja kein Problem. Woran ich scheitere sind die Interrupt-Vektoren. Der Tiny88 hat nur einen (Int20, TWI). Das Beispiel benutzt aber 2 (USI_START und USI_OVERFLOW). Das heisst wahrscheinlich, dass es ohne grössere "Umbauten" nicht geht?
Beitrag #5882138 wurde von einem Moderator gelöscht.
Andere Baustelle. In diesem Thread geht es um AVR Controller ohne halbwegs echtem I2C-Modul, bei dem das ziemlich bitweise über USI implementiert wird. Der Tiny88 hat aber ein echtes I2C-Modul (aka TWI), das nicht mit dem USI der anderen Tinys verwandt ist, sondern mit den Megas wie Mega8 und Nachfolgern.
Gast
#5893054
aha !
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.