Forum: Mikrocontroller und Digitale Elektronik ATTiny2313 als I2C/TWI-Slave (zer)stört Bus


von Stefan T. (tommie)


Lesenswert?

Hallo,

ich versuche gerade, meinen Quadcopter (Multiwii, ATMega328p) per I2C 
mit GPS-Daten zu versorgen. Dazu habe ich mir bereits vor einiger Zeit 
ein entsprechendes Programm für einen ATTiny2313 gestrickt, dass über 
den UART NMEA-Daten einliest, parst und per TWI zur Verfügung stellt. In 
einem Testszenario vor einiger Zeit klappte das auch noch prima, 
schließe ich den Controller jetzt aber an den vorhandenen I2C-Bus an, 
steigen alle anderen Sensoren (Gyro, Acc, Mag, Baro) aus; ich muss dazu 
sagen, dass der Bus mit 3,3V betrieben wird.

Anscheinend legt mein ATTiny jedoch aktiv auf SCL und SDA sein VCC von 
5V, so dass der Bus natürlich aus den Fugen gerät. Ich verwende den 
I2C-Code von Donald Blake und habe folgende Stelle im Code in Verdacht:
https://github.com/wertarbyte/tiny-gps/blob/master/usiTwiSlave.c#L316

So wie ich es verstehe, wird damit doch 5V auf den Bus gelegt?
Leider kenne ich mich mit der ganzen USI-Geschichte nicht sehr gut aus, 
vielleicht hat jemand mit mehr Ahnung ja eine Idee, woran es liegen 
könnte.

Beste Grüße
Stefan

von F. Richards (Gast)


Lesenswert?

Stefan Tomanek schrieb:
> schließe ich den Controller jetzt aber an den vorhandenen I2C-Bus an,
> steigen alle anderen Sensoren (Gyro, Acc, Mag, Baro) aus
Der Controller muss, wenn er nix zu sagen hat, hochohmig am I²C-Bus 
hängen.

von Stefan T. (tommie)


Lesenswert?

Ja, das ist mir schon klar. Laut Dokumentation verhalten sich SCL und 
SDA auch als Open-Collector-Ausgänge, ziehen den Bus also entweder gegen 
GND oder lassen ihn "floaten" (und durch die Pull-Ups auf HIGH gehen).
Deshalb erstehe ich die von mir genannten Code-Stellen auch nicht, die j 
anscheinend die Ports auf HIGH legen, noch bevor der TWI-Modus aktiviert 
wurde.

von Klaus 2. (klaus2m5)


Lesenswert?

Bei den Kommentaren zu diesem Code ist mal mindestens die Funktion von 
DDR und Port Register vertauscht. Bei einer Open Collector Ansteuerung 
dient das DDR-Register als invertierter Output, die Port Pins müssen 
immer 0 sein. DDR = 1 bedeutet Ausgang auf 0 ziehen, DDR = 0 bedeutet 
Ausgang offen, also 1 durch Pullup wenn kein anderer Port am Bus 0 ist.

Der Programmierer hat also gar nicht verstanden, wie der USI 
funktioniert. Dass es zu Problemen mit anderen Slaves kommt, ist mehr 
als wahrscheinlich.

von Stefan T. (tommie)


Lesenswert?

Hat jemand einen anderen USI/TWI-Code zur Hand, der wirklich auch mit 
mehreren Slaves funktioniert? :-)

von Klaus 2. (klaus2m5)


Lesenswert?

Atmel Application Note AVR312 - Da stimmen die Kommentare zwar auch 
nicht, aber mindestens die Initialisierung ist richtig.

von Stefan T. (tommie)


Lesenswert?

Sicher? Ich habe den Code hier gerade vor mir (USI_TWI_Slace.c):
1
void USI_TWI_Slave_Initialise( unsigned char TWI_ownAddress )
2
{
3
  Flush_TWI_Buffers();
4
5
  TWI_slaveAddress = TWI_ownAddress;
6
7
  PORT_USI |=  (1<<PORT_USI_SCL);                                 // Set SCL high
8
  PORT_USI |=  (1<<PORT_USI_SDA);                                 // Set SDA high
9
  DDR_USI  |=  (1<<PORT_USI_SCL);                                 // Set SCL as output
10
  DDR_USI  &= ~(1<<PORT_USI_SDA);                                 // Set SDA as input

kommt das nicht aufs gleiche raus? Zumindest habe ich auch mit dieser 
Initialisierung VCC am SDA-Pin.

von Klaus 2. (klaus2m5)


Lesenswert?

Ups, ich habe glaube ich Software TWI und USI verwechselt, vergiss meine 
Beiträge.

von H. Bunse (Gast)


Lesenswert?

Stefan Tomanek schrieb:
> kommt das nicht aufs gleiche raus? Zumindest habe ich auch mit dieser
> Initialisierung VCC am SDA-Pin.
Nimm mal probeweise die beiden Pull-Up Widerstände für SCL und SDA raus 
und miss noch mal.

von Stefan T. (tommie)


Lesenswert?

Die Widerstände hängen am Master, d.h. auch wenn der Tiny gar nicht 
angeschlossen ist, pusht er die Spannung selbst hoch.

von Stefan T. (tommie)


Lesenswert?

Hat jemand noch eine Idee? Ich habe mir noch ein paar andere 
USI/TWI-Libs angeguckt, aber es sieht eigentlich überall gleich aus, so 
auch in der Lib von Martin Junghans (u.a. 
http://www.das-labor.org/svn/microcontroller/src-atmel/lib/i2c/trunk/usi-twi_slave/usiTwiSlave.c):
1
void usiTwiSlaveInit()
2
{
3
  // In Two Wire mode (USIWM1, USIWM0 = 1X), the slave USI will pull SCL
4
  // low when a start condition is detected or a counter overflow (only
5
  // for USIWM1, USIWM0 = 11).  This inserts a wait state. SCL is released
6
  // by the ISRs (USI_START_vect and USI_OVERFLOW_vect).
7
  DDR_USI |= (1 << PORT_USI_SCL) | (1 << PORT_USI_SDA);  // Set SCL and SDA as output
8
  PORT_USI |= (1 << PORT_USI_SCL);  // Set SCL high
9
  PORT_USI |= (1 << PORT_USI_SDA);  // Set SDA high
10
  DDR_USI &= ~(1 << PORT_USI_SDA);  // Set SDA as input
11
  USICR =
12
    (1 << USISIE) |          // Enable Start Condition Interrupt
13
    (0 << USIOIE) |          // Disable Overflow Interrupt
14
    (1 << USIWM1) | (0 << USIWM0) |  // Set USI in Two-wire mode, no USI Counter overflow hold
15
    (1 << USICS1) | (0 << USICS0) | (0 << USICLK) |// Shift Register Clock Source = external, positive edge 4-Bit Counter Source = external, both edges
16
    (0 << USITC);          // No toggle clock-port pin
17
  USISR = (1 << USI_START_COND_INT) | (1 << USIOIF) | (1 << USIPF) | (1 << USIDC);  // clear all interrupt flags and reset overflow counter
18
}
Selbst wenn das Problem mit der Unterschiedlichen Spannung am Bus nicht 
wäre (3,3V vs. 5V) würde die initialisierung deses Slaves doch jeden 
laufenden Transfer auf dem Bus zerschlagen?

von Stefan T. (tommie)


Lesenswert?

OK, ich muss alles zurückziehen. Die Override-Register sorgen schon für 
das Open-Collector-Verhalten, sobald der USI-Modus geschaltet ist.

Woran lag es schlussendlich? An der Taktfrequenz. Mit 8MHz kann der 
ATTiny mit dem Bus schritt halten und fügt sich harmonisch ein. Danke 
trotzdem für alle, die mitgeholfen haben :-)

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.