mikrocontroller.net

Forum: Projekte & Code attiny USI Slave Implementierung


Autor: Axel Gartner (axelg) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Axel Gartner (axelg) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
SCL Overflowfehler korrigiert.
Axel Gartner

Autor: Benno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Axel Gartner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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

Autor: Benno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Axel Gartner (axelg) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Dennis Goetz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: B. Köppel (bekoeppel) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Kest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael Fluhr (fury)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: A.K. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: malefs (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Andre Göpfert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Christoph Klein (hyla)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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-m...

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.

Autor: pinkpanter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau so was hab ich gesucht!
Und im gegensatz zu allen anderen Codeschnipseln funktionierte die 
Bibliothek gleich beim ersten Versuch.

Vielen Dank der Richard

Autor: auch_anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Cool genau das hab ich gesucht.

danke

Autor: Thomas G. (mrmp3)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier das allgemeine Beispiel von mir, steht auch auf der jtronics.de
//############# I2C/TWI Adressen
#define Adr_Attiny  0b00110100 
 
//############# I2C    ATTiny
void read_Attiny(void)
{
i2c_start_wait(Adr_Attiny + I2C_WRITE); // Adr_Attiny ansprechen
i2c_write(0);                          // startadresse zum lesen
 
i2c_rep_start (Adr_Attiny + I2C_READ ); // Lesen beginnen 
Byte0    = i2c_readAck();         // Byte empfangen 
Byte1    = i2c_readAck();         // Byte empfangen  
Byte2    = i2c_readAck();         // Byte empfangen  
Byte3    = i2c_readNak();         // letes Byte empfangen  
 
i2c_stop();                          // stopt I2C Verbindung
}

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
int main(void)
{
uint8_t buffer;
uart_init(UART_BAUD_SELECT(2400, F_CPU));
sei();
i2c_init();
_delay_ms(10);

//##################################
uart_puts("Slave adresse senden\r");// debug

i2c_start_wait(ATTINY+I2C_WRITE);
i2c_write(0);                     // ab Speicherplatz 0 abfragen


uart_puts("Slave lesen\r");         // debug

i2c_rep_start(ATTINY+I2C_READ);
buffer=i2c_readNak();             // lesen
i2c_stop();

uart_puts("Buffer: ");// debug
uart_putc(buffer); 
uart_putc('\r');

while(1)
  {  
  }
}

Autor: Thomas G. (mrmp3)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Martin J. (bluematrix) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Tester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bekomme folgenden Fehler bei Verwendung von avr-gcc und 
attiny[248]5:
Library_TWI_USI_Slave_Epprom_8MHZ % make

-------- begin --------
avr-gcc (GCC) 4.3.4
Copyright (C) 2008 Free Software Foundation, Inc.
Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.


Compiling: main.c
avr-gcc -c -mmcu=attiny45 -I. -gdwarf-2 -DF_CPU=8000000ULUL    -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=main.lst  -std=gnu99 -MD -MP -MF .dep/main.o.d main.c -o main.o 

Compiling: usiTwiSlave.c
avr-gcc -c -mmcu=attiny45 -I. -gdwarf-2 -DF_CPU=8000000ULUL    -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=usiTwiSlave.lst  -std=gnu99 -MD -MP -MF .dep/usiTwiSlave.o.d usiTwiSlave.c -o usiTwiSlave.o 
usiTwiSlave.c: In Funktion »usiTwiSlaveInit«:
usiTwiSlave.c:201: Fehler: »USICIF« nicht deklariert (erste Benutzung in dieser Funktion)
usiTwiSlave.c:201: Fehler: (Jeder nicht deklarierte Bezeichner wird nur einmal aufgeführt
usiTwiSlave.c:201: Fehler: für jede Funktion in der er auftritt.)
usiTwiSlave.c: In Funktion »__vector_13«:
usiTwiSlave.c:239: Fehler: »USICIF« nicht deklariert (erste Benutzung in dieser Funktion)
usiTwiSlave.c: In Funktion »__vector_14«:
usiTwiSlave.c:263: Fehler: »USICIF« nicht deklariert (erste Benutzung in dieser Funktion)
make: *** [usiTwiSlave.o] Fehler 1

USICIF sollte doch definiert sein. BTW: bei attiny26 funktioniert das 
Compilieren ...

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Martin J. (bluematrix) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier noch eine Version mit überarbeiteten Kommentaren
komplett in Englisch...

Vielen Dank nochmal an Markus für das überarbeiten

Grüße Martin

Autor: Tester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ?

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mhm könnte ein kleiner Fehler sein...
in der usiTwiSlave.c musst du folgendes Ändern
#elif   defined( __AVR_ATtiny25__ ) | \
  defined( __AVR_ATtiny45__ ) | \
  defined( __AVR_ATtiny85__ )
  #define DDR_USI             DDRB
  #define PORT_USI            PORTB
  #define PIN_USI             PINB
  #define PORT_USI_SDA        PB0
  #define PORT_USI_SCL        PB2
  #define PIN_USI_SDA         PINB0
  #define PIN_USI_SCL         PINB2
  #define USI_START_COND_INT  USICIF     // HIER muss USISIF stehn!!!!
  #define USI_START_VECTOR    USI_START_vect
  #define USI_OVERFLOW_VECTOR USI_OVF_vect


so sollte dann funktionieren...
testen kann ich das aber net , hab grad kein controller dafür hier.
sag Bescheid, ob es geht.


Viel Erfolg

Autor: Tester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke :-)  Compilieren geht schon mal ...

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fein fein

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jepp, das sollte in den Quellen dringend korrigiert werden! Ich bin beim 
ATtiny45 eben auch auf den USICIF-Fehler gestoßen... :-/

Gruß, Volker

Autor: Martin J. (bluematrix) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier die korrigierte Version

Autor: Sebastian M. (compressed)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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/tw...

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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/tw...

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

Autor: martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Link
http://www.jtronics.de/elektronik-avr/lib-i2ctwi-m...
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.

Autor: Thomas Berends (t5b6_de) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Thomas Berends (t5b6_de) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Alexander Ratzefumm (ratzefumm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?
#elif   defined( __AVR_ATmega8__ )
    #define DDR_USI             DDRC
    #define PORT_USI            PORTC
    #define PIN_USI             PINC
    #define PORT_USI_SDA        PC4
    #define PORT_USI_SCL        PC5
    #define PIN_USI_SDA         PINC4
    #define PIN_USI_SCL         PINC5
    #define USI_START_COND_INT  USISIF
    #define USI_START_VECTOR    USI_START_vect
    #define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect

hat doch sicher schon mal einer probiert oder?

Autor: woodym (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
ISR( USI_START_VECTOR )
{
  overflowState = USI_SLAVE_CHECK_ADDRESS;      // Set default starting conditions for new TWI package
  DDR_USI &= ~( 1 << PORT_USI_SDA );          // Set SDA as input

geändert zu
ISR( USI_START_VECTOR )
{
  overflowState = USI_SLAVE_CHECK_ADDRESS;      // Set default starting conditions for new TWI package
  PORT_USI |= ( 1 << PORT_USI_SDA );  // Set SDA high
  DDR_USI &= ~( 1 << PORT_USI_SDA );          // Set SDA as input
.....

und folgendes:
    case USI_SLAVE_CHECK_ADDRESS:
      if (USIDR == 0 || (USIDR & ~1) == slaveAddress)     // If adress is either 0 or own address    
      {
        if (  USIDR & 0x01 )
        {
          overflowState = USI_SLAVE_SEND_DATA;    // Master Write Data Mode - Slave transmit
        }
        else
        {
          overflowState = USI_SLAVE_REQUEST_DATA;    // Master Read Data Mode - Slave receive
          buffer_adr=0xFF; // Buffer position undefined
        } // end if
        SET_USI_TO_SEND_ACK();

geändert zu:

    case USI_SLAVE_CHECK_ADDRESS:
      if (USIDR == 0 || (USIDR & ~1) == slaveAddress)     // If adress is either 0 or own address    
      {
        if (  USIDR & 0x01 )
        {
          overflowState = USI_SLAVE_SEND_DATA;    // Master Write Data Mode - Slave transmit
        }
        else
        {
          overflowState = USI_SLAVE_REQUEST_DATA;    // Master Read Data Mode - Slave receive
          buffer_adr=0xFF; // Buffer position undefined
        } // end if
        PORT_USI &= ~( 1 << PORT_USI_SDA );  // Set SDA high
        SET_USI_TO_SEND_ACK();

bei mir funktioniert jetzt sowohl der ACK als auch die SCL-Verzögerung.

bye woodym

Autor: tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: woodym (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: woodym (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

habe auf einem ATTiny2313 die USI-TWI Slave 
http://www.jtronics.de/avr-projekte/library-i2c-tw... 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!

Autor: Uwe S. (de0508)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Bitte hänge dein gesamtes Programm noch an.
So ist das nur Raten..

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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-tw...

Danke im voraus

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Michael S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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-tw.... 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!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Reiner Geiger (reinerg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

;-)

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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ß

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Hendrik L. (lbd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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#Devi.... 
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ß

Autor: MOBA 2015 (2009marius15)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Martin J. (bluematrix) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

: Bearbeitet durch User
Autor: Fred S. (kogitsune)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Vollständigkeit halber:

bezüglich der jtronics library 
(http://www.jtronics.de/avr-projekte/library-i2c-tw... 
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
if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
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):
--- usiTwiSlave_old.c  2011-10-21 12:17:44.000000000 +0200
+++ usiTwiSlave.c  2014-10-25 17:00:17.794250296 +0200
@@ -255,7 +255,7 @@
   
   while (  ( PIN_USI & ( 1 << PIN_USI_SCL ) ) &&  !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) ));// SCL his high and SDA is low
 
-  if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
+  if ( !( PIN_USI & ( 1 << PIN_USI_SCL ) ) )
     {  // A Stop Condition did not occur
     USICR =
     ( 1 << USISIE ) |                // Keep Start Condition Interrupt enabled to detect RESTART

Autor: Dennis K. (scarfaceno1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Wilhelm M. (wimalopaan)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
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 ...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.