Forum: Projekte & Code attiny USI Slave Implementierung


von Axel G. (axelg) Benutzerseite


Angehängte Dateien:

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

von Axel G. (axelg) Benutzerseite


Angehängte Dateien:

Lesenswert?

SCL Overflowfehler korrigiert.
Axel Gartner

von Benno (Gast)


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!

von Axel Gartner (Gast)


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

von peter dannegger (Gast)


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

von Benno (Gast)


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?

von Axel G. (axelg) Benutzerseite


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

von Dennis Goetz (Gast)


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

von B. K. (bekoeppel) Benutzerseite


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.

von Kest (Gast)


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

von Michael F. (fury)


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

von A.K. (Gast)


Angehängte Dateien:

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.

von malefs (Gast)


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!

von Andre Göpfert (Gast)


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

von Christoph K. (hyla)


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

von Martin J. (bluematrix) Benutzerseite


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-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.

von pinkpanter (Gast)


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

von auch_anfänger (Gast)


Lesenswert?

Cool genau das hab ich gesucht.

danke

von Thomas G. (mrmp3)


Angehängte Dateien:

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

von Martin J. (bluematrix) Benutzerseite


Lesenswert?

hier das allgemeine Beispiel von mir, steht auch auf der jtronics.de
1
//############# I2C/TWI Adressen
2
#define Adr_Attiny  0b00110100 
3
 
4
//############# I2C    ATTiny
5
void read_Attiny(void)
6
{
7
i2c_start_wait(Adr_Attiny + I2C_WRITE); // Adr_Attiny ansprechen
8
i2c_write(0);                          // startadresse zum lesen
9
 
10
i2c_rep_start (Adr_Attiny + I2C_READ ); // Lesen beginnen 
11
Byte0    = i2c_readAck();         // Byte empfangen 
12
Byte1    = i2c_readAck();         // Byte empfangen  
13
Byte2    = i2c_readAck();         // Byte empfangen  
14
Byte3    = i2c_readNak();         // letes Byte empfangen  
15
 
16
i2c_stop();                          // stopt I2C Verbindung
17
}

von Martin J. (bluematrix) Benutzerseite


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
1
int main(void)
2
{
3
uint8_t buffer;
4
uart_init(UART_BAUD_SELECT(2400, F_CPU));
5
sei();
6
i2c_init();
7
_delay_ms(10);
8
9
//##################################
10
uart_puts("Slave adresse senden\r");// debug
11
12
i2c_start_wait(ATTINY+I2C_WRITE);
13
i2c_write(0);                     // ab Speicherplatz 0 abfragen
14
15
16
uart_puts("Slave lesen\r");         // debug
17
18
i2c_rep_start(ATTINY+I2C_READ);
19
buffer=i2c_readNak();             // lesen
20
i2c_stop();
21
22
uart_puts("Buffer: ");// debug
23
uart_putc(buffer); 
24
uart_putc('\r');
25
26
while(1)
27
  {  
28
  }
29
}

von Thomas G. (mrmp3)


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

von Martin J. (bluematrix) Benutzerseite


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

von Martin J. (bluematrix) Benutzerseite


Angehängte Dateien:

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

von Tester (Gast)


Lesenswert?

Hallo,

ich bekomme folgenden Fehler bei Verwendung von avr-gcc und 
attiny[248]5:
1
Library_TWI_USI_Slave_Epprom_8MHZ % make
2
3
-------- begin --------
4
avr-gcc (GCC) 4.3.4
5
Copyright (C) 2008 Free Software Foundation, Inc.
6
Dies ist freie Software; die Kopierbedingungen stehen in den Quellen. Es
7
gibt KEINE Garantie; auch nicht für MARKTGÄNGIGKEIT oder FÜR SPEZIELLE ZWECKE.
8
9
10
Compiling: main.c
11
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 
12
13
Compiling: usiTwiSlave.c
14
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 
15
usiTwiSlave.c: In Funktion »usiTwiSlaveInit«:
16
usiTwiSlave.c:201: Fehler: »USICIF« nicht deklariert (erste Benutzung in dieser Funktion)
17
usiTwiSlave.c:201: Fehler: (Jeder nicht deklarierte Bezeichner wird nur einmal aufgeführt
18
usiTwiSlave.c:201: Fehler: für jede Funktion in der er auftritt.)
19
usiTwiSlave.c: In Funktion »__vector_13«:
20
usiTwiSlave.c:239: Fehler: »USICIF« nicht deklariert (erste Benutzung in dieser Funktion)
21
usiTwiSlave.c: In Funktion »__vector_14«:
22
usiTwiSlave.c:263: Fehler: »USICIF« nicht deklariert (erste Benutzung in dieser Funktion)
23
make: *** [usiTwiSlave.o] Fehler 1

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

von Martin J. (bluematrix) Benutzerseite


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.

von Martin J. (bluematrix) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hier noch eine Version mit überarbeiteten Kommentaren
komplett in Englisch...

Vielen Dank nochmal an Markus für das überarbeiten

Grüße Martin

von Tester (Gast)


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 ?

von Martin J. (bluematrix) Benutzerseite


Lesenswert?

mhm könnte ein kleiner Fehler sein...
in der usiTwiSlave.c musst du folgendes Ändern
1
#elif   defined( __AVR_ATtiny25__ ) | \
2
  defined( __AVR_ATtiny45__ ) | \
3
  defined( __AVR_ATtiny85__ )
4
  #define DDR_USI             DDRB
5
  #define PORT_USI            PORTB
6
  #define PIN_USI             PINB
7
  #define PORT_USI_SDA        PB0
8
  #define PORT_USI_SCL        PB2
9
  #define PIN_USI_SDA         PINB0
10
  #define PIN_USI_SCL         PINB2
11
  #define USI_START_COND_INT  USICIF     // HIER muss USISIF stehn!!!!
12
  #define USI_START_VECTOR    USI_START_vect
13
  #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

von Tester (Gast)


Lesenswert?

Danke :-)  Compilieren geht schon mal ...

von Martin J. (bluematrix) Benutzerseite


Lesenswert?

fein fein

von Volker (Gast)


Lesenswert?

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

Gruß, Volker

von Martin J. (bluematrix) Benutzerseite


Angehängte Dateien:

Lesenswert?

hier die korrigierte Version

von Sebastian M. (compressed)


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

von Martin J. (bluematrix) Benutzerseite


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

von Reiner G. (reinerg)


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ß

von martin (Gast)


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

von martin (Gast)


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/twi-slave-mit-usi-avr

von Reiner G. (reinerg)


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/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

von martin (Gast)


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.

von Reiner G. (reinerg)


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ß

von martin (Gast)


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

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

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.

von Thomas B. (t5b6_de) Benutzerseite


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

von Thomas B. (t5b6_de) Benutzerseite


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.

von Alexander R. (ratzefumm)


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?
1
#elif   defined( __AVR_ATmega8__ )
2
    #define DDR_USI             DDRC
3
    #define PORT_USI            PORTC
4
    #define PIN_USI             PINC
5
    #define PORT_USI_SDA        PC4
6
    #define PORT_USI_SCL        PC5
7
    #define PIN_USI_SDA         PINC4
8
    #define PIN_USI_SCL         PINC5
9
    #define USI_START_COND_INT  USISIF
10
    #define USI_START_VECTOR    USI_START_vect
11
    #define USI_OVERFLOW_VECTOR USI_OVERFLOW_vect

hat doch sicher schon mal einer probiert oder?

von woodym (Gast)


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

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

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

geändert zu:
1
    case USI_SLAVE_CHECK_ADDRESS:
2
      if (USIDR == 0 || (USIDR & ~1) == slaveAddress)     // If adress is either 0 or own address    
3
      {
4
        if (  USIDR & 0x01 )
5
        {
6
          overflowState = USI_SLAVE_SEND_DATA;    // Master Write Data Mode - Slave transmit
7
        }
8
        else
9
        {
10
          overflowState = USI_SLAVE_REQUEST_DATA;    // Master Read Data Mode - Slave receive
11
          buffer_adr=0xFF; // Buffer position undefined
12
        } // end if
13
        PORT_USI &= ~( 1 << PORT_USI_SDA );  // Set SDA high
14
        SET_USI_TO_SEND_ACK();

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

bye woodym

von tobi (Gast)


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

von woodym (Gast)


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

von tobi (Gast)


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

von woodym (Gast)


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

von Hendrik L. (lbd)


Lesenswert?

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!

von Uwe S. (de0508)


Lesenswert?

Hallo,

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

von Hendrik L. (lbd)


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-twi-slave-usi.html

Danke im voraus

von Reiner G. (reinerg)


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ß

von Hendrik L. (lbd)


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)

von Peter D. (peda)


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

von Michael S. (Gast)


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.

von Reiner G. (reinerg)


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ß

von Peter D. (peda)


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

von Michael S. (Gast)


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.

von Reiner G. (reinerg)


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ß

von Hendrik L. (lbd)


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-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!

von Peter D. (peda)


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

von Reiner G. (reinerg)


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

;-)

von Hendrik L. (lbd)


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!

von Hendrik L. (lbd)


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ß

von Hendrik L. (lbd)


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!

von Hendrik L. (lbd)


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#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ß

von MOBA 2. (Gast)


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?

von Martin J. (bluematrix) Benutzerseite


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
von Fred S. (kogitsune)


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.

von Bernd K. (prof7bit)


Lesenswert?

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
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):
1
--- usiTwiSlave_old.c  2011-10-21 12:17:44.000000000 +0200
2
+++ usiTwiSlave.c  2014-10-25 17:00:17.794250296 +0200
3
@@ -255,7 +255,7 @@
4
   
5
   while (  ( PIN_USI & ( 1 << PIN_USI_SCL ) ) &&  !( ( PIN_USI & ( 1 << PIN_USI_SDA ) ) ));// SCL his high and SDA is low
6
 
7
-  if ( !( PIN_USI & ( 1 << PIN_USI_SDA ) ) )
8
+  if ( !( PIN_USI & ( 1 << PIN_USI_SCL ) ) )
9
     {  // A Stop Condition did not occur
10
     USICR =
11
     ( 1 << USISIE ) |                // Keep Start Condition Interrupt enabled to detect RESTART

von Dennis K. (scarfaceno1)


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

von martin (Gast)


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

von Wilhelm M. (wimalopaan)


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 ...

von chris (Gast)


Lesenswert?

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)

von Horst (Gast)


Lesenswert?

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 vom Autor gelöscht.
von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Henry (Gast)


Lesenswert?

aha !

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.