Hallo Zusammen,
voerst bedanke ich mich für alle Beitäge.
wie bekannt ist, ist meine I2C-Kommunikation bei einer Fehlersimulation (Wackelkontakt SDA- bzw. SCL-Leitung oder SDA- und SCL-Leitung gebrückt) ausgefallen. Mit Hilfe des Oszilloskops habe ich erkannt, dass dann die SDA-Leitung dauerhaft auf LOW liegt. Dieser LOW-Pegel wurde hervorgerufen durch den entsprechende Slave und/ oder des Masters.
Fehlerbehebung konnte erfolgen durch:
Slave-Seite:
Einbau eine bilateralen Switch! Bei einem Fehlerfall wurde der Slave kurzzeitig abgeschalten.
Master-Seite:
Sobald das TWEN: TWI Enable Bit im TWCR Register gesetzt wurde ist kein weiteres Zugriff auf die SCL & SDA I/O Pins möglich. Dieses Bit wird sobald der Befehl „wire.begin();“ aufgerufen wird dauerhaft gesetzt. Da bei einem Fehler ein Problem im I2C-Modul vorliegt, wollte ich versuchen einen Urzustand herzustellen. Dies konnte ich ermöglichen indem ich die wire library mit den Änderung von GitHub - steamfire/WSWireLib: Arduino Wire Library modified to add timeouts to the freeze-prone TWI while() loops vorgenommen und zusätzlich folgendes im twi.cpp file geändert (Fett Markierung):
void twi_init(void)
{
// initialize state
twi_state = TWI_READY;
twi_sendStop = true; // default value
twi_inRepStart = false;
TWCR=0;
delay(1);
pinMode(SDA , OUTPUT);
pinMode(SCL , OUTPUT);
digitalWrite(SDA, 0);
digitalWrite(SCL, 0);
delay (200);
digitalWrite(SDA, 1);
digitalWrite(SCL, 1);
delay(200);
// initialize twi prescaler and bit rate
cbi(TWSR, TWPS0);
cbi(TWSR, TWPS1);
TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;
/* twi bit rate formula from atmega128 manual pg 204
SCL Frequency = CPU Clock Frequency / (16 + (2 * TWBR))
note: TWBR should be 10 or higher for master mode
It is 72 for a 16mhz Wiring board with 100kHz TWI */
// enable twi module, acks, and twi interrupt
TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
}
Sobald auf Seiten des Master die SDA-Leitung runtergezogen wird, kann das I2C-Modul rückgesetzt werden. Dies wird ermöglicht durch den Codezusatz twi_tout () in den entsprechenden while-Schleifen.
Natürlich könnte man jetzt verschiedene Fehlerrutinen zusätzlich programmiert.
Ich hoffe den einen oder anderen Hilft diese Information.
Beste Grüße
Jörg